Newer
Older
import ComposableArchitecture
import HomeFeature
import RestoreFeature
import SwiftUI
import WelcomeFeature
struct AppView: View {
let store: Store<AppState, AppAction>
case loading
case welcome
case restore
init(_ state: AppState) {
switch state.screen {
case .loading: self = .loading
case .welcome(_): self = .welcome
case .restore(_): self = .restore
case .failure(let failure): self = .failure(failure)
WithViewStore(store, observe: ViewState.init) { viewStore in
switch viewStore.state {
case .loading:
ProgressView {
Text("Loading")
}
.controlSize(.large)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.opacity)
case .welcome:
IfLetStore(
store.scope(
state: { (/AppState.Screen.welcome).extract(from: $0.screen) },
action: AppAction.welcome
),
then: { store in
WelcomeView(store: store)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .opacity
))
}
)
case .restore:
IfLetStore(
store.scope(
state: { (/AppState.Screen.restore).extract(from: $0.screen) },
action: AppAction.restore
),
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .opacity
))
case .home:
IfLetStore(
store.scope(
state: { (/AppState.Screen.home).extract(from: $0.screen) },
action: AppAction.home
),
then: { store in
HomeView(store: store)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .opacity
))
}
)
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
case .failure(let failure):
NavigationView {
VStack(spacing: 0) {
ScrollView {
Text(failure)
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
}
Divider()
Button {
viewStore.send(.start)
} label: {
Text("Retry")
.frame(maxWidth: .infinity)
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
.padding()
}
.navigationTitle("Error")
}
.navigationViewStyle(.stack)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .opacity
))
}
}
.animation(.default, value: viewStore.state)
.onShake {
isPresentingPulse = true
}
.fullScreenCover(isPresented: $isPresentingPulse) {
PulseUI.MainView(
store: .shared,
onDismiss: { isPresentingPulse = false }
)
}