From 1f170097b2f6621ea6b1df04762d780a36282f3d Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 8 Jun 2022 12:57:11 +0200 Subject: [PATCH] Present MyIdentityView from SessionView --- Example/example-app/Package.swift | 2 + .../example-app/Sources/AppFeature/App.swift | 5 ++- .../MyIdentityFeature/MyIdentityFeature.swift | 8 +++- .../MyIdentityFeature/MyIdentityView.swift | 2 +- .../SessionFeature/SessionFeature.swift | 40 +++++++++++++++++-- .../Sources/SessionFeature/SessionView.swift | 25 ++++++++++++ .../SessionFeatureTests.swift | 22 ++++++++++ 7 files changed, 97 insertions(+), 7 deletions(-) diff --git a/Example/example-app/Package.swift b/Example/example-app/Package.swift index cb8aead7..0c0ef222 100644 --- a/Example/example-app/Package.swift +++ b/Example/example-app/Package.swift @@ -62,6 +62,7 @@ let package = Package( dependencies: [ .target(name: "ErrorFeature"), .target(name: "LandingFeature"), + .target(name: "MyIdentityFeature"), .target(name: "SessionFeature"), .product( name: "ElixxirDAppsSDK", @@ -157,6 +158,7 @@ let package = Package( name: "SessionFeature", dependencies: [ .target(name: "ErrorFeature"), + .target(name: "MyIdentityFeature"), .product( name: "ComposableArchitecture", package: "swift-composable-architecture" diff --git a/Example/example-app/Sources/AppFeature/App.swift b/Example/example-app/Sources/AppFeature/App.swift index 341cb46c..06477b12 100644 --- a/Example/example-app/Sources/AppFeature/App.swift +++ b/Example/example-app/Sources/AppFeature/App.swift @@ -3,6 +3,7 @@ import ComposableArchitecture import ElixxirDAppsSDK import ErrorFeature import LandingFeature +import MyIdentityFeature import SessionFeature import SwiftUI @@ -44,7 +45,9 @@ extension AppEnvironment { session: SessionEnvironment( getClient: { clientSubject.value }, bgScheduler: bgScheduler, - mainScheduler: mainScheduler + mainScheduler: mainScheduler, + makeId: UUID.init, + myIdentity: MyIdentityEnvironment() ) ) } diff --git a/Example/example-app/Sources/MyIdentityFeature/MyIdentityFeature.swift b/Example/example-app/Sources/MyIdentityFeature/MyIdentityFeature.swift index a9b97361..fb4c7200 100644 --- a/Example/example-app/Sources/MyIdentityFeature/MyIdentityFeature.swift +++ b/Example/example-app/Sources/MyIdentityFeature/MyIdentityFeature.swift @@ -1,7 +1,13 @@ import ComposableArchitecture public struct MyIdentityState: Equatable { - public init() {} + public init( + id: UUID + ) { + self.id = id + } + + public var id: UUID } public enum MyIdentityAction: Equatable {} diff --git a/Example/example-app/Sources/MyIdentityFeature/MyIdentityView.swift b/Example/example-app/Sources/MyIdentityFeature/MyIdentityView.swift index 4061024b..c50941b6 100644 --- a/Example/example-app/Sources/MyIdentityFeature/MyIdentityView.swift +++ b/Example/example-app/Sources/MyIdentityFeature/MyIdentityView.swift @@ -24,7 +24,7 @@ public struct MyIdentityView_Previews: PreviewProvider { public static var previews: some View { NavigationView { MyIdentityView(store: .init( - initialState: .init(), + initialState: .init(id: UUID()), reducer: .empty, environment: () )) diff --git a/Example/example-app/Sources/SessionFeature/SessionFeature.swift b/Example/example-app/Sources/SessionFeature/SessionFeature.swift index 0756f738..f3ba9326 100644 --- a/Example/example-app/Sources/SessionFeature/SessionFeature.swift +++ b/Example/example-app/Sources/SessionFeature/SessionFeature.swift @@ -2,24 +2,28 @@ import Combine import ComposableArchitecture import ElixxirDAppsSDK import ErrorFeature +import MyIdentityFeature public struct SessionState: Equatable { public init( id: UUID, networkFollowerStatus: NetworkFollowerStatus? = nil, isNetworkHealthy: Bool? = nil, - error: ErrorState? = nil + error: ErrorState? = nil, + myIdentity: MyIdentityState? = nil ) { self.id = id self.networkFollowerStatus = networkFollowerStatus self.isNetworkHealthy = isNetworkHealthy self.error = error + self.myIdentity = myIdentity } public var id: UUID public var networkFollowerStatus: NetworkFollowerStatus? public var isNetworkHealthy: Bool? public var error: ErrorState? + public var myIdentity: MyIdentityState? } public enum SessionAction: Equatable { @@ -31,23 +35,32 @@ public enum SessionAction: Equatable { case monitorNetworkHealth(Bool) case didUpdateNetworkHealth(Bool?) case didDismissError + case presentMyIdentity + case didDismissMyIdentity case error(ErrorAction) + case myIdentity(MyIdentityAction) } public struct SessionEnvironment { public init( getClient: @escaping () -> Client?, bgScheduler: AnySchedulerOf<DispatchQueue>, - mainScheduler: AnySchedulerOf<DispatchQueue> + mainScheduler: AnySchedulerOf<DispatchQueue>, + makeId: @escaping () -> UUID, + myIdentity: MyIdentityEnvironment ) { self.getClient = getClient self.bgScheduler = bgScheduler self.mainScheduler = mainScheduler + self.makeId = makeId + self.myIdentity = myIdentity } public var getClient: () -> Client? public var bgScheduler: AnySchedulerOf<DispatchQueue> public var mainScheduler: AnySchedulerOf<DispatchQueue> + public var makeId: () -> UUID + public var myIdentity: MyIdentityEnvironment } public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironment> @@ -129,17 +142,36 @@ public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironm state.error = nil return .none - case .error(_): + case .presentMyIdentity: + if state.myIdentity == nil { + state.myIdentity = MyIdentityState(id: env.makeId()) + } + return .none + + case .didDismissMyIdentity: + state.myIdentity = nil + return .none + + case .error(_), .myIdentity(_): return .none } } +.presenting( + myIdentityReducer, + state: .keyPath(\.myIdentity), + id: .keyPath(\.?.id), + action: /SessionAction.myIdentity, + environment: \.myIdentity +) #if DEBUG extension SessionEnvironment { public static let failing = SessionEnvironment( getClient: { .failing }, bgScheduler: .failing, - mainScheduler: .failing + mainScheduler: .failing, + makeId: { fatalError() }, + myIdentity: .failing ) } #endif diff --git a/Example/example-app/Sources/SessionFeature/SessionView.swift b/Example/example-app/Sources/SessionFeature/SessionView.swift index 395cfcb1..9f3c419b 100644 --- a/Example/example-app/Sources/SessionFeature/SessionView.swift +++ b/Example/example-app/Sources/SessionFeature/SessionView.swift @@ -2,6 +2,7 @@ import ComposableArchitecture import ComposablePresentation import ElixxirDAppsSDK import ErrorFeature +import MyIdentityFeature import SwiftUI public struct SessionView: View { @@ -49,6 +50,18 @@ public struct SessionView: View { } header: { Text("Network health") } + + Section { + Button { + viewStore.send(.presentMyIdentity) + } label: { + HStack { + Text("My identity") + Spacer() + Image(systemName: "chevron.forward") + } + } + } } .navigationTitle("Session") .task { @@ -64,6 +77,18 @@ public struct SessionView: View { }, content: ErrorView.init(store:) ) + .background( + NavigationLinkWithStore( + store.scope( + state: \.myIdentity, + action: SessionAction.myIdentity + ), + onDeactivate: { + viewStore.send(.didDismissMyIdentity) + }, + destination: MyIdentityView.init(store:) + ) + ) } } } diff --git a/Example/example-app/Tests/SessionFeatureTests/SessionFeatureTests.swift b/Example/example-app/Tests/SessionFeatureTests/SessionFeatureTests.swift index 2ada840d..02039168 100644 --- a/Example/example-app/Tests/SessionFeatureTests/SessionFeatureTests.swift +++ b/Example/example-app/Tests/SessionFeatureTests/SessionFeatureTests.swift @@ -1,6 +1,7 @@ import ComposableArchitecture import ElixxirDAppsSDK import ErrorFeature +import MyIdentityFeature import XCTest @testable import SessionFeature @@ -155,4 +156,25 @@ final class SessionFeatureTests: XCTestCase { $0.error = nil } } + + func testPresentingMyIdentity() { + let newId = UUID() + + var env = SessionEnvironment.failing + env.makeId = { newId } + + let store = TestStore( + initialState: SessionState(id: UUID()), + reducer: sessionReducer, + environment: env + ) + + store.send(.presentMyIdentity) { + $0.myIdentity = MyIdentityState(id: newId) + } + + store.send(.didDismissMyIdentity) { + $0.myIdentity = nil + } + } } -- GitLab