diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index 01878fbd634c1e36d0be0f56b53331ba7b8b0d71..c2da9978d6ac07644d78a4161d741f5e22e85929 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -75,6 +75,7 @@ let package = Package( name: "AppFeature", dependencies: [ .target(name: "AppCore"), + .target(name: "CheckContactAuthFeature"), .target(name: "ContactFeature"), .target(name: "ContactsFeature"), .target(name: "HomeFeature"), @@ -117,6 +118,7 @@ let package = Package( name: "ContactFeature", dependencies: [ .target(name: "AppCore"), + .target(name: "CheckContactAuthFeature"), .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 ad9218250dfe2f9d2e8464da32a1c015948ed35d..ae1da8b967a2db31994c641acea8b310dba25d6a 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 CheckContactAuthFeature import ContactFeature import ContactsFeature import Foundation @@ -49,6 +50,13 @@ extension AppEnvironment { mainQueue: mainQueue, bgQueue: bgQueue ) + }, + checkAuth: { + CheckContactAuthEnvironment( + messenger: messenger, + mainQueue: mainQueue, + bgQueue: bgQueue + ) } ) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index 15f32bed5e442d9ec305f3e842607bfe8786cdf2..8bee1b75a32a1278c79bc03fd9d97851d121e95b 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -1,4 +1,5 @@ import AppCore +import CheckContactAuthFeature import ComposableArchitecture import ComposablePresentation import Foundation @@ -18,7 +19,8 @@ public struct ContactState: Equatable { importEmail: Bool = true, importPhone: Bool = true, sendRequest: SendRequestState? = nil, - verifyContact: VerifyContactState? = nil + verifyContact: VerifyContactState? = nil, + checkAuth: CheckContactAuthState? = nil ) { self.id = id self.dbContact = dbContact @@ -28,6 +30,7 @@ public struct ContactState: Equatable { self.importPhone = importPhone self.sendRequest = sendRequest self.verifyContact = verifyContact + self.checkAuth = checkAuth } public var id: Data @@ -38,6 +41,7 @@ public struct ContactState: Equatable { @BindableState public var importPhone: Bool public var sendRequest: SendRequestState? public var verifyContact: VerifyContactState? + public var checkAuth: CheckContactAuthState? } public enum ContactAction: Equatable, BindableAction { @@ -50,6 +54,9 @@ public enum ContactAction: Equatable, BindableAction { case verifyContactTapped case verifyContactDismissed case verifyContact(VerifyContactAction) + case checkAuthTapped + case checkAuthDismissed + case checkAuth(CheckContactAuthAction) case binding(BindingAction<ContactState>) } @@ -60,7 +67,8 @@ public struct ContactEnvironment { mainQueue: AnySchedulerOf<DispatchQueue>, bgQueue: AnySchedulerOf<DispatchQueue>, sendRequest: @escaping () -> SendRequestEnvironment, - verifyContact: @escaping () -> VerifyContactEnvironment + verifyContact: @escaping () -> VerifyContactEnvironment, + checkAuth: @escaping () -> CheckContactAuthEnvironment ) { self.messenger = messenger self.db = db @@ -68,6 +76,7 @@ public struct ContactEnvironment { self.bgQueue = bgQueue self.sendRequest = sendRequest self.verifyContact = verifyContact + self.checkAuth = checkAuth } public var messenger: Messenger @@ -76,6 +85,7 @@ public struct ContactEnvironment { public var bgQueue: AnySchedulerOf<DispatchQueue> public var sendRequest: () -> SendRequestEnvironment public var verifyContact: () -> VerifyContactEnvironment + public var checkAuth: () -> CheckContactAuthEnvironment } #if DEBUG @@ -86,7 +96,8 @@ extension ContactEnvironment { mainQueue: .unimplemented, bgQueue: .unimplemented, sendRequest: { .unimplemented }, - verifyContact: { .unimplemented } + verifyContact: { .unimplemented }, + checkAuth: { .unimplemented } ) } #endif @@ -158,7 +169,19 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm state.verifyContact = nil return .none - case .binding(_), .sendRequest(_), .verifyContact(_): + case .checkAuthTapped: + if let marshaled = state.dbContact?.marshaled { + state.checkAuth = CheckContactAuthState( + contact: .live(marshaled) + ) + } + return .none + + case .checkAuthDismissed: + state.checkAuth = nil + return .none + + case .binding(_), .sendRequest(_), .verifyContact(_), .checkAuth(_): return .none } } @@ -177,3 +200,10 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm action: /ContactAction.verifyContact, environment: { $0.verifyContact() } ) +.presenting( + checkContactAuthReducer, + state: .keyPath(\.checkAuth), + id: .notNil(), + action: /ContactAction.checkAuth, + environment: { $0.checkAuth() } +) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index 86202f158efc725096e8b2c7ffcedcc223dc8acb..079428412cae39abb46f66951b2d59efeddf9642 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -1,4 +1,5 @@ import AppCore +import CheckContactAuthFeature import ComposableArchitecture import ComposablePresentation import SendRequestFeature @@ -124,6 +125,15 @@ public struct ContactView: View { Image(systemName: "chevron.forward") } } + Button { + viewStore.send(.checkAuthTapped) + } label: { + HStack { + Text("Check authorization") + Spacer() + Image(systemName: "chevron.forward") + } + } } header: { Text("Auth") } @@ -149,6 +159,14 @@ public struct ContactView: View { onDeactivate: { viewStore.send(.verifyContactDismissed) }, destination: VerifyContactView.init(store:) )) + .background(NavigationLinkWithStore( + store.scope( + state: \.checkAuth, + action: ContactAction.checkAuth + ), + onDeactivate: { viewStore.send(.checkAuthDismissed) }, + destination: CheckContactAuthView.init(store:) + )) } } } diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index 9a24cab9517dddb2f9f2df66548e80da438fdbd4..250d802c9c7360aea613ab8a0195eae8f0ab98c0 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -1,3 +1,4 @@ +import CheckContactAuthFeature import Combine import ComposableArchitecture import CustomDump @@ -202,4 +203,42 @@ final class ContactFeatureTests: XCTestCase { $0.verifyContact = nil } } + + func testCheckAuthTapped() { + 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(.checkAuthTapped) { + $0.checkAuth = CheckContactAuthState( + contact: .unimplemented(contactData) + ) + } + } + + func testCheckAuthDismissed() { + let store = TestStore( + initialState: ContactState( + id: "contact-id".data(using: .utf8)!, + checkAuth: CheckContactAuthState( + contact: .unimplemented("contact-data".data(using: .utf8)!) + ) + ), + reducer: contactReducer, + environment: .unimplemented + ) + + store.send(.checkAuthDismissed) { + $0.checkAuth = nil + } + } }