From 16b258b9ff7fcb74ac619cc1d9cd2879fa1b78e5 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 7 Sep 2022 22:29:58 +0200 Subject: [PATCH] Import selected facts to contact --- .../ContactFeature/ContactFeature.swift | 32 ++++++++++--- .../Sources/ContactFeature/ContactView.swift | 47 +++++++++++++++++-- .../ContactFeatureTests.swift | 4 +- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index c75faa7b..b8da32a4 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -13,27 +13,37 @@ public struct ContactState: Equatable { id: Data, dbContact: XXModels.Contact? = nil, xxContact: XXClient.Contact? = nil, + importUsername: Bool = true, + importEmail: Bool = true, + importPhone: Bool = true, sendRequest: SendRequestState? = nil ) { self.id = id self.dbContact = dbContact self.xxContact = xxContact + self.importUsername = importUsername + self.importEmail = importEmail + self.importPhone = importPhone self.sendRequest = sendRequest } public var id: Data public var dbContact: XXModels.Contact? public var xxContact: XXClient.Contact? + @BindableState public var importUsername: Bool + @BindableState public var importEmail: Bool + @BindableState public var importPhone: Bool public var sendRequest: SendRequestState? } -public enum ContactAction: Equatable { +public enum ContactAction: Equatable, BindableAction { case start case dbContactFetched(XXModels.Contact?) - case saveFactsTapped + case importFactsTapped case sendRequestTapped case sendRequestDismissed case sendRequest(SendRequestAction) + case binding(BindingAction<ContactState>) } public struct ContactEnvironment { @@ -89,14 +99,20 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm state.dbContact = contact return .none - case .saveFactsTapped: + case .importFactsTapped: guard let xxContact = state.xxContact else { return .none } return .fireAndForget { [state] in var dbContact = state.dbContact ?? XXModels.Contact(id: state.id) dbContact.marshaled = xxContact.data - dbContact.username = xxContact.username - dbContact.email = xxContact.email - dbContact.phone = xxContact.phone + if state.importUsername { + dbContact.username = xxContact.username + } + if state.importEmail { + dbContact.email = xxContact.email + } + if state.importPhone { + dbContact.phone = xxContact.phone + } _ = try! env.db().saveContact(dbContact) } .subscribe(on: env.bgQueue) @@ -121,8 +137,12 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm case .sendRequest(_): return .none + + case .binding(_): + return .none } } +.binding() .presenting( sendRequestReducer, state: .keyPath(\.sendRequest), diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index d14271f0..a3b6ee08 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -16,10 +16,16 @@ public struct ContactView: View { struct ViewState: Equatable { var dbContact: XXModels.Contact? var xxContact: XXClient.Contact? + var importUsername: Bool + var importEmail: Bool + var importPhone: Bool init(state: ContactState) { dbContact = state.dbContact xxContact = state.xxContact + importUsername = state.importUsername + importEmail = state.importEmail + importPhone = state.importPhone } } @@ -28,11 +34,44 @@ public struct ContactView: View { Form { if let xxContact = viewStore.xxContact { Section { - Label(xxContact.username ?? "", systemImage: "person") - Label(xxContact.email ?? "", systemImage: "envelope") - Label(xxContact.phone ?? "", systemImage: "phone") Button { - viewStore.send(.saveFactsTapped) + viewStore.send(.set(\.$importUsername, !viewStore.importUsername)) + } label: { + HStack { + Label(xxContact.username ?? "", systemImage: "person") + .tint(Color.primary) + Spacer() + Image(systemName: viewStore.importUsername ? "checkmark.circle.fill" : "circle") + .foregroundColor(.accentColor) + } + } + + Button { + viewStore.send(.set(\.$importEmail, !viewStore.importEmail)) + } label: { + HStack { + Label(xxContact.email ?? "", systemImage: "envelope") + .tint(Color.primary) + Spacer() + Image(systemName: viewStore.importEmail ? "checkmark.circle.fill" : "circle") + .foregroundColor(.accentColor) + } + } + + Button { + viewStore.send(.set(\.$importPhone, !viewStore.importPhone)) + } label: { + HStack { + Label(xxContact.phone ?? "", systemImage: "phone") + .tint(Color.primary) + Spacer() + Image(systemName: viewStore.importPhone ? "checkmark.circle.fill" : "circle") + .foregroundColor(.accentColor) + } + } + + Button { + viewStore.send(.importFactsTapped) } label: { if viewStore.dbContact == nil { Text("Save contact") diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index 4d637ecf..244cc900 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -47,7 +47,7 @@ final class ContactFeatureTests: XCTestCase { dbContactsPublisher.send(completion: .finished) } - func testSaveFacts() { + func testImportFacts() { let dbContact: XXModels.Contact = .init( id: "contact-id".data(using: .utf8)! ) @@ -84,7 +84,7 @@ final class ContactFeatureTests: XCTestCase { return db } - store.send(.saveFactsTapped) + store.send(.importFactsTapped) var expectedSavedContact = dbContact expectedSavedContact.marshaled = xxContact.data -- GitLab