From b29d338e0fdf0b1bf2f152d09e9cf5ec9dc45b8f Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 8 Jun 2022 14:15:48 +0200 Subject: [PATCH] Present MyContactView from SessionView --- Example/example-app/Package.swift | 2 ++ .../example-app/Sources/AppFeature/App.swift | 4 ++- .../SessionFeature/SessionFeature.swift | 36 ++++++++++++++++--- .../Sources/SessionFeature/SessionView.swift | 23 ++++++++++++ .../SessionFeatureTests.swift | 22 ++++++++++++ 5 files changed, 82 insertions(+), 5 deletions(-) diff --git a/Example/example-app/Package.swift b/Example/example-app/Package.swift index d7a464f9..faa8a155 100644 --- a/Example/example-app/Package.swift +++ b/Example/example-app/Package.swift @@ -66,6 +66,7 @@ let package = Package( dependencies: [ .target(name: "ErrorFeature"), .target(name: "LandingFeature"), + .target(name: "MyContactFeature"), .target(name: "MyIdentityFeature"), .target(name: "SessionFeature"), .product( @@ -188,6 +189,7 @@ let package = Package( name: "SessionFeature", dependencies: [ .target(name: "ErrorFeature"), + .target(name: "MyContactFeature"), .target(name: "MyIdentityFeature"), .product( name: "ComposableArchitecture", diff --git a/Example/example-app/Sources/AppFeature/App.swift b/Example/example-app/Sources/AppFeature/App.swift index a8b27266..b106e28a 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 MyContactFeature import MyIdentityFeature import SessionFeature import SwiftUI @@ -56,7 +57,8 @@ extension AppEnvironment { bgScheduler: bgScheduler, mainScheduler: mainScheduler, error: ErrorEnvironment() - ) + ), + myContact: MyContactEnvironment() ) ) } diff --git a/Example/example-app/Sources/SessionFeature/SessionFeature.swift b/Example/example-app/Sources/SessionFeature/SessionFeature.swift index ae1afd73..5b1005a9 100644 --- a/Example/example-app/Sources/SessionFeature/SessionFeature.swift +++ b/Example/example-app/Sources/SessionFeature/SessionFeature.swift @@ -2,6 +2,7 @@ import Combine import ComposableArchitecture import ElixxirDAppsSDK import ErrorFeature +import MyContactFeature import MyIdentityFeature public struct SessionState: Equatable { @@ -10,13 +11,15 @@ public struct SessionState: Equatable { networkFollowerStatus: NetworkFollowerStatus? = nil, isNetworkHealthy: Bool? = nil, error: ErrorState? = nil, - myIdentity: MyIdentityState? = nil + myIdentity: MyIdentityState? = nil, + myContact: MyContactState? = nil ) { self.id = id self.networkFollowerStatus = networkFollowerStatus self.isNetworkHealthy = isNetworkHealthy self.error = error self.myIdentity = myIdentity + self.myContact = myContact } public var id: UUID @@ -24,6 +27,7 @@ public struct SessionState: Equatable { public var isNetworkHealthy: Bool? public var error: ErrorState? public var myIdentity: MyIdentityState? + public var myContact: MyContactState? } public enum SessionAction: Equatable { @@ -37,8 +41,11 @@ public enum SessionAction: Equatable { case didDismissError case presentMyIdentity case didDismissMyIdentity + case presentMyContact + case didDismissMyContact case error(ErrorAction) case myIdentity(MyIdentityAction) + case myContact(MyContactAction) } public struct SessionEnvironment { @@ -48,7 +55,8 @@ public struct SessionEnvironment { mainScheduler: AnySchedulerOf<DispatchQueue>, makeId: @escaping () -> UUID, error: ErrorEnvironment, - myIdentity: MyIdentityEnvironment + myIdentity: MyIdentityEnvironment, + myContact: MyContactEnvironment ) { self.getClient = getClient self.bgScheduler = bgScheduler @@ -56,6 +64,7 @@ public struct SessionEnvironment { self.makeId = makeId self.error = error self.myIdentity = myIdentity + self.myContact = myContact } public var getClient: () -> Client? @@ -64,6 +73,7 @@ public struct SessionEnvironment { public var makeId: () -> UUID public var error: ErrorEnvironment public var myIdentity: MyIdentityEnvironment + public var myContact: MyContactEnvironment } public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironment> @@ -155,7 +165,17 @@ public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironm state.myIdentity = nil return .none - case .error(_), .myIdentity(_): + case .presentMyContact: + if state.myContact == nil { + state.myContact = MyContactState(id: env.makeId()) + } + return .none + + case .didDismissMyContact: + state.myContact = nil + return .none + + case .error(_), .myIdentity(_), .myContact(_): return .none } } @@ -173,6 +193,13 @@ public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironm action: /SessionAction.myIdentity, environment: \.myIdentity ) +.presenting( + myContactReducer, + state: .keyPath(\.myContact), + id: .keyPath(\.?.id), + action: /SessionAction.myContact, + environment: \.myContact +) #if DEBUG extension SessionEnvironment { @@ -182,7 +209,8 @@ extension SessionEnvironment { mainScheduler: .failing, makeId: { fatalError() }, error: .failing, - myIdentity: .failing + myIdentity: .failing, + myContact: .failing ) } #endif diff --git a/Example/example-app/Sources/SessionFeature/SessionView.swift b/Example/example-app/Sources/SessionFeature/SessionView.swift index 9f3c419b..ea14d91f 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 MyContactFeature import MyIdentityFeature import SwiftUI @@ -61,6 +62,16 @@ public struct SessionView: View { Image(systemName: "chevron.forward") } } + + Button { + viewStore.send(.presentMyContact) + } label: { + HStack { + Text("My contact") + Spacer() + Image(systemName: "chevron.forward") + } + } } } .navigationTitle("Session") @@ -89,6 +100,18 @@ public struct SessionView: View { destination: MyIdentityView.init(store:) ) ) + .background( + NavigationLinkWithStore( + store.scope( + state: \.myContact, + action: SessionAction.myContact + ), + onDeactivate: { + viewStore.send(.didDismissMyContact) + }, + destination: MyContactView.init(store:) + ) + ) } } } diff --git a/Example/example-app/Tests/SessionFeatureTests/SessionFeatureTests.swift b/Example/example-app/Tests/SessionFeatureTests/SessionFeatureTests.swift index 02039168..5c1aa3ba 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 MyContactFeature import MyIdentityFeature import XCTest @testable import SessionFeature @@ -177,4 +178,25 @@ final class SessionFeatureTests: XCTestCase { $0.myIdentity = nil } } + + func testPresentingMyContact() { + let newId = UUID() + + var env = SessionEnvironment.failing + env.makeId = { newId } + + let store = TestStore( + initialState: SessionState(id: UUID()), + reducer: sessionReducer, + environment: env + ) + + store.send(.presentMyContact) { + $0.myContact = MyContactState(id: newId) + } + + store.send(.didDismissMyContact) { + $0.myContact = nil + } + } } -- GitLab