Skip to content
Snippets Groups Projects

Messenger example - send auth request

Merged Dariusz Rybicki requested to merge feature/messenger-example-contact-request into development
1 file
+ 1
1
Compare changes
  • Side-by-side
  • Inline
import ComposableArchitecture
import ComposablePresentation
import ContactFeature
import Foundation
import XCTestDynamicOverlay
import XXClient
@@ -11,70 +13,60 @@ public struct UserSearchState: Equatable {
case phone
}
public struct Result: Equatable, Identifiable {
public init(
id: Data,
contact: Contact,
username: String? = nil,
email: String? = nil,
phone: String? = nil
) {
self.id = id
self.contact = contact
self.username = username
self.email = email
self.phone = phone
}
public var id: Data
public var contact: XXClient.Contact
public var username: String?
public var email: String?
public var phone: String?
}
public init(
focusedField: Field? = nil,
query: MessengerSearchUsers.Query = .init(),
isSearching: Bool = false,
failure: String? = nil,
results: IdentifiedArrayOf<Result> = []
results: IdentifiedArrayOf<UserSearchResultState> = [],
contact: ContactState? = nil
) {
self.focusedField = focusedField
self.query = query
self.isSearching = isSearching
self.failure = failure
self.results = results
self.contact = contact
}
@BindableState public var focusedField: Field?
@BindableState public var query: MessengerSearchUsers.Query
public var isSearching: Bool
public var failure: String?
public var results: IdentifiedArrayOf<Result>
public var results: IdentifiedArrayOf<UserSearchResultState>
public var contact: ContactState?
}
public enum UserSearchAction: Equatable, BindableAction {
case searchTapped
case didFail(String)
case didSucceed([Contact])
case didDismissContact
case binding(BindingAction<UserSearchState>)
case result(id: UserSearchResultState.ID, action: UserSearchResultAction)
case contact(ContactAction)
}
public struct UserSearchEnvironment {
public init(
messenger: Messenger,
mainQueue: AnySchedulerOf<DispatchQueue>,
bgQueue: AnySchedulerOf<DispatchQueue>
bgQueue: AnySchedulerOf<DispatchQueue>,
result: @escaping () -> UserSearchResultEnvironment,
contact: @escaping () -> ContactEnvironment
) {
self.messenger = messenger
self.mainQueue = mainQueue
self.bgQueue = bgQueue
self.result = result
self.contact = contact
}
public var messenger: Messenger
public var mainQueue: AnySchedulerOf<DispatchQueue>
public var bgQueue: AnySchedulerOf<DispatchQueue>
public var result: () -> UserSearchResultEnvironment
public var contact: () -> ContactEnvironment
}
#if DEBUG
@@ -82,7 +74,9 @@ extension UserSearchEnvironment {
public static let unimplemented = UserSearchEnvironment(
messenger: .unimplemented,
mainQueue: .unimplemented,
bgQueue: .unimplemented
bgQueue: .unimplemented,
result: { .unimplemented },
contact: { .unimplemented }
)
}
#endif
@@ -111,14 +105,7 @@ public let userSearchReducer = Reducer<UserSearchState, UserSearchAction, UserSe
state.failure = nil
state.results = IdentifiedArray(uniqueElements: contacts.compactMap { contact in
guard let id = try? contact.getId() else { return nil }
let facts = (try? contact.getFacts()) ?? []
return UserSearchState.Result(
id: id,
contact: contact,
username: facts.first(where: { $0.type == 0 })?.fact,
email: facts.first(where: { $0.type == 1 })?.fact,
phone: facts.first(where: { $0.type == 2 })?.fact
)
return UserSearchResultState(id: id, xxContact: contact)
})
return .none
@@ -128,8 +115,32 @@ public let userSearchReducer = Reducer<UserSearchState, UserSearchAction, UserSe
state.results = []
return .none
case .binding(_):
case .didDismissContact:
state.contact = nil
return .none
case .result(let id, action: .tapped):
state.contact = ContactState(
id: id,
xxContact: state.results[id: id]?.xxContact
)
return .none
case .binding(_), .result(_, _), .contact(_):
return .none
}
}
.binding()
.presenting(
forEach: userSearchResultReducer,
state: \.results,
action: /UserSearchAction.result(id:action:),
environment: { $0.result() }
)
.presenting(
contactReducer,
state: .keyPath(\.contact),
id: .keyPath(\.?.id),
action: /UserSearchAction.contact,
environment: { $0.contact() }
)
Loading