diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index 716b1482e5d2f1081a20b6e748e3707b31229b26..5e9a48c35a590e8cb106ef2a0d8510f37779b977 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -77,6 +77,7 @@ let package = Package( dependencies: [ .target(name: "AppCore"), .target(name: "CheckContactAuthFeature"), + .target(name: "ConfirmRequestFeature"), .target(name: "ContactFeature"), .target(name: "ContactsFeature"), .target(name: "HomeFeature"), @@ -137,6 +138,7 @@ let package = Package( dependencies: [ .target(name: "AppCore"), .target(name: "CheckContactAuthFeature"), + .target(name: "ConfirmRequestFeature"), .target(name: "SendRequestFeature"), .target(name: "VerifyContactFeature"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 4cbcef24b7d39adec9ec0eb32a84b88340d043d8..7adbcae89b9a90d56d2297c29f63ba4be3700367 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -1,5 +1,6 @@ import AppCore import CheckContactAuthFeature +import ConfirmRequestFeature import ContactFeature import ContactsFeature import Foundation @@ -48,6 +49,14 @@ extension AppEnvironment { bgQueue: bgQueue ) }, + confirmRequest: { + ConfirmRequestEnvironment( + messenger: messenger, + db: dbManager.getDB, + mainQueue: mainQueue, + bgQueue: bgQueue + ) + }, checkAuth: { CheckContactAuthEnvironment( messenger: messenger, diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index 8bee1b75a32a1278c79bc03fd9d97851d121e95b..545cb8fb520e9f1a99e691855c78dd1b166e98a0 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -2,6 +2,7 @@ import AppCore import CheckContactAuthFeature import ComposableArchitecture import ComposablePresentation +import ConfirmRequestFeature import Foundation import SendRequestFeature import VerifyContactFeature @@ -20,6 +21,7 @@ public struct ContactState: Equatable { importPhone: Bool = true, sendRequest: SendRequestState? = nil, verifyContact: VerifyContactState? = nil, + confirmRequest: ConfirmRequestState? = nil, checkAuth: CheckContactAuthState? = nil ) { self.id = id @@ -30,6 +32,7 @@ public struct ContactState: Equatable { self.importPhone = importPhone self.sendRequest = sendRequest self.verifyContact = verifyContact + self.confirmRequest = confirmRequest self.checkAuth = checkAuth } @@ -41,6 +44,7 @@ public struct ContactState: Equatable { @BindableState public var importPhone: Bool public var sendRequest: SendRequestState? public var verifyContact: VerifyContactState? + public var confirmRequest: ConfirmRequestState? public var checkAuth: CheckContactAuthState? } @@ -57,6 +61,9 @@ public enum ContactAction: Equatable, BindableAction { case checkAuthTapped case checkAuthDismissed case checkAuth(CheckContactAuthAction) + case confirmRequestTapped + case confirmRequestDismissed + case confirmRequest(ConfirmRequestAction) case binding(BindingAction<ContactState>) } @@ -68,6 +75,7 @@ public struct ContactEnvironment { bgQueue: AnySchedulerOf<DispatchQueue>, sendRequest: @escaping () -> SendRequestEnvironment, verifyContact: @escaping () -> VerifyContactEnvironment, + confirmRequest: @escaping () -> ConfirmRequestEnvironment, checkAuth: @escaping () -> CheckContactAuthEnvironment ) { self.messenger = messenger @@ -76,6 +84,7 @@ public struct ContactEnvironment { self.bgQueue = bgQueue self.sendRequest = sendRequest self.verifyContact = verifyContact + self.confirmRequest = confirmRequest self.checkAuth = checkAuth } @@ -85,6 +94,7 @@ public struct ContactEnvironment { public var bgQueue: AnySchedulerOf<DispatchQueue> public var sendRequest: () -> SendRequestEnvironment public var verifyContact: () -> VerifyContactEnvironment + public var confirmRequest: () -> ConfirmRequestEnvironment public var checkAuth: () -> CheckContactAuthEnvironment } @@ -97,6 +107,7 @@ extension ContactEnvironment { bgQueue: .unimplemented, sendRequest: { .unimplemented }, verifyContact: { .unimplemented }, + confirmRequest: { .unimplemented }, checkAuth: { .unimplemented } ) } @@ -181,7 +192,19 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm state.checkAuth = nil return .none - case .binding(_), .sendRequest(_), .verifyContact(_), .checkAuth(_): + case .confirmRequestTapped: + if let marshaled = state.dbContact?.marshaled { + state.confirmRequest = ConfirmRequestState( + contact: .live(marshaled) + ) + } + return .none + + case .confirmRequestDismissed: + state.confirmRequest = nil + return .none + + case .binding(_), .sendRequest(_), .verifyContact(_), .confirmRequest(_), .checkAuth(_): return .none } } @@ -200,6 +223,13 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm action: /ContactAction.verifyContact, environment: { $0.verifyContact() } ) +.presenting( + confirmRequestReducer, + state: .keyPath(\.confirmRequest), + id: .notNil(), + action: /ContactAction.confirmRequest, + environment: { $0.confirmRequest() } +) .presenting( checkContactAuthReducer, state: .keyPath(\.checkAuth), diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index 079428412cae39abb46f66951b2d59efeddf9642..08ae7eb8863b95bc9e5b3d0ef8e7f529b2f8b39e 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -2,6 +2,7 @@ import AppCore import CheckContactAuthFeature import ComposableArchitecture import ComposablePresentation +import ConfirmRequestFeature import SendRequestFeature import SwiftUI import VerifyContactFeature @@ -125,6 +126,15 @@ public struct ContactView: View { Image(systemName: "chevron.forward") } } + Button { + viewStore.send(.confirmRequestTapped) + } label: { + HStack { + Text("Confirm request") + Spacer() + Image(systemName: "chevron.forward") + } + } Button { viewStore.send(.checkAuthTapped) } label: { @@ -159,6 +169,14 @@ public struct ContactView: View { onDeactivate: { viewStore.send(.verifyContactDismissed) }, destination: VerifyContactView.init(store:) )) + .background(NavigationLinkWithStore( + store.scope( + state: \.confirmRequest, + action: ContactAction.confirmRequest + ), + onDeactivate: { viewStore.send(.confirmRequestDismissed) }, + destination: ConfirmRequestView.init(store:) + )) .background(NavigationLinkWithStore( store.scope( state: \.checkAuth, diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index 250d802c9c7360aea613ab8a0195eae8f0ab98c0..afc146b1981cf07e5c0105da1c6022f51c56aef4 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -1,6 +1,7 @@ import CheckContactAuthFeature import Combine import ComposableArchitecture +import ConfirmRequestFeature import CustomDump import SendRequestFeature import VerifyContactFeature @@ -241,4 +242,42 @@ final class ContactFeatureTests: XCTestCase { $0.checkAuth = nil } } + + func testConfirmRequestTapped() { + let contactData = "contact-data".data(using: .utf8)! + let store = TestStore( + initialState: ContactState( + id: Data(), + dbContact: XXModels.Contact( + id: Data(), + marshaled: contactData + ) + ), + reducer: contactReducer, + environment: .unimplemented + ) + + store.send(.confirmRequestTapped) { + $0.confirmRequest = ConfirmRequestState( + contact: .unimplemented(contactData) + ) + } + } + + func testConfirmRequestDismissed() { + let store = TestStore( + initialState: ContactState( + id: "contact-id".data(using: .utf8)!, + confirmRequest: ConfirmRequestState( + contact: .unimplemented("contact-data".data(using: .utf8)!) + ) + ), + reducer: contactReducer, + environment: .unimplemented + ) + + store.send(.confirmRequestDismissed) { + $0.confirmRequest = nil + } + } }