Merge pull request #230 from LukasKorba/200_hidden_debug_menus
Hidden gestures to access debug menus added
This commit is contained in:
commit
e2d973b984
|
@ -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 */,
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: ()
|
||||
)
|
||||
}
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue