diff --git a/Platform/Shared/VMNavigationListView.swift b/Platform/Shared/VMNavigationListView.swift index cc8405e6e..ff96f8496 100644 --- a/Platform/Shared/VMNavigationListView.swift +++ b/Platform/Shared/VMNavigationListView.swift @@ -95,6 +95,7 @@ struct VMNavigationListView: View { private struct VMListModifier: ViewModifier { @EnvironmentObject private var data: UTMData + @State private var settingsPresented = false func body(content: Content) -> some View { content @@ -115,6 +116,11 @@ private struct VMListModifier: ViewModifier { ToolbarItem(placement: .navigationBarLeading) { newButton } + ToolbarItem(placement: .navigationBarTrailing) { + Button("Settings") { + settingsPresented.toggle() + } + } ToolbarItem(placement: .navigationBarTrailing) { EditButton() } @@ -123,6 +129,11 @@ private struct VMListModifier: ViewModifier { .sheet(isPresented: $data.showNewVMSheet) { VMWizardView() } + #if os(iOS) + .sheet(isPresented: $settingsPresented) { + UTMSettingsView() + } + #endif } private var newButton: some View { diff --git a/Platform/iOS/IASKAppSettings.swift b/Platform/iOS/IASKAppSettings.swift new file mode 100644 index 000000000..4ae3e0162 --- /dev/null +++ b/Platform/iOS/IASKAppSettings.swift @@ -0,0 +1,52 @@ +// +// Copyright © 2022 osy. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI +import InAppSettingsKit + +struct IASKAppSettings: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> IASKAppSettingsViewController { + return IASKAppSettingsViewController() + } + + func updateUIViewController(_ uiViewController: IASKAppSettingsViewController, context: Context) { + uiViewController.neverShowPrivacySettings = !context.environment.showPrivacyLink + uiViewController.showCreditsFooter = false + } +} + +private struct AppSettingsShowPrivacyLinkKey: EnvironmentKey { + static let defaultValue = true +} + +extension EnvironmentValues { + var showPrivacyLink: Bool { + get { self[AppSettingsShowPrivacyLinkKey.self] } + set { self[AppSettingsShowPrivacyLinkKey.self] = newValue } + } +} + +extension View { + func appSettingsShowPrivacyLink(_ showPrivacyLink: Bool) -> some View { + environment(\.showPrivacyLink, showPrivacyLink) + } +} + +struct IASKAppSettings_Previews: PreviewProvider { + static var previews: some View { + IASKAppSettings() + } +} diff --git a/Platform/iOS/UTMSettingsView.swift b/Platform/iOS/UTMSettingsView.swift new file mode 100644 index 000000000..490620b49 --- /dev/null +++ b/Platform/iOS/UTMSettingsView.swift @@ -0,0 +1,43 @@ +// +// Copyright © 2022 osy. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +struct UTMSettingsView: View { + @Environment(\.presentationMode) private var presentationMode: Binding + + var body: some View { + NavigationView { + IASKAppSettings() + .navigationTitle("Settings") + .navigationBarTitleDisplayMode(.inline) + .appSettingsShowPrivacyLink(false) //FIXME: detect TrollStore and set true + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button("Close") { + presentationMode.wrappedValue.dismiss() + } + } + } + } + } +} + +struct UTMSettingsView_Previews: PreviewProvider { + static var previews: some View { + UTMSettingsView() + } +} diff --git a/UTM.xcodeproj/project.pbxproj b/UTM.xcodeproj/project.pbxproj index 06e1d4b5c..ccb146161 100644 --- a/UTM.xcodeproj/project.pbxproj +++ b/UTM.xcodeproj/project.pbxproj @@ -161,6 +161,7 @@ 8469CACF277D345700BA5601 /* qapi-visit-compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 8469CACD277D345700BA5601 /* qapi-visit-compat.c */; }; 8469CAD0277D345700BA5601 /* qapi-visit-compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 8469CACD277D345700BA5601 /* qapi-visit-compat.c */; }; 8469CAD1277D345700BA5601 /* qapi-visit-compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 8469CACD277D345700BA5601 /* qapi-visit-compat.c */; }; + 846D878629050B6B0095F10B /* InAppSettingsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 846D878529050B6B0095F10B /* InAppSettingsKit */; }; 8471770627CC974F00D3A50B /* DefaultTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471770527CC974F00D3A50B /* DefaultTextField.swift */; }; 8471770727CC974F00D3A50B /* DefaultTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471770527CC974F00D3A50B /* DefaultTextField.swift */; }; 8471770827CC974F00D3A50B /* DefaultTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471770527CC974F00D3A50B /* DefaultTextField.swift */; }; @@ -255,6 +256,11 @@ 84C60FB82681A41B00B58C00 /* VMToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C60FB62681A41B00B58C00 /* VMToolbarView.swift */; }; 84C60FBA268269D700B58C00 /* VMDisplayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C60FB9268269D700B58C00 /* VMDisplayViewController.swift */; }; 84C60FBB268269D700B58C00 /* VMDisplayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C60FB9268269D700B58C00 /* VMDisplayViewController.swift */; }; + 84CE3DAC2904C14100FF068B /* InAppSettingsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE3DAB2904C14100FF068B /* InAppSettingsKit */; }; + 84CE3DAE2904C17C00FF068B /* IASKAppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE3DAD2904C17C00FF068B /* IASKAppSettings.swift */; }; + 84CE3DAF2904C17C00FF068B /* IASKAppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE3DAD2904C17C00FF068B /* IASKAppSettings.swift */; }; + 84CE3DB12904C7A100FF068B /* UTMSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE3DB02904C7A100FF068B /* UTMSettingsView.swift */; }; + 84CE3DB22904C7A100FF068B /* UTMSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE3DB02904C7A100FF068B /* UTMSettingsView.swift */; }; 84CF5DD3288DCE6400D01721 /* VMDisplayHostedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CF5DD2288DCE6400D01721 /* VMDisplayHostedView.swift */; }; 84CF5DD4288DCE6400D01721 /* VMDisplayHostedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CF5DD2288DCE6400D01721 /* VMDisplayHostedView.swift */; }; 84CF5DF3288E433F00D01721 /* SwiftUIVisualEffects in Frameworks */ = {isa = PBXBuildFile; productRef = 84CF5DF2288E433F00D01721 /* SwiftUIVisualEffects */; }; @@ -1726,6 +1732,8 @@ 84C584EA268FA6D1000FCABF /* VMConfigAppleSystemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMConfigAppleSystemView.swift; sourceTree = ""; }; 84C60FB62681A41B00B58C00 /* VMToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarView.swift; sourceTree = ""; }; 84C60FB9268269D700B58C00 /* VMDisplayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayViewController.swift; sourceTree = ""; }; + 84CE3DAD2904C17C00FF068B /* IASKAppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IASKAppSettings.swift; sourceTree = ""; }; + 84CE3DB02904C7A100FF068B /* UTMSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMSettingsView.swift; sourceTree = ""; }; 84CF5DD2288DCE6400D01721 /* VMDisplayHostedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayHostedView.swift; sourceTree = ""; }; 84CF5DF4288F558400D01721 /* VMToolbarDriveMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarDriveMenuView.swift; sourceTree = ""; }; 84E6F6FC289319AE00080EEF /* VMToolbarDisplayMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarDisplayMenuView.swift; sourceTree = ""; }; @@ -2322,6 +2330,7 @@ CE2D935124AD46670059923A /* gstaudio-1.0.0.framework in Frameworks */, CE2D935224AD46670059923A /* gpg-error.0.framework in Frameworks */, CE2D935324AD46670059923A /* gcrypt.20.framework in Frameworks */, + 84CE3DAC2904C14100FF068B /* InAppSettingsKit in Frameworks */, CE2D935424AD46670059923A /* gobject-2.0.0.framework in Frameworks */, CE9A353426533A52005077CF /* JailbreakInterposer.framework in Frameworks */, CE2D935524AD46670059923A /* gsttag-1.0.0.framework in Frameworks */, @@ -2454,6 +2463,7 @@ CEA45F37263519B5002FA97D /* libgstvideotestsrc.a in Frameworks */, CEA45F38263519B5002FA97D /* libgstosxaudio.a in Frameworks */, CEA45F39263519B5002FA97D /* gmodule-2.0.0.framework in Frameworks */, + 846D878629050B6B0095F10B /* InAppSettingsKit in Frameworks */, CEA45F3A263519B5002FA97D /* jpeg.62.framework in Frameworks */, CEA45F3B263519B5002FA97D /* intl.8.framework in Frameworks */, CEA45F3C263519B5002FA97D /* gstapp-1.0.0.framework in Frameworks */, @@ -2721,10 +2731,12 @@ CE7BED4D22600F5000A1E1B6 /* Display */, CE8813D224CD230300532628 /* ActivityView.swift */, CED814EE24C7EB760042F0F1 /* ImagePicker.swift */, + 84CE3DAD2904C17C00FF068B /* IASKAppSettings.swift */, 841E58D02893AF5400137A20 /* UTMApp.swift */, CEBBF1A424B56A2900C15049 /* UTMDataExtension.swift */, 841E58CA28937EE200137A20 /* UTMExternalSceneDelegate.swift */, 841E58CD28937FED00137A20 /* UTMMainView.swift */, + 84CE3DB02904C7A100FF068B /* UTMSettingsView.swift */, 842B9F8C28CC58B700031EE7 /* UTMViewControllerPatches.swift */, CE2D954D24AD4F980059923A /* VMConfigNetworkPortForwardView.swift */, 84CF5DD2288DCE6400D01721 /* VMDisplayHostedView.swift */, @@ -3338,6 +3350,7 @@ 84B36D1D27B3264600C22685 /* CocoaSpice */, 840186592887AFD50050AC51 /* SwiftTerm */, 84018694288B66370050AC51 /* SwiftUIVisualEffects */, + 84CE3DAB2904C14100FF068B /* InAppSettingsKit */, ); productName = UTM; productReference = CE2D93BE24AD46670059923A /* UTM.app */; @@ -3410,6 +3423,7 @@ 84B36D1F27B3264E00C22685 /* CocoaSpiceNoUsb */, 8401865B2887AFDC0050AC51 /* SwiftTerm */, 84CF5DF2288E433F00D01721 /* SwiftUIVisualEffects */, + 846D878529050B6B0095F10B /* InAppSettingsKit */, ); productName = UTM; productReference = CEA45FB9263519B5002FA97D /* UTM SE.app */; @@ -3487,6 +3501,7 @@ 848F71E4277A2466006A0240 /* XCRemoteSwiftPackageReference "SwiftTerm" */, 84B36D1C27B3261E00C22685 /* XCRemoteSwiftPackageReference "CocoaSpice" */, 84018693288B66370050AC51 /* XCRemoteSwiftPackageReference "swiftui-visual-effects" */, + 84CE3DAA2904C14100FF068B /* XCRemoteSwiftPackageReference "InAppSettingsKit" */, ); productRefGroup = CE550BCA225947990063E575 /* Products */; projectDirPath = ""; @@ -3792,6 +3807,7 @@ CE2D92F424AD46670059923A /* qapi-types-sockets.c in Sources */, 8432329828C3017F00CFBC97 /* GlobalFileImporter.swift in Sources */, CE2D92F624AD46670059923A /* qapi-events-block-core.c in Sources */, + 84CE3DAE2904C17C00FF068B /* IASKAppSettings.swift in Sources */, 841E58CB28937EE200137A20 /* UTMExternalSceneDelegate.swift in Sources */, 84FCABBA268CE05E0036196C /* UTMQemuVirtualMachine.m in Sources */, CEB63A7A24F469E300CAF323 /* UTMJailbreak.m in Sources */, @@ -3852,6 +3868,7 @@ CE2D931924AD46670059923A /* qapi-types-misc-target.c in Sources */, CE2D931A24AD46670059923A /* qapi-events-rdma.c in Sources */, CE2D931D24AD46670059923A /* qapi-visit-dump.c in Sources */, + 84CE3DB12904C7A100FF068B /* UTMSettingsView.swift in Sources */, CE2D931E24AD46670059923A /* qapi-visit-error.c in Sources */, CE2D931F24AD46670059923A /* error.c in Sources */, CEF83EBA24F9ABEA00557D15 /* UTMQemuManager+BlockDevices.m in Sources */, @@ -4240,6 +4257,7 @@ CEA45E56263519B5002FA97D /* qapi-types-rdma.c in Sources */, CEA45E57263519B5002FA97D /* ImagePicker.swift in Sources */, 84F90A00289488F90008DBE2 /* MenuLabel.swift in Sources */, + 84CE3DAF2904C17C00FF068B /* IASKAppSettings.swift in Sources */, 84C4D9032880CA8A00EC3B2B /* VMSettingsAddDeviceMenuView.swift in Sources */, CEA45E58263519B5002FA97D /* qapi-commands-rocker.c in Sources */, CEA45E5A263519B5002FA97D /* VMConfigSystemView.swift in Sources */, @@ -4357,6 +4375,7 @@ CEA45EC2263519B5002FA97D /* qapi-dealloc-visitor.c in Sources */, CEA45EC3263519B5002FA97D /* VMCommands.swift in Sources */, CEA45EC4263519B5002FA97D /* qapi-visit-job.c in Sources */, + 84CE3DB22904C7A100FF068B /* UTMSettingsView.swift in Sources */, 8443EFF32845641600B2E6E2 /* UTMQemuConfigurationDrive.swift in Sources */, CEA45EC7263519B5002FA97D /* qapi-types-block.c in Sources */, CEA45EC8263519B5002FA97D /* qapi-events-machine.c in Sources */, @@ -5190,6 +5209,14 @@ kind = branch; }; }; + 84CE3DAA2904C14100FF068B /* XCRemoteSwiftPackageReference "InAppSettingsKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/futuretap/InAppSettingsKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 3.0.0; + }; + }; B329049A270FE136002707AC /* XCRemoteSwiftPackageReference "AltKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/rileytestut/AltKit.git"; @@ -5263,6 +5290,11 @@ package = 84018693288B66370050AC51 /* XCRemoteSwiftPackageReference "swiftui-visual-effects" */; productName = SwiftUIVisualEffects; }; + 846D878529050B6B0095F10B /* InAppSettingsKit */ = { + isa = XCSwiftPackageProductDependency; + package = 84CE3DAA2904C14100FF068B /* XCRemoteSwiftPackageReference "InAppSettingsKit" */; + productName = InAppSettingsKit; + }; 848F71E5277A2466006A0240 /* SwiftTerm */ = { isa = XCSwiftPackageProductDependency; package = 848F71E4277A2466006A0240 /* XCRemoteSwiftPackageReference "SwiftTerm" */; @@ -5283,6 +5315,11 @@ package = 84B36D1C27B3261E00C22685 /* XCRemoteSwiftPackageReference "CocoaSpice" */; productName = CocoaSpice; }; + 84CE3DAB2904C14100FF068B /* InAppSettingsKit */ = { + isa = XCSwiftPackageProductDependency; + package = 84CE3DAA2904C14100FF068B /* XCRemoteSwiftPackageReference "InAppSettingsKit" */; + productName = InAppSettingsKit; + }; 84CF5DF2288E433F00D01721 /* SwiftUIVisualEffects */ = { isa = XCSwiftPackageProductDependency; package = 84018693288B66370050AC51 /* XCRemoteSwiftPackageReference "swiftui-visual-effects" */; diff --git a/UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 041322a4f..4cb6023ad 100644 --- a/UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/UTM.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -18,6 +18,15 @@ "revision" : "33f9e8e7cee801137238d33b793b92392d7a9854" } }, + { + "identity" : "inappsettingskit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/futuretap/InAppSettingsKit.git", + "state" : { + "revision" : "1c5122f51206ea86b2301ea8a93e7703617a9b40", + "version" : "3.3.6" + } + }, { "identity" : "iqkeyboardmanager", "kind" : "remoteSourceControl",