From 7ba09aa7456dde371df389f0fd3dd255e7ac7916 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Tue, 13 Sep 2022 23:03:58 +0200 Subject: [PATCH] Present Chat from Contact --- Examples/xx-messenger/Package.swift | 2 ++ .../AppFeature/AppEnvironment+Live.swift | 4 +++ .../ContactFeature/ContactFeature.swift | 34 ++++++++++++++++--- .../Sources/ContactFeature/ContactView.swift | 23 +++++++++++++ .../ContactFeatureTests.swift | 31 +++++++++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index 30f5cd4e..2d5fbb9f 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -77,6 +77,7 @@ let package = Package( name: "AppFeature", dependencies: [ .target(name: "AppCore"), + .target(name: "ChatFeature"), .target(name: "CheckContactAuthFeature"), .target(name: "ConfirmRequestFeature"), .target(name: "ContactFeature"), @@ -152,6 +153,7 @@ let package = Package( name: "ContactFeature", dependencies: [ .target(name: "AppCore"), + .target(name: "ChatFeature"), .target(name: "CheckContactAuthFeature"), .target(name: "ConfirmRequestFeature"), .target(name: "SendRequestFeature"), diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 7adbcae8..9050fb3e 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -1,4 +1,5 @@ import AppCore +import ChatFeature import CheckContactAuthFeature import ConfirmRequestFeature import ContactFeature @@ -64,6 +65,9 @@ extension AppEnvironment { mainQueue: mainQueue, bgQueue: bgQueue ) + }, + chat: { + ChatEnvironment() } ) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index 545cb8fb..993796e4 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -1,4 +1,5 @@ import AppCore +import ChatFeature import CheckContactAuthFeature import ComposableArchitecture import ComposablePresentation @@ -22,7 +23,8 @@ public struct ContactState: Equatable { sendRequest: SendRequestState? = nil, verifyContact: VerifyContactState? = nil, confirmRequest: ConfirmRequestState? = nil, - checkAuth: CheckContactAuthState? = nil + checkAuth: CheckContactAuthState? = nil, + chat: ChatState? = nil ) { self.id = id self.dbContact = dbContact @@ -34,6 +36,7 @@ public struct ContactState: Equatable { self.verifyContact = verifyContact self.confirmRequest = confirmRequest self.checkAuth = checkAuth + self.chat = chat } public var id: Data @@ -46,6 +49,7 @@ public struct ContactState: Equatable { public var verifyContact: VerifyContactState? public var confirmRequest: ConfirmRequestState? public var checkAuth: CheckContactAuthState? + public var chat: ChatState? } public enum ContactAction: Equatable, BindableAction { @@ -64,6 +68,9 @@ public enum ContactAction: Equatable, BindableAction { case confirmRequestTapped case confirmRequestDismissed case confirmRequest(ConfirmRequestAction) + case chatTapped + case chatDismissed + case chat(ChatAction) case binding(BindingAction<ContactState>) } @@ -76,7 +83,8 @@ public struct ContactEnvironment { sendRequest: @escaping () -> SendRequestEnvironment, verifyContact: @escaping () -> VerifyContactEnvironment, confirmRequest: @escaping () -> ConfirmRequestEnvironment, - checkAuth: @escaping () -> CheckContactAuthEnvironment + checkAuth: @escaping () -> CheckContactAuthEnvironment, + chat: @escaping () -> ChatEnvironment ) { self.messenger = messenger self.db = db @@ -86,6 +94,7 @@ public struct ContactEnvironment { self.verifyContact = verifyContact self.confirmRequest = confirmRequest self.checkAuth = checkAuth + self.chat = chat } public var messenger: Messenger @@ -96,6 +105,7 @@ public struct ContactEnvironment { public var verifyContact: () -> VerifyContactEnvironment public var confirmRequest: () -> ConfirmRequestEnvironment public var checkAuth: () -> CheckContactAuthEnvironment + public var chat: () -> ChatEnvironment } #if DEBUG @@ -108,7 +118,8 @@ extension ContactEnvironment { sendRequest: { .unimplemented }, verifyContact: { .unimplemented }, confirmRequest: { .unimplemented }, - checkAuth: { .unimplemented } + checkAuth: { .unimplemented }, + chat: { .unimplemented } ) } #endif @@ -204,7 +215,15 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm state.confirmRequest = nil return .none - case .binding(_), .sendRequest(_), .verifyContact(_), .confirmRequest(_), .checkAuth(_): + case .chatTapped: + state.chat = ChatState(id: .contact(state.id)) + return .none + + case .chatDismissed: + state.chat = nil + return .none + + case .binding(_), .sendRequest(_), .verifyContact(_), .confirmRequest(_), .checkAuth(_), .chat(_): return .none } } @@ -237,3 +256,10 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm action: /ContactAction.checkAuth, environment: { $0.checkAuth() } ) +.presenting( + chatReducer, + state: .keyPath(\.chat), + id: .keyPath(\.?.id), + action: /ContactAction.chat, + environment: { $0.chat() } +) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index 08ae7eb8..d775df01 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -1,4 +1,5 @@ import AppCore +import ChatFeature import CheckContactAuthFeature import ComposableArchitecture import ComposablePresentation @@ -148,6 +149,20 @@ public struct ContactView: View { Text("Auth") } .animation(.default, value: viewStore.dbContact?.authStatus) + + Section { + Button { + viewStore.send(.chatTapped) + } label: { + HStack { + Text("Chat") + Spacer() + Image(systemName: "chevron.forward") + } + } + } header: { + Text("Chat") + } } } .navigationTitle("Contact") @@ -185,6 +200,14 @@ public struct ContactView: View { onDeactivate: { viewStore.send(.checkAuthDismissed) }, destination: CheckContactAuthView.init(store:) )) + .background(NavigationLinkWithStore( + store.scope( + state: \.chat, + action: ContactAction.chat + ), + onDeactivate: { viewStore.send(.chatDismissed) }, + destination: ChatView.init(store:) + )) } } } diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index afc146b1..11bfe8a7 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -1,3 +1,4 @@ +import ChatFeature import CheckContactAuthFeature import Combine import ComposableArchitecture @@ -280,4 +281,34 @@ final class ContactFeatureTests: XCTestCase { $0.confirmRequest = nil } } + + func testChatTapped() { + let contactId = "contact-id".data(using: .utf8)! + let store = TestStore( + initialState: ContactState( + id: contactId + ), + reducer: contactReducer, + environment: .unimplemented + ) + + store.send(.chatTapped) { + $0.chat = ChatState(id: .contact(contactId)) + } + } + + func testChatDismissed() { + let store = TestStore( + initialState: ContactState( + id: "contact-id".data(using: .utf8)!, + chat: ChatState(id: .contact("contact-id".data(using: .utf8)!)) + ), + reducer: contactReducer, + environment: .unimplemented + ) + + store.send(.chatDismissed) { + $0.chat = nil + } + } } -- GitLab