secant-ios-wallet/secant/Features/Onboarding/OnboardingStore.swift

125 lines
3.4 KiB
Swift
Raw Normal View History

2021-10-12 04:25:34 -07:00
//
// Onboarding.swift
// OnboardingTCA
//
// Created by Adam Stener on 10/10/21.
//
import Foundation
import SwiftUI
import ComposableArchitecture
typealias OnboardingViewStore = ViewStore<OnboardingState, OnboardingAction>
2021-10-12 04:25:34 -07:00
struct OnboardingState: Equatable {
enum Route: Equatable, CaseIterable {
case createNewWallet
case importExistingWallet
}
2021-11-09 03:59:03 -08:00
struct Step: Equatable, Identifiable {
let id: UUID
let title: LocalizedStringKey
let description: LocalizedStringKey
2021-11-09 03:59:03 -08:00
let background: Image
let badge: Badge
}
var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
2021-10-12 04:25:34 -07:00
var index = 0
2021-11-04 05:41:39 -07:00
var skippedAtindex: Int?
var route: Route?
2021-11-09 03:59:03 -08:00
var currentStep: Step { steps[index] }
var isFinalStep: Bool { steps.count == index + 1 }
var isInitialStep: Bool { index == 0 }
2021-11-04 05:41:39 -07:00
var progress: Int { ((index + 1) * 100) / (steps.count) }
2021-11-05 05:26:20 -07:00
var offset: CGFloat {
let maxOffset = CGFloat(-60)
let stepOffset = CGFloat(maxOffset / CGFloat(steps.count - 1))
guard index != 0 else { return .zero }
return stepOffset * CGFloat(index)
}
/// Import Wallet
var importWalletState: ImportWalletState
}
extension OnboardingViewStore {
func bindingForRoute(_ route: OnboardingState.Route) -> Binding<Bool> {
self.binding(
get: { $0.route == route },
send: { isActive in
return .updateRoute(isActive ? route : nil)
}
)
}
2021-10-12 04:25:34 -07:00
}
enum OnboardingAction: Equatable {
2021-11-04 05:41:39 -07:00
case next
case back
case skip
case updateRoute(OnboardingState.Route?)
2021-11-04 05:41:39 -07:00
case createNewWallet
case importExistingWallet
case importWallet(ImportWalletAction)
2021-10-12 04:25:34 -07:00
}
2021-11-09 03:59:03 -08:00
typealias OnboardingReducer = Reducer<OnboardingState, OnboardingAction, Void>
extension OnboardingReducer {
static let `default` = OnboardingReducer.combine(
[
onboardingReducer,
importWalletReducer
]
)
private static let onboardingReducer = OnboardingReducer { state, action, _ in
2021-11-09 03:59:03 -08:00
switch action {
case .back:
guard state.index > 0 else { return .none }
if let skippedFrom = state.skippedAtindex {
state.index = skippedFrom
state.skippedAtindex = nil
} else {
state.index -= 1
}
return .none
case .next:
guard state.index < state.steps.count - 1 else { return .none }
state.index += 1
return .none
case .skip:
guard state.skippedAtindex == nil else { return .none }
state.skippedAtindex = state.index
state.index = state.steps.count - 1
return .none
case .updateRoute(let route):
state.route = route
return .none
2021-11-09 03:59:03 -08:00
case .createNewWallet:
state.route = .createNewWallet
2021-11-09 03:59:03 -08:00
return .none
case .importExistingWallet:
state.route = .importExistingWallet
return .none
case .importWallet(let route):
return .none
2021-11-04 05:41:39 -07:00
}
2021-10-12 04:25:34 -07:00
}
private static let importWalletReducer: OnboardingReducer = ImportWalletReducer.default.pullback(
state: \OnboardingState.importWalletState,
action: /OnboardingAction.importWallet,
environment: { _ in ImportWalletEnvironment.live }
)
2021-10-12 04:25:34 -07:00
}