Add App placeholder feature

This feature represents the "entrypoint" of the app.

As it stands now it combines the home, and onboarding features.

Notice how we have created `AppReducer.routeReducer` to (temporarily)
use use the `OnboardingAction.createWallet` action, to navigate directly
to `Home` while we are still implementing it.
This commit is contained in:
Daniel Haight 2021-12-14 00:51:31 +00:00
parent c0dd6f8015
commit 9f7c5c158a
3 changed files with 175 additions and 0 deletions

View File

@ -107,6 +107,8 @@
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E5273B501F0021B49A /* TransactionDetailView.swift */; };
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */; };
F96B41EB273B50520021B49A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41EA273B50520021B49A /* Strings.swift */; };
F9971A4D27680DC400A2DB75 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4A27680DC400A2DB75 /* App.swift */; };
F9971A4E27680DC400A2DB75 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4C27680DC400A2DB75 /* AppView.swift */; };
F9971A5327680DD000A2DB75 /* Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5027680DD000A2DB75 /* Profile.swift */; };
F9971A5427680DD000A2DB75 /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5227680DD000A2DB75 /* ProfileView.swift */; };
F9971A5927680DDE00A2DB75 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5627680DDE00A2DB75 /* Request.swift */; };
@ -250,6 +252,8 @@
F96B41E5273B501F0021B49A /* TransactionDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionDetailView.swift; sourceTree = "<group>"; };
F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryView.swift; sourceTree = "<group>"; };
F96B41EA273B50520021B49A /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
F9971A4A27680DC400A2DB75 /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
F9971A4C27680DC400A2DB75 /* AppView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = "<group>"; };
F9971A5027680DD000A2DB75 /* Profile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = "<group>"; };
F9971A5227680DD000A2DB75 /* ProfileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
F9971A5627680DDE00A2DB75 /* Request.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
@ -715,6 +719,7 @@
6654C73B2715A3F000901167 /* Features */ = {
isa = PBXGroup;
children = (
F9971A4927680DC400A2DB75 /* App */,
F93874EC273C4DE200F0E875 /* Home */,
F9971A4F27680DD000A2DB75 /* Profile */,
F9971A5527680DDE00A2DB75 /* Request */,
@ -815,6 +820,23 @@
path = Views;
sourceTree = "<group>";
};
F9971A4927680DC400A2DB75 /* App */ = {
isa = PBXGroup;
children = (
F9971A4A27680DC400A2DB75 /* App.swift */,
F9971A4B27680DC400A2DB75 /* Views */,
);
path = App;
sourceTree = "<group>";
};
F9971A4B27680DC400A2DB75 /* Views */ = {
isa = PBXGroup;
children = (
F9971A4C27680DC400A2DB75 /* AppView.swift */,
);
path = Views;
sourceTree = "<group>";
};
F9971A4F27680DD000A2DB75 /* Profile */ = {
isa = PBXGroup;
children = (
@ -1149,12 +1171,14 @@
0D18581B272728D60046B928 /* PhraseChip.swift in Sources */,
665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */,
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */,
F9971A4D27680DC400A2DB75 /* App.swift in Sources */,
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */,
F93874F1273C4DE200F0E875 /* HomeView.swift in Sources */,
0D32282326C586A800262533 /* HistoryScreen.swift in Sources */,
0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */,
F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */,
0D864A0A26E154FD00A61879 /* InitFailedScreenViewModel.swift in Sources */,
F9971A4E27680DC400A2DB75 /* AppView.swift in Sources */,
0DA13CA526C1963000E3B610 /* Balance.swift in Sources */,
2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */,
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */,

View File

@ -0,0 +1,84 @@
import ComposableArchitecture
struct AppState: Equatable {
enum Route {
case startup
case onboarding
case home
}
var homeState: HomeState
var onboardingState: OnboardingState
var route: Route = .startup
}
enum AppAction: Equatable {
case updateRoute(AppState.Route)
case home(HomeAction)
case onboarding(OnboardingAction)
}
struct AppEnvironment: Equatable {
}
// MARK: - AppReducer
typealias AppReducer = Reducer<AppState, AppAction, AppEnvironment>
extension AppReducer {
static let `default` = AppReducer.combine(
[
routeReducer,
homeReducer,
onboardingReducer
]
)
private static let routeReducer = AppReducer { state, action, environment in
switch action {
case let .updateRoute(route):
state.route = route
case .onboarding(.createNewWallet):
state.route = .home
default:
break
}
return .none
}
private static let homeReducer: AppReducer = HomeReducer.default.pullback(
state: \AppState.homeState,
action: /AppAction.home,
environment: { _ in }
)
private static let onboardingReducer: AppReducer = OnboardingReducer.default.pullback(
state: \AppState.onboardingState,
action: /AppAction.onboarding,
environment: { _ in }
)
}
// MARK: - AppStore
typealias AppStore = Store<AppState, AppAction>
extension AppStore {
}
// MARK: - AppViewStore
typealias AppViewStore = ViewStore<AppState, AppAction>
extension AppViewStore {
}
// MARK: PlaceHolders
extension AppState {
static var placeholder: Self {
.init(
homeState: .placeholder,
onboardingState: .init()
)
}
}

View File

@ -0,0 +1,67 @@
import SwiftUI
import StoreKit
import ComposableArchitecture
struct AppView: View {
let store: AppStore
var body: some View {
WithViewStore(store) { viewStore in
switch viewStore.route {
case .home:
NavigationView {
HomeView(
store: store.scope(
state: \.homeState,
action: AppAction.home
)
)
}
.navigationViewStyle(StackNavigationViewStyle())
case .onboarding:
OnboardingScreen(
store: store.scope(
state: \.onboardingState,
action: AppAction.onboarding
)
)
case .startup:
ZStack(alignment: .topTrailing) {
StartupView(sendAction: viewStore.send)
}
}
}
}
}
private struct StartupView: View {
var sendAction: (AppAction) -> Void
var body: some View {
List {
Section(header: Text("Navigation Stack Routes")) {
Button("Go To Home") {
sendAction(.updateRoute(.home))
}
Button("Go To Onboarding") {
sendAction(.updateRoute(.onboarding))
}
}
}
.navigationBarTitle("Startup")
}
}
struct AppView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
AppView(
store: AppStore(
initialState: .placeholder,
reducer: .default,
environment: .init()
)
)
}
}
}