gestures added

debug menus are accessible starting on welcome screen following 2 steps:
1. long press (0.75s)
2. swipe up/down to access either home/startup

cleanup

Debug menus connected

Also fixed the App flow
This commit is contained in:
Lukas Korba 2022-04-04 13:23:57 +02:00
parent 3a70472c9f
commit 71deb3c757
5 changed files with 114 additions and 6 deletions

View File

@ -86,6 +86,7 @@
9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E37A2B727C8F59F00AE57B3 /* Localizable.strings */; };
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; };
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
9E69A24D27FB002800A55317 /* Welcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* Welcome.swift */; };
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */; };
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */; };
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
@ -225,6 +226,7 @@
9E37A2B727C8F59F00AE57B3 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = "<group>"; };
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
9E69A24C27FB002800A55317 /* Welcome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Welcome.swift; sourceTree = "<group>"; };
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = "<group>"; };
9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseTestPreambleView.swift; sourceTree = "<group>"; };
9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorageTests.swift; sourceTree = "<group>"; };
@ -292,6 +294,7 @@
0D0781C2278750C00083ACD7 /* Welcome */ = {
isa = PBXGroup;
children = (
9E69A24C27FB002800A55317 /* Welcome.swift */,
0D0781C3278750E30083ACD7 /* WelcomeView.swift */,
);
path = Welcome;
@ -1147,6 +1150,7 @@
F9971A6027680DF600A2DB75 /* Scan.swift in Sources */,
9EF8139127F191BF0075AF48 /* WalletStorageInteractor.swift in Sources */,
0DFE93E1272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift in Sources */,
9E69A24D27FB002800A55317 /* Welcome.swift in Sources */,
F9C165CB2741AB5D00592F76 /* SendView.swift in Sources */,
0D0781C4278750E30083ACD7 /* WelcomeView.swift in Sources */,
F9971A6527680DFE00A2DB75 /* Settings.swift in Sources */,

View File

@ -14,6 +14,7 @@ struct AppState: Equatable {
var onboardingState: OnboardingState
var phraseValidationState: RecoveryPhraseValidationState
var phraseDisplayState: RecoveryPhraseDisplayState
var welcomeState: WelcomeState
var route: Route = .welcome
var storedWallet: StoredWallet?
var appInitializationState: InitializationState = .uninitialized
@ -29,6 +30,7 @@ enum AppAction: Equatable {
case phraseDisplay(RecoveryPhraseDisplayAction)
case phraseValidation(RecoveryPhraseValidationAction)
case updateRoute(AppState.Route)
case welcome(WelcomeAction)
}
struct AppEnvironment {
@ -53,6 +55,8 @@ extension AppEnvironment {
// MARK: - AppReducer
private struct ListenerId: Hashable {}
typealias AppReducer = Reducer<AppState, AppAction, AppEnvironment>
extension AppReducer {
@ -123,6 +127,7 @@ extension AppReducer {
return Effect(value: .updateRoute(.onboarding))
.delay(for: 3, scheduler: environment.scheduler)
.eraseToEffect()
.cancellable(id: ListenerId(), cancelInFlight: true)
}
return .none
@ -143,6 +148,18 @@ extension AppReducer {
.delay(for: 3, scheduler: environment.scheduler)
.eraseToEffect()
case .welcome(.debugMenuHome):
return .concatenate(
Effect.cancel(id: ListenerId()),
Effect(value: .updateRoute(.home))
)
case .welcome(.debugMenuStartup):
return .concatenate(
Effect.cancel(id: ListenerId()),
Effect(value: .updateRoute(.startup))
)
/// Default is meaningful here because there's `routeReducer` handling routes and this reducer is handling only actions. We don't here plenty of unused cases.
default:
return .none
@ -201,6 +218,12 @@ extension AppReducer {
action: /AppAction.phraseDisplay,
environment: { _ in BackupPhraseEnvironment.demo }
)
private static let welcomeReducer: AppReducer = WelcomeReducer.default.pullback(
state: \AppState.welcomeState,
action: /AppAction.welcome,
environment: { _ in }
)
}
// MARK: - AppStore
@ -236,7 +259,8 @@ extension AppState {
phraseValidationState: RecoveryPhraseValidationState.placeholder,
phraseDisplayState: RecoveryPhraseDisplayState(
phrase: .placeholder
)
),
welcomeState: .placeholder
)
}
}

View File

@ -57,8 +57,13 @@ struct AppView: View {
)
}
case .welcome:
WelcomeView()
.onAppear(perform: { viewStore.send(.checkWalletInitialization) })
WelcomeView(
store: store.scope(
state: \.welcomeState,
action: AppAction.welcome
)
)
.onAppear(perform: { viewStore.send(.checkWalletInitialization) })
}
}
}

View File

@ -0,0 +1,38 @@
//
// Welcome.swift
// secant-testnet
//
// Created by Lukáš Korba on 04.04.2022.
//
import Foundation
import ComposableArchitecture
struct WelcomeState: Equatable {}
extension WelcomeState {
static let placeholder = WelcomeState()
}
enum WelcomeAction: Equatable {
case debugMenuStartup
case debugMenuHome
}
typealias WelcomeReducer = Reducer<WelcomeState, WelcomeAction, Void>
extension WelcomeReducer {
static let `default` = WelcomeReducer { _, _, _ in
return .none
}
}
typealias WelcomeStore = Store<WelcomeState, WelcomeAction>
extension WelcomeStore {
static var demo = WelcomeStore(
initialState: .placeholder,
reducer: .default,
environment: ()
)
}

View File

@ -6,13 +6,49 @@
//
import SwiftUI
import ComposableArchitecture
struct WelcomeView: View {
var store: WelcomeStore
enum DragState {
case inactive
case pressing
case dragging(translation: CGSize)
}
let topPaddingRatio: Double = 0.18
let horizontalPaddingRatio: Double = 0.07
@GestureState var dragState = DragState.inactive
var body: some View {
GeometryReader { proxy in
let longPressDrag = LongPressGesture(minimumDuration: 0.75)
.sequenced(before: DragGesture())
.updating($dragState) { value, state, _ in
switch value {
// Long press begins.
case .first(true):
state = .pressing
// Long press confirmed, dragging may begin.
case .second(true, let drag):
state = .dragging(translation: drag?.translation ?? .zero)
// Dragging ended or the long press cancelled.
default:
state = .inactive
}
}
.onEnded { value in
guard case .second(true, let drag?) = value else { return }
if drag.translation.height < 0 {
ViewStore(store).send(.debugMenuHome)
} else {
ViewStore(store).send(.debugMenuStartup)
}
}
return GeometryReader { proxy in
ZStack(alignment: .top) {
VStack(alignment: .center, spacing: 80) {
let diameter = proxy.size.width - 40
@ -21,6 +57,7 @@ struct WelcomeView: View {
width: diameter,
height: diameter
)
.gesture(longPressDrag)
VStack {
Text("welcomeScreen.title")
@ -118,10 +155,10 @@ struct WelcomeView_Previews: PreviewProvider {
.preferredColorScheme(.light)
Group {
WelcomeView()
WelcomeView(store: .demo)
.preferredColorScheme(.dark)
WelcomeView()
WelcomeView(store: .demo)
.previewDevice("iPhone SE (2nd generation)")
}
}