Pārlūkot izejas kodu

home(iOS): add integrated in-app settings popover

Resolves #4446
osy 2 gadi atpakaļ
vecāks
revīzija
b17c5de891

+ 11 - 0
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 {

+ 52 - 0
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
+}
+
+private 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()
+    }
+}

+ 43 - 0
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<PresentationMode>
+    
+    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()
+    }
+}

+ 37 - 0
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 = "<group>"; };
 		84C60FB62681A41B00B58C00 /* VMToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarView.swift; sourceTree = "<group>"; };
 		84C60FB9268269D700B58C00 /* VMDisplayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayViewController.swift; sourceTree = "<group>"; };
+		84CE3DAD2904C17C00FF068B /* IASKAppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IASKAppSettings.swift; sourceTree = "<group>"; };
+		84CE3DB02904C7A100FF068B /* UTMSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMSettingsView.swift; sourceTree = "<group>"; };
 		84CF5DD2288DCE6400D01721 /* VMDisplayHostedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayHostedView.swift; sourceTree = "<group>"; };
 		84CF5DF4288F558400D01721 /* VMToolbarDriveMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarDriveMenuView.swift; sourceTree = "<group>"; };
 		84E6F6FC289319AE00080EEF /* VMToolbarDisplayMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarDisplayMenuView.swift; sourceTree = "<group>"; };
@@ -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" */;

+ 9 - 0
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",