diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index db3097ee99057d8c4c52ec1fdf6b9cd1daf430e7..5df8eb39dd57b9f788e430521dd637d0e48e1b64 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -120,6 +120,8 @@ let package = Package( .target(name: "ContactFeature"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), .product(name: "ComposablePresentation", package: "swift-composable-presentation"), + .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), + .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), .product(name: "XXModels", package: "client-ios-db"), ], swiftSettings: swiftSettings diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index f57003f0335827259ab1c96d66eead155b013f08..61bfba1f3163cf119e610606f9d89ea67a122171 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -66,6 +66,7 @@ extension AppEnvironment { }, contacts: { ContactsEnvironment( + messenger: messenger, db: dbManager.getDB, mainQueue: mainQueue, bgQueue: bgQueue, diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift index 7969093471a590d9543b5fed7c1d90a6e5975b6a..1ded89de4cbf9dd44014395e3e79bf6ff2fdcc20 100644 --- a/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift +++ b/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift @@ -4,17 +4,22 @@ import ComposablePresentation import ContactFeature import Foundation import XCTestDynamicOverlay +import XXClient +import XXMessengerClient import XXModels public struct ContactsState: Equatable { public init( - contacts: IdentifiedArrayOf<Contact> = [], + myId: Data? = nil, + contacts: IdentifiedArrayOf<XXModels.Contact> = [], contact: ContactState? = nil ) { + self.myId = myId self.contacts = contacts self.contact = contact } + public var myId: Data? public var contacts: IdentifiedArrayOf<XXModels.Contact> public var contact: ContactState? } @@ -29,17 +34,20 @@ public enum ContactsAction: Equatable { public struct ContactsEnvironment { public init( + messenger: Messenger, db: DBManagerGetDB, mainQueue: AnySchedulerOf<DispatchQueue>, bgQueue: AnySchedulerOf<DispatchQueue>, contact: @escaping () -> ContactEnvironment ) { + self.messenger = messenger self.db = db self.mainQueue = mainQueue self.bgQueue = bgQueue self.contact = contact } + public var messenger: Messenger public var db: DBManagerGetDB public var mainQueue: AnySchedulerOf<DispatchQueue> public var bgQueue: AnySchedulerOf<DispatchQueue> @@ -49,6 +57,7 @@ public struct ContactsEnvironment { #if DEBUG extension ContactsEnvironment { public static let unimplemented = ContactsEnvironment( + messenger: .unimplemented, db: .unimplemented, mainQueue: .unimplemented, bgQueue: .unimplemented, @@ -61,6 +70,7 @@ public let contactsReducer = Reducer<ContactsState, ContactsAction, ContactsEnvi { state, action, env in switch action { case .start: + state.myId = try? env.messenger.e2e.tryGet().getContact().getId() return Effect .catching { try env.db() } .flatMap { $0.fetchContactsPublisher(.init()) } @@ -70,7 +80,11 @@ public let contactsReducer = Reducer<ContactsState, ContactsAction, ContactsEnvi .receive(on: env.mainQueue) .eraseToEffect() - case .didFetchContacts(let contacts): + case .didFetchContacts(var contacts): + if let myId = state.myId, + let myIndex = contacts.firstIndex(where: { $0.id == myId }) { + contacts.move(fromOffsets: [myIndex], toOffset: contacts.startIndex) + } state.contacts = IdentifiedArray(uniqueElements: contacts) return .none diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift index 7b02efd1786f87905d93799aa6f58af350fca27d..b7798685cf75d851adba765f751c6fb5a47ceea0 100644 --- a/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift +++ b/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift @@ -13,9 +13,11 @@ public struct ContactsView: View { let store: Store<ContactsState, ContactsAction> struct ViewState: Equatable { + var myId: Data? var contacts: IdentifiedArrayOf<XXModels.Contact> init(state: ContactsState) { + myId = state.myId contacts = state.contacts } } @@ -24,23 +26,37 @@ public struct ContactsView: View { WithViewStore(store.scope(state: ViewState.init)) { viewStore in Form { ForEach(viewStore.contacts) { contact in - Section { - Button { - viewStore.send(.contactSelected(contact)) - } label: { - HStack { - VStack(alignment: .leading, spacing: 8) { - Label(contact.username ?? "", systemImage: "person") - Label(contact.email ?? "", systemImage: "envelope") - Label(contact.phone ?? "", systemImage: "phone") + if contact.id == viewStore.myId { + Section { + VStack(alignment: .leading, spacing: 8) { + Label(contact.username ?? "", systemImage: "person") + Label(contact.email ?? "", systemImage: "envelope") + Label(contact.phone ?? "", systemImage: "phone") + } + .font(.callout) + .tint(Color.primary) + } header: { + Text("My contact") + } + } else { + Section { + Button { + viewStore.send(.contactSelected(contact)) + } label: { + HStack { + VStack(alignment: .leading, spacing: 8) { + Label(contact.username ?? "", systemImage: "person") + Label(contact.email ?? "", systemImage: "envelope") + Label(contact.phone ?? "", systemImage: "phone") + } + .font(.callout) + .tint(Color.primary) + Spacer() + Image(systemName: "chevron.forward") } - .font(.callout) - .tint(Color.primary) - Spacer() - Image(systemName: "chevron.forward") } + ContactAuthStatusView(contact.authStatus) } - ContactAuthStatusView(contact.authStatus) } } } diff --git a/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift b/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift index 6c68f406deb4e350c129d5a1a33920c2ef0280a0..a0c0291ef79865fa6c1f3d1ffeb25235bd520acf 100644 --- a/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift @@ -3,6 +3,8 @@ import ComposableArchitecture import ContactFeature import CustomDump import XCTest +import XXClient +import XXMessengerClient import XXModels @testable import ContactsFeature @@ -14,11 +16,21 @@ final class ContactsFeatureTests: XCTestCase { environment: .unimplemented ) + let myId = "2".data(using: .utf8)! var didFetchContacts: [XXModels.Contact.Query] = [] let contactsPublisher = PassthroughSubject<[XXModels.Contact], Error>() store.environment.mainQueue = .immediate store.environment.bgQueue = .immediate + store.environment.messenger.e2e.get = { + var e2e: E2E = .unimplemented + e2e.getContact.run = { + var contact: XXClient.Contact = .unimplemented(Data()) + contact.getIdFromContact.run = { _ in myId } + return contact + } + return e2e + } store.environment.db.run = { var db: Database = .failing db.fetchContactsPublisher.run = { query in @@ -28,7 +40,9 @@ final class ContactsFeatureTests: XCTestCase { return db } - store.send(.start) + store.send(.start) { + $0.myId = myId + } XCTAssertNoDifference(didFetchContacts, [XXModels.Contact.Query()]) @@ -40,7 +54,11 @@ final class ContactsFeatureTests: XCTestCase { contactsPublisher.send(contacts) store.receive(.didFetchContacts(contacts)) { - $0.contacts = IdentifiedArray(uniqueElements: contacts) + $0.contacts = IdentifiedArray(uniqueElements: [ + contacts[1], + contacts[0], + contacts[2], + ]) } contactsPublisher.send(completion: .finished)