From 2939919ddb3805c94442200ba2ff2cba0dac4b61 Mon Sep 17 00:00:00 2001 From: Fabian Thies Date: Sat, 20 May 2023 22:14:50 +0200 Subject: [PATCH] Fix disabling horizontal scroll on onboarding screens and made showing only certain steps more reusable --- AltStore/LaunchViewController.swift | 7 +- .../Views/Onboarding/OnboardingStepView.swift | 17 +--- .../Views/Onboarding/OnboardingView.swift | 91 +++++++++++-------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 692c8bbb..3c3d50ec 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -53,6 +53,7 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(true) + #if !targetEnvironment(simulator) if !UserDefaults.standard.onboardingComplete { self.showOnboarding() @@ -62,15 +63,15 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg start_em_proxy(bind_addr: Consts.Proxy.serverURL) guard let pf = fetchPairingFile() else { - self.showOnboarding(step: .pairing) + self.showOnboarding(enabledSteps: [.pairing]) return } start_minimuxer_threads(pf) #endif } - func showOnboarding(step: OnboardingView.OnboardingStep = .welcome) { - let onboardingView = OnboardingView(onDismiss: { self.dismiss(animated: true) }, currentStep: step) + func showOnboarding(enabledSteps: [OnboardingStep] = OnboardingStep.allCases) { + let onboardingView = OnboardingView(onDismiss: { self.dismiss(animated: true) }, enabledSteps: enabledSteps) .environment(\.managedObjectContext, DatabaseManager.shared.viewContext) let navigationController = UINavigationController(rootViewController: UIHostingController(rootView: onboardingView)) navigationController.isNavigationBarHidden = true diff --git a/AltStore/Views/Onboarding/OnboardingStepView.swift b/AltStore/Views/Onboarding/OnboardingStepView.swift index 1cc15d30..095fa46c 100644 --- a/AltStore/Views/Onboarding/OnboardingStepView.swift +++ b/AltStore/Views/Onboarding/OnboardingStepView.swift @@ -9,22 +9,6 @@ import SwiftUI -struct OnboardingStep { - - @ViewBuilder - var title: Title - - @ViewBuilder - var hero: Hero - - @ViewBuilder - var content: Content - - @ViewBuilder - var action: Action -} - - struct OnboardingStepView: View { @ViewBuilder @@ -49,6 +33,7 @@ struct OnboardingStepView: .frame(height: 150) self.content + .frame(maxWidth: .infinity, alignment: .leading) Spacer() diff --git a/AltStore/Views/Onboarding/OnboardingView.swift b/AltStore/Views/Onboarding/OnboardingView.swift index 53e5e799..c51425fa 100644 --- a/AltStore/Views/Onboarding/OnboardingView.swift +++ b/AltStore/Views/Onboarding/OnboardingView.swift @@ -14,17 +14,19 @@ import Reachability import UniformTypeIdentifiers +enum OnboardingStep: Int, CaseIterable { + case welcome, pairing, wireguard, wireguardConfig, addSources, finish +} + struct OnboardingView: View { - enum OnboardingStep: Int, CaseIterable { - case welcome, pairing, wireguard, wireguardConfig, addSources, finish - } @Environment(\.dismiss) var dismiss // Temporary workaround for UIKit compatibility var onDismiss: (() -> Void)? = nil - @State var currentStep: OnboardingStep = .wireguard //.welcome + var enabledSteps = OnboardingStep.allCases + @State private var currentStep: OnboardingStep = .welcome @State private var pairingFileURL: URL? = nil @State private var isWireGuardAppStorePageVisible: Bool = false @State private var isDownloadingWireGuardProfile: Bool = false @@ -38,34 +40,25 @@ struct OnboardingView: View { var body: some View { TabView(selection: self.$currentStep) { - welcomeStep - .tag(OnboardingStep.welcome) - .highPriorityGesture(DragGesture()) - - pairingView - .tag(OnboardingStep.pairing) - .highPriorityGesture(DragGesture()) - - wireguardView - .tag(OnboardingStep.wireguard) - .highPriorityGesture(DragGesture()) - - wireguardConfigView - .tag(OnboardingStep.wireguardConfig) - .highPriorityGesture(DragGesture()) - - addSourcesView - .tag(OnboardingStep.addSources) - .highPriorityGesture(DragGesture()) - - finishView - .tag(OnboardingStep.finish) - .highPriorityGesture(DragGesture()) - + ForEach(self.enabledSteps, id: \.self) { step in + self.viewForStep(step) + .tag(step) + // Hack to disable horizontal scrolling in onboarding screens + .background( + Color.black + .opacity(0.001) + .edgesIgnoringSafeArea(.all) + ) + .highPriorityGesture(DragGesture()) + } } .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) .edgesIgnoringSafeArea(.bottom) - .background(Color.accentColor.opacity(0.1).edgesIgnoringSafeArea(.all)) + .background( + Color.accentColor + .opacity(0.1) + .edgesIgnoringSafeArea(.all) + ) .onChange(of: self.currentStep) { step in switch step { case .wireguardConfig: @@ -76,12 +69,6 @@ struct OnboardingView: View { } } - func showNextStep() { - withAnimation { - self.currentStep = OnboardingStep(rawValue: self.currentStep.rawValue + 1) ?? self.currentStep - } - } - var welcomeStep: some View { OnboardingStepView { VStack(alignment: .leading) { @@ -118,7 +105,7 @@ struct OnboardingView: View { .shadow(color: .accentColor.opacity(0.8), radius: 12) }, content: { VStack(alignment: .leading, spacing: 16) { - Text("SideStore supports sideloading even on non-jailbroken devices.") + Text("SideStore supports on-device sideloading even on non-jailbroken devices.") Text("For it to work, you have to generate a pairing file as described [here in our documentation](https://wiki.sidestore.io/guides/install#pairing-process).") Text("Once you have the `.mobiledevicepairing`, import it using the button below.") } @@ -251,7 +238,7 @@ struct OnboardingView: View { }, content: { VStack(alignment: .leading, spacing: 16) { Text("Congratulations, you did it! 🎉") - Text("You can start your sideloading journey.") + Text("You can now start your sideloading journey.") } }, action: { SwiftUI.Button("Let's Go") { @@ -260,6 +247,31 @@ struct OnboardingView: View { .buttonStyle(FilledButtonStyle()) }) } + + @ViewBuilder + func viewForStep(_ step: OnboardingStep) -> some View { + switch step { + case .welcome: self.welcomeStep + case .pairing: self.pairingView + case .wireguard: self.wireguardView + case .wireguardConfig: self.wireguardConfigView + case .addSources: self.addSourcesView + case .finish: self.finishView + } + } +} + +extension OnboardingView { + func showNextStep() { + guard self.currentStep != self.enabledSteps.last, + let index = self.enabledSteps.firstIndex(of: self.currentStep) else { + return self.finishOnboarding() + } + + withAnimation { + self.currentStep = self.enabledSteps[index + 1] + } + } } extension OnboardingView { @@ -287,7 +299,6 @@ extension OnboardingView { // Show the next onboarding step self.showNextStep() - } catch { NotificationManager.shared.reportError(error: error) } @@ -432,11 +443,11 @@ extension OnboardingView { struct OnboardingView_Previews: PreviewProvider { static var previews: some View { - ForEach(OnboardingView.OnboardingStep.allCases, id: \.self) { step in + ForEach(OnboardingStep.allCases, id: \.self) { step in Color.red .ignoresSafeArea() .sheet(isPresented: .constant(true)) { - OnboardingView(currentStep: step) + OnboardingView(enabledSteps: [step]) } } }