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