diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index 8c7a1c90beeef33b8af3e6fe67b82fc92935ccca..3951efb54d0a9dbad1b6b975850bb97c39516589 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -81,6 +81,7 @@ let package = Package( .target(name: "RestoreFeature"), .target(name: "SendRequestFeature"), .target(name: "UserSearchFeature"), + .target(name: "VerifyContactFeature"), .target(name: "WelcomeFeature"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), .product(name: "ComposablePresentation", package: "swift-composable-presentation"), @@ -101,6 +102,7 @@ let package = Package( dependencies: [ .target(name: "AppCore"), .target(name: "SendRequestFeature"), + .target(name: "VerifyContactFeature"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), .product(name: "ComposablePresentation", package: "swift-composable-presentation"), .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), @@ -228,6 +230,7 @@ let package = Package( name: "VerifyContactFeature", dependencies: [ .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), + .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), ] ), .testTarget( diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 5267fcc3f1a42445702386278b8fbeeb600785ae..beb0730000cf3567195ec9fbb8f76ff143b20dc1 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -7,6 +7,7 @@ import RegisterFeature import RestoreFeature import SendRequestFeature import UserSearchFeature +import VerifyContactFeature import WelcomeFeature import XXMessengerClient import XXModels @@ -41,6 +42,9 @@ extension AppEnvironment { mainQueue: mainQueue, bgQueue: bgQueue ) + }, + verifyContact: { + VerifyContactEnvironment() } ) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index 9f6ef294f5a8b35bdc7e7d0300ce05fd84ae1823..9d7a03d86c71b5e24c6c3b9bcbe965c04c102a4c 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -3,6 +3,7 @@ import ComposableArchitecture import ComposablePresentation import Foundation import SendRequestFeature +import VerifyContactFeature import XCTestDynamicOverlay import XXClient import XXMessengerClient @@ -16,7 +17,8 @@ public struct ContactState: Equatable { importUsername: Bool = true, importEmail: Bool = true, importPhone: Bool = true, - sendRequest: SendRequestState? = nil + sendRequest: SendRequestState? = nil, + verifyContact: VerifyContactState? = nil ) { self.id = id self.dbContact = dbContact @@ -25,6 +27,7 @@ public struct ContactState: Equatable { self.importEmail = importEmail self.importPhone = importPhone self.sendRequest = sendRequest + self.verifyContact = verifyContact } public var id: Data @@ -34,6 +37,7 @@ public struct ContactState: Equatable { @BindableState public var importEmail: Bool @BindableState public var importPhone: Bool public var sendRequest: SendRequestState? + public var verifyContact: VerifyContactState? } public enum ContactAction: Equatable, BindableAction { @@ -43,6 +47,9 @@ public enum ContactAction: Equatable, BindableAction { case sendRequestTapped case sendRequestDismissed case sendRequest(SendRequestAction) + case verifyContactTapped + case verifyContactDismissed + case verifyContact(VerifyContactAction) case binding(BindingAction<ContactState>) } @@ -52,13 +59,15 @@ public struct ContactEnvironment { db: DBManagerGetDB, mainQueue: AnySchedulerOf<DispatchQueue>, bgQueue: AnySchedulerOf<DispatchQueue>, - sendRequest: @escaping () -> SendRequestEnvironment + sendRequest: @escaping () -> SendRequestEnvironment, + verifyContact: @escaping () -> VerifyContactEnvironment ) { self.messenger = messenger self.db = db self.mainQueue = mainQueue self.bgQueue = bgQueue self.sendRequest = sendRequest + self.verifyContact = verifyContact } public var messenger: Messenger @@ -66,6 +75,7 @@ public struct ContactEnvironment { public var mainQueue: AnySchedulerOf<DispatchQueue> public var bgQueue: AnySchedulerOf<DispatchQueue> public var sendRequest: () -> SendRequestEnvironment + public var verifyContact: () -> VerifyContactEnvironment } #if DEBUG @@ -75,7 +85,8 @@ extension ContactEnvironment { db: .unimplemented, mainQueue: .unimplemented, bgQueue: .unimplemented, - sendRequest: { .unimplemented } + sendRequest: { .unimplemented }, + verifyContact: { .unimplemented } ) } #endif @@ -135,10 +146,19 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm state.sendRequest = nil return .none - case .sendRequest(_): + case .verifyContactTapped: + if let marshaled = state.dbContact?.marshaled { + state.verifyContact = VerifyContactState( + xxContact: .live(marshaled) + ) + } + return .none + + case .verifyContactDismissed: + state.verifyContact = nil return .none - case .binding(_): + case .binding(_), .sendRequest(_), .verifyContact(_): return .none } } @@ -150,3 +170,10 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm action: /ContactAction.sendRequest, environment: { $0.sendRequest() } ) +.presenting( + verifyContactReducer, + state: .keyPath(\.verifyContact), + id: .notNil(), + action: /ContactAction.verifyContact, + environment: { $0.verifyContact() } +) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index 1cd8fa2eda4f9058cd8ed333f15e15f7588cd2dc..86202f158efc725096e8b2c7ffcedcc223dc8acb 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -3,6 +3,7 @@ import ComposableArchitecture import ComposablePresentation import SendRequestFeature import SwiftUI +import VerifyContactFeature import XXClient import XXModels @@ -114,6 +115,15 @@ public struct ContactView: View { Image(systemName: "chevron.forward") } } + Button { + viewStore.send(.verifyContactTapped) + } label: { + HStack { + Text("Verify contact") + Spacer() + Image(systemName: "chevron.forward") + } + } } header: { Text("Auth") } @@ -131,6 +141,14 @@ public struct ContactView: View { onDeactivate: { viewStore.send(.sendRequestDismissed) }, destination: SendRequestView.init(store:) )) + .background(NavigationLinkWithStore( + store.scope( + state: \.verifyContact, + action: ContactAction.verifyContact + ), + onDeactivate: { viewStore.send(.verifyContactDismissed) }, + destination: VerifyContactView.init(store:) + )) } } } diff --git a/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactFeature.swift b/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactFeature.swift index c657dd72d846af36a14979b8f3e89940889bd155..a64c43c4dbb1e0cb97a2fdef8a0d9776b1e80823 100644 --- a/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactFeature.swift +++ b/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactFeature.swift @@ -1,8 +1,15 @@ import ComposableArchitecture import XCTestDynamicOverlay +import XXClient public struct VerifyContactState: Equatable { - public init() {} + public init( + xxContact: XXClient.Contact + ) { + self.xxContact = xxContact + } + + public var xxContact: XXClient.Contact } public enum VerifyContactAction: Equatable { diff --git a/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactView.swift b/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactView.swift index ff2d76b2907c154df30f8008b6495057e60b5c3b..fff1ad51f53b1a238295c1f323035dcb42ec6ab7 100644 --- a/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactView.swift +++ b/Examples/xx-messenger/Sources/VerifyContactFeature/VerifyContactView.swift @@ -27,7 +27,9 @@ public struct VerifyContactView: View { public struct VerifyContactView_Previews: PreviewProvider { public static var previews: some View { VerifyContactView(store: Store( - initialState: VerifyContactState(), + initialState: VerifyContactState( + xxContact: .unimplemented("contact-data".data(using: .utf8)!) + ), reducer: .empty, environment: () )) diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index 247abb49e226acd5ea720d8a7cd8265f6ca197ef..260ed2790e6387c2c3bfbdfd466483ca33816afc 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -2,6 +2,7 @@ import Combine import ComposableArchitecture import CustomDump import SendRequestFeature +import VerifyContactFeature import XCTest import XXClient import XXModels @@ -163,4 +164,42 @@ final class ContactFeatureTests: XCTestCase { $0.sendRequest = nil } } + + func testVerifyContactTapped() { + 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(.verifyContactTapped) { + $0.verifyContact = VerifyContactState( + xxContact: .live(contactData) + ) + } + } + + func testVerifyContactDismissed() { + let store = TestStore( + initialState: ContactState( + id: "contact-id".data(using: .utf8)!, + verifyContact: VerifyContactState( + xxContact: .unimplemented("contact-data".data(using: .utf8)!) + ) + ), + reducer: contactReducer, + environment: .unimplemented + ) + + store.send(.verifyContactDismissed) { + $0.verifyContact = nil + } + } } diff --git a/Examples/xx-messenger/Tests/VerifyContactFeatureTests/VerifyContactFeatureTests.swift b/Examples/xx-messenger/Tests/VerifyContactFeatureTests/VerifyContactFeatureTests.swift index b0f41108a6536a602aea93b83bad20e9de1a5fe0..212b3d0a9d047841a01a40b26e2bf1ced5d6287b 100644 --- a/Examples/xx-messenger/Tests/VerifyContactFeatureTests/VerifyContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/VerifyContactFeatureTests/VerifyContactFeatureTests.swift @@ -5,7 +5,9 @@ import XCTest final class VerifyContactFeatureTests: XCTestCase { func testStart() { let store = TestStore( - initialState: VerifyContactState(), + initialState: VerifyContactState( + xxContact: .unimplemented("contact-data".data(using: .utf8)!) + ), reducer: verifyContactReducer, environment: .unimplemented )