From dffced825a23595a76df8af3c62032482a4ae6bb Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Mon, 5 Dec 2022 12:21:12 +0100
Subject: [PATCH] Present group chat screen

---
 Examples/xx-messenger/Package.swift           |  1 +
 .../Sources/GroupFeature/GroupComponent.swift | 27 ++++++++++++++++++-
 .../Sources/GroupFeature/GroupView.swift      | 22 +++++++++++++++
 .../GroupComponentTests.swift                 | 21 +++++++++++++++
 4 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift
index 2c22609f..be183c09 100644
--- a/Examples/xx-messenger/Package.swift
+++ b/Examples/xx-messenger/Package.swift
@@ -267,6 +267,7 @@ let package = Package(
       name: "GroupFeature",
       dependencies: [
         .target(name: "AppCore"),
+        .target(name: "ChatFeature"),
         .product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
         .product(name: "ComposablePresentation", package: "swift-composable-presentation"),
         .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
diff --git a/Examples/xx-messenger/Sources/GroupFeature/GroupComponent.swift b/Examples/xx-messenger/Sources/GroupFeature/GroupComponent.swift
index d9b7d233..359ee899 100644
--- a/Examples/xx-messenger/Sources/GroupFeature/GroupComponent.swift
+++ b/Examples/xx-messenger/Sources/GroupFeature/GroupComponent.swift
@@ -1,5 +1,7 @@
 import AppCore
+import ChatFeature
 import ComposableArchitecture
+import ComposablePresentation
 import Foundation
 import XXMessengerClient
 import XXModels
@@ -10,18 +12,21 @@ public struct GroupComponent: ReducerProtocol {
       groupId: XXModels.Group.ID,
       groupInfo: XXModels.GroupInfo? = nil,
       isJoining: Bool = false,
-      joinFailure: String? = nil
+      joinFailure: String? = nil,
+      chat: ChatComponent.State? = nil
     ) {
       self.groupId = groupId
       self.groupInfo = groupInfo
       self.isJoining = isJoining
       self.joinFailure = joinFailure
+      self.chat = chat
     }
 
     public var groupId: XXModels.Group.ID
     public var groupInfo: XXModels.GroupInfo?
     public var isJoining: Bool
     public var joinFailure: String?
+    public var chat: ChatComponent.State?
   }
 
   public enum Action: Equatable {
@@ -30,6 +35,9 @@ public struct GroupComponent: ReducerProtocol {
     case joinButtonTapped
     case didJoin
     case didFailToJoin(String)
+    case chatButtonTapped
+    case didDismissChat
+    case chat(ChatComponent.Action)
   }
 
   public init() {}
@@ -88,7 +96,24 @@ public struct GroupComponent: ReducerProtocol {
         state.isJoining = false
         state.joinFailure = failure
         return .none
+
+      case .chatButtonTapped:
+        state.chat = ChatComponent.State(id: .group(state.groupId))
+        return .none
+
+      case .didDismissChat:
+        state.chat = nil
+        return .none
+
+      case .chat(_):
+        return .none
       }
     }
+    .presenting(
+      state: .keyPath(\.chat),
+      id: .notNil(),
+      action: /Action.chat,
+      presented: { ChatComponent() }
+    )
   }
 }
diff --git a/Examples/xx-messenger/Sources/GroupFeature/GroupView.swift b/Examples/xx-messenger/Sources/GroupFeature/GroupView.swift
index 67b880f4..a7520d53 100644
--- a/Examples/xx-messenger/Sources/GroupFeature/GroupView.swift
+++ b/Examples/xx-messenger/Sources/GroupFeature/GroupView.swift
@@ -1,5 +1,7 @@
 import AppCore
+import ChatFeature
 import ComposableArchitecture
+import ComposablePresentation
 import SwiftUI
 import XXModels
 
@@ -68,8 +70,28 @@ public struct GroupView: View {
             }
           }
         }
+
+        Section {
+          Button {
+            viewStore.send(.chatButtonTapped)
+          } label: {
+            HStack {
+              Text("Chat")
+              Spacer()
+              Image(systemName: "chevron.forward")
+            }
+          }
+        }
       }
       .navigationTitle("Group")
+      .background(NavigationLinkWithStore(
+        store.scope(
+          state: \.chat,
+          action: Component.Action.chat
+        ),
+        onDeactivate: { viewStore.send(.didDismissChat) },
+        destination: ChatView.init(store:)
+      ))
       .task { viewStore.send(.start) }
     }
   }
diff --git a/Examples/xx-messenger/Tests/GroupFeatureTests/GroupComponentTests.swift b/Examples/xx-messenger/Tests/GroupFeatureTests/GroupComponentTests.swift
index 3c7193fc..b3791b1f 100644
--- a/Examples/xx-messenger/Tests/GroupFeatureTests/GroupComponentTests.swift
+++ b/Examples/xx-messenger/Tests/GroupFeatureTests/GroupComponentTests.swift
@@ -1,3 +1,4 @@
+import ChatFeature
 import Combine
 import ComposableArchitecture
 import CustomDump
@@ -140,6 +141,26 @@ final class GroupComponentTests: XCTestCase {
       $0.joinFailure = failure.localizedDescription
     }
   }
+
+  func testPresentChat() {
+    let groupInfo = GroupInfo.stub()
+
+    let store = TestStore(
+      initialState: GroupComponent.State(
+        groupId: groupInfo.group.id,
+        groupInfo: groupInfo
+      ),
+      reducer: GroupComponent()
+    )
+
+    store.send(.chatButtonTapped) {
+      $0.chat = ChatComponent.State(id: .group(groupInfo.id))
+    }
+
+    store.send(.didDismissChat) {
+      $0.chat = nil
+    }
+  }
 }
 
 private extension XXModels.GroupInfo {
-- 
GitLab