From b2b508d289d05d78eeb756ec3dc700f3b9626edd Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 7 Sep 2022 13:26:26 +0200 Subject: [PATCH] Add Send Request screen --- Examples/xx-messenger/Package.swift | 1 + .../AppFeature/AppEnvironment+Live.swift | 5 ++- .../ContactFeature/ContactFeature.swift | 31 ++++++++++++++-- .../ContactSendRequestFeature.swift | 28 +++++++++++++++ .../ContactSendRequestView.swift | 36 +++++++++++++++++++ .../Sources/ContactFeature/ContactView.swift | 9 +++++ .../ContactFeatureTests.swift | 8 ++++- .../ContactSendRequestFeatureTests.swift | 15 ++++++++ 8 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestFeature.swift create mode 100644 Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestView.swift create mode 100644 Examples/xx-messenger/Tests/ContactFeatureTests/ContactSendRequestFeatureTests.swift diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index e991313f..79123e05 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -95,6 +95,7 @@ let package = Package( dependencies: [ .target(name: "AppCore"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), + .product(name: "ComposablePresentation", package: "swift-composable-presentation"), .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), .product(name: "XXModels", package: "client-ios-db"), ], diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 8e3f48dc..514f56bd 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -60,7 +60,10 @@ extension AppEnvironment { messenger: messenger, db: dbManager.getDB, mainQueue: mainQueue, - bgQueue: bgQueue + bgQueue: bgQueue, + sendRequest: { + ContactSendRequestEnvironment() + } ) } ) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index 7bbb5f3c..76715592 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -1,5 +1,6 @@ import AppCore import ComposableArchitecture +import ComposablePresentation import Foundation import XCTestDynamicOverlay import XXClient @@ -10,16 +11,19 @@ public struct ContactState: Equatable { public init( id: Data, dbContact: XXModels.Contact? = nil, - xxContact: XXClient.Contact? = nil + xxContact: XXClient.Contact? = nil, + sendRequest: ContactSendRequestState? = nil ) { self.id = id self.dbContact = dbContact self.xxContact = xxContact + self.sendRequest = sendRequest } public var id: Data public var dbContact: XXModels.Contact? public var xxContact: XXClient.Contact? + public var sendRequest: ContactSendRequestState? } public enum ContactAction: Equatable { @@ -27,6 +31,8 @@ public enum ContactAction: Equatable { case dbContactFetched(XXModels.Contact?) case saveFactsTapped case sendRequestTapped + case sendRequestDismissed + case sendRequest(ContactSendRequestAction) } public struct ContactEnvironment { @@ -34,18 +40,21 @@ public struct ContactEnvironment { messenger: Messenger, db: DBManagerGetDB, mainQueue: AnySchedulerOf<DispatchQueue>, - bgQueue: AnySchedulerOf<DispatchQueue> + bgQueue: AnySchedulerOf<DispatchQueue>, + sendRequest: @escaping () -> ContactSendRequestEnvironment ) { self.messenger = messenger self.db = db self.mainQueue = mainQueue self.bgQueue = bgQueue + self.sendRequest = sendRequest } public var messenger: Messenger public var db: DBManagerGetDB public var mainQueue: AnySchedulerOf<DispatchQueue> public var bgQueue: AnySchedulerOf<DispatchQueue> + public var sendRequest: () -> ContactSendRequestEnvironment } #if DEBUG @@ -54,7 +63,8 @@ extension ContactEnvironment { messenger: .unimplemented, db: .unimplemented, mainQueue: .unimplemented, - bgQueue: .unimplemented + bgQueue: .unimplemented, + sendRequest: { .unimplemented } ) } #endif @@ -93,6 +103,21 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm .eraseToEffect() case .sendRequestTapped: + state.sendRequest = ContactSendRequestState() + return .none + + case .sendRequestDismissed: + state.sendRequest = nil + return .none + + case .sendRequest(_): return .none } } +.presenting( + contactSendRequestReducer, + state: .keyPath(\.sendRequest), + id: .notNil(), + action: /ContactAction.sendRequest, + environment: { $0.sendRequest() } +) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestFeature.swift new file mode 100644 index 00000000..a0a474e5 --- /dev/null +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestFeature.swift @@ -0,0 +1,28 @@ +import ComposableArchitecture +import XCTestDynamicOverlay + +public struct ContactSendRequestState: Equatable { + public init() {} +} + +public enum ContactSendRequestAction: Equatable { + case start +} + +public struct ContactSendRequestEnvironment { + public init() {} +} + +#if DEBUG +extension ContactSendRequestEnvironment { + public static let unimplemented = ContactSendRequestEnvironment() +} +#endif + +public let contactSendRequestReducer = Reducer<ContactSendRequestState, ContactSendRequestAction, ContactSendRequestEnvironment> +{ state, action, env in + switch action { + case .start: + return .none + } +} diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestView.swift new file mode 100644 index 00000000..4f5048d3 --- /dev/null +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactSendRequestView.swift @@ -0,0 +1,36 @@ +import ComposableArchitecture +import SwiftUI + +public struct ContactSendRequestView: View { + public init(store: Store<ContactSendRequestState, ContactSendRequestAction>) { + self.store = store + } + + let store: Store<ContactSendRequestState, ContactSendRequestAction> + + struct ViewState: Equatable { + init(state: ContactSendRequestState) {} + } + + public var body: some View { + WithViewStore(store.scope(state: ViewState.init)) { viewStore in + Form { + + } + .navigationTitle("Send Request") + .task { viewStore.send(.start) } + } + } +} + +#if DEBUG +public struct ContactSendRequestView_Previews: PreviewProvider { + public static var previews: some View { + ContactSendRequestView(store: Store( + initialState: ContactSendRequestState(), + reducer: .empty, + environment: () + )) + } +} +#endif diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index 6bf50150..44a46c56 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -1,5 +1,6 @@ import AppCore import ComposableArchitecture +import ComposablePresentation import SwiftUI import XXClient import XXModels @@ -160,6 +161,14 @@ public struct ContactView: View { } .navigationTitle("Contact") .task { viewStore.send(.start) } + .background(NavigationLinkWithStore( + store.scope( + state: \.sendRequest, + action: ContactAction.sendRequest + ), + onDeactivate: { viewStore.send(.sendRequestDismissed) }, + destination: ContactSendRequestView.init(store:) + )) } } } diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index f14c9e39..64d0d72a 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -103,6 +103,12 @@ final class ContactFeatureTests: XCTestCase { environment: .unimplemented ) - store.send(.sendRequestTapped) + store.send(.sendRequestTapped) { + $0.sendRequest = ContactSendRequestState() + } + + store.send(.sendRequestDismissed) { + $0.sendRequest = nil + } } } diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactSendRequestFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactSendRequestFeatureTests.swift new file mode 100644 index 00000000..8d4eb040 --- /dev/null +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactSendRequestFeatureTests.swift @@ -0,0 +1,15 @@ +import ComposableArchitecture +import XCTest +@testable import ContactFeature + +final class ContactSendRequestFeatureTests: XCTestCase { + func testStart() { + let store = TestStore( + initialState: ContactSendRequestState(), + reducer: contactSendRequestReducer, + environment: .unimplemented + ) + + store.send(.start) + } +} -- GitLab