mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Fix disabling horizontal scroll on onboarding screens and made showing only certain steps more reusable
This commit is contained in:
@@ -53,6 +53,7 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
|
|||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(true)
|
super.viewDidAppear(true)
|
||||||
|
|
||||||
#if !targetEnvironment(simulator)
|
#if !targetEnvironment(simulator)
|
||||||
if !UserDefaults.standard.onboardingComplete {
|
if !UserDefaults.standard.onboardingComplete {
|
||||||
self.showOnboarding()
|
self.showOnboarding()
|
||||||
@@ -62,15 +63,15 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
|
|||||||
start_em_proxy(bind_addr: Consts.Proxy.serverURL)
|
start_em_proxy(bind_addr: Consts.Proxy.serverURL)
|
||||||
|
|
||||||
guard let pf = fetchPairingFile() else {
|
guard let pf = fetchPairingFile() else {
|
||||||
self.showOnboarding(step: .pairing)
|
self.showOnboarding(enabledSteps: [.pairing])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
start_minimuxer_threads(pf)
|
start_minimuxer_threads(pf)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
func showOnboarding(step: OnboardingView.OnboardingStep = .welcome) {
|
func showOnboarding(enabledSteps: [OnboardingStep] = OnboardingStep.allCases) {
|
||||||
let onboardingView = OnboardingView(onDismiss: { self.dismiss(animated: true) }, currentStep: step)
|
let onboardingView = OnboardingView(onDismiss: { self.dismiss(animated: true) }, enabledSteps: enabledSteps)
|
||||||
.environment(\.managedObjectContext, DatabaseManager.shared.viewContext)
|
.environment(\.managedObjectContext, DatabaseManager.shared.viewContext)
|
||||||
let navigationController = UINavigationController(rootViewController: UIHostingController(rootView: onboardingView))
|
let navigationController = UINavigationController(rootViewController: UIHostingController(rootView: onboardingView))
|
||||||
navigationController.isNavigationBarHidden = true
|
navigationController.isNavigationBarHidden = true
|
||||||
|
|||||||
@@ -9,22 +9,6 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
|
||||||
struct OnboardingStep<Title: View, Hero: View, Content: View, Action: View> {
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
var title: Title
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
var hero: Hero
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
var content: Content
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
var action: Action
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct OnboardingStepView<Title: View, Hero: View, Content: View, Action: View>: View {
|
struct OnboardingStepView<Title: View, Hero: View, Content: View, Action: View>: View {
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
@@ -49,6 +33,7 @@ struct OnboardingStepView<Title: View, Hero: View, Content: View, Action: View>:
|
|||||||
.frame(height: 150)
|
.frame(height: 150)
|
||||||
|
|
||||||
self.content
|
self.content
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
|
|||||||
@@ -14,17 +14,19 @@ import Reachability
|
|||||||
import UniformTypeIdentifiers
|
import UniformTypeIdentifiers
|
||||||
|
|
||||||
|
|
||||||
struct OnboardingView: View {
|
enum OnboardingStep: Int, CaseIterable {
|
||||||
enum OnboardingStep: Int, CaseIterable {
|
|
||||||
case welcome, pairing, wireguard, wireguardConfig, addSources, finish
|
case welcome, pairing, wireguard, wireguardConfig, addSources, finish
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OnboardingView: View {
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
// Temporary workaround for UIKit compatibility
|
// Temporary workaround for UIKit compatibility
|
||||||
var onDismiss: (() -> Void)? = nil
|
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 pairingFileURL: URL? = nil
|
||||||
@State private var isWireGuardAppStorePageVisible: Bool = false
|
@State private var isWireGuardAppStorePageVisible: Bool = false
|
||||||
@State private var isDownloadingWireGuardProfile: Bool = false
|
@State private var isDownloadingWireGuardProfile: Bool = false
|
||||||
@@ -38,34 +40,25 @@ struct OnboardingView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
TabView(selection: self.$currentStep) {
|
TabView(selection: self.$currentStep) {
|
||||||
welcomeStep
|
ForEach(self.enabledSteps, id: \.self) { step in
|
||||||
.tag(OnboardingStep.welcome)
|
self.viewForStep(step)
|
||||||
|
.tag(step)
|
||||||
|
// Hack to disable horizontal scrolling in onboarding screens
|
||||||
|
.background(
|
||||||
|
Color.black
|
||||||
|
.opacity(0.001)
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
)
|
||||||
.highPriorityGesture(DragGesture())
|
.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())
|
|
||||||
|
|
||||||
}
|
}
|
||||||
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
|
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
|
||||||
.edgesIgnoringSafeArea(.bottom)
|
.edgesIgnoringSafeArea(.bottom)
|
||||||
.background(Color.accentColor.opacity(0.1).edgesIgnoringSafeArea(.all))
|
.background(
|
||||||
|
Color.accentColor
|
||||||
|
.opacity(0.1)
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
)
|
||||||
.onChange(of: self.currentStep) { step in
|
.onChange(of: self.currentStep) { step in
|
||||||
switch step {
|
switch step {
|
||||||
case .wireguardConfig:
|
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 {
|
var welcomeStep: some View {
|
||||||
OnboardingStepView {
|
OnboardingStepView {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
@@ -118,7 +105,7 @@ struct OnboardingView: View {
|
|||||||
.shadow(color: .accentColor.opacity(0.8), radius: 12)
|
.shadow(color: .accentColor.opacity(0.8), radius: 12)
|
||||||
}, content: {
|
}, content: {
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
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("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 `<UUID>.mobiledevicepairing`, import it using the button below.")
|
Text("Once you have the `<UUID>.mobiledevicepairing`, import it using the button below.")
|
||||||
}
|
}
|
||||||
@@ -251,7 +238,7 @@ struct OnboardingView: View {
|
|||||||
}, content: {
|
}, content: {
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
Text("Congratulations, you did it! 🎉")
|
Text("Congratulations, you did it! 🎉")
|
||||||
Text("You can start your sideloading journey.")
|
Text("You can now start your sideloading journey.")
|
||||||
}
|
}
|
||||||
}, action: {
|
}, action: {
|
||||||
SwiftUI.Button("Let's Go") {
|
SwiftUI.Button("Let's Go") {
|
||||||
@@ -260,6 +247,31 @@ struct OnboardingView: View {
|
|||||||
.buttonStyle(FilledButtonStyle())
|
.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 {
|
extension OnboardingView {
|
||||||
@@ -287,7 +299,6 @@ extension OnboardingView {
|
|||||||
|
|
||||||
// Show the next onboarding step
|
// Show the next onboarding step
|
||||||
self.showNextStep()
|
self.showNextStep()
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
NotificationManager.shared.reportError(error: error)
|
NotificationManager.shared.reportError(error: error)
|
||||||
}
|
}
|
||||||
@@ -432,11 +443,11 @@ extension OnboardingView {
|
|||||||
|
|
||||||
struct OnboardingView_Previews: PreviewProvider {
|
struct OnboardingView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ForEach(OnboardingView.OnboardingStep.allCases, id: \.self) { step in
|
ForEach(OnboardingStep.allCases, id: \.self) { step in
|
||||||
Color.red
|
Color.red
|
||||||
.ignoresSafeArea()
|
.ignoresSafeArea()
|
||||||
.sheet(isPresented: .constant(true)) {
|
.sheet(isPresented: .constant(true)) {
|
||||||
OnboardingView(currentStep: step)
|
OnboardingView(enabledSteps: [step])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user