Skip to content
Snippets Groups Projects
Commit c727c9dd authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Refactor fact helpers

parent 1c098a7e
Branches
Tags
2 merge requests!102Release 1.0.0,!68Messenger example - send auth request
import XXClient
// TODO: Move to XXClient library
public enum FactType: Equatable {
case username
case email
case phone
case other(Int)
public static let knownTypes: [Self] = [.username, .email, .phone]
public init(rawValue: Int) {
if let known = FactType.knownTypes.first(where: { $0.rawValue == rawValue }) {
self = known
} else {
self = .other(rawValue)
}
}
public var rawValue: Int {
switch self {
case .username: return 0
case .email: return 1
case .phone: return 2
case .other(let rawValue): return rawValue
}
}
}
extension Array where Element == Fact {
public func get(_ type: FactType) -> Fact? {
first(where: { $0.type == type.rawValue })
}
public mutating func set(_ type: FactType, _ value: String?) {
removeAll(where: { $0.type == type.rawValue })
if let value = value {
append(Fact(fact: value, type: type.rawValue))
sort(by: { $0.type < $1.type })
}
}
}
extension Contact {
public func getFact(_ type: FactType) throws -> Fact? {
try getFacts().get(type)
}
public mutating func setFact(_ type: FactType, _ value: String?) throws {
var facts = try getFacts()
facts.set(type, value)
try setFacts(facts)
}
}
import XXClient
extension Contact {
public var username: String? {
try? getFacts().first(where: { $0.type == 0 })?.fact
}
public var email: String? {
try? getFacts().first(where: { $0.type == 1 })?.fact
}
public var phone: String? {
try? getFacts().first(where: { $0.type == 2 })?.fact
}
}
......@@ -105,13 +105,13 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm
var dbContact = state.dbContact ?? XXModels.Contact(id: state.id)
dbContact.marshaled = xxContact.data
if state.importUsername {
dbContact.username = xxContact.username
dbContact.username = try? xxContact.getFact(.username)?.fact
}
if state.importEmail {
dbContact.email = xxContact.email
dbContact.email = try? xxContact.getFact(.email)?.fact
}
if state.importPhone {
dbContact.phone = xxContact.phone
dbContact.phone = try? xxContact.getFact(.phone)?.fact
}
_ = try! env.db().saveContact(dbContact)
}
......
......@@ -15,14 +15,20 @@ public struct ContactView: View {
struct ViewState: Equatable {
var dbContact: XXModels.Contact?
var xxContact: XXClient.Contact?
var xxContactIsSet: Bool
var xxContactUsername: String?
var xxContactEmail: String?
var xxContactPhone: String?
var importUsername: Bool
var importEmail: Bool
var importPhone: Bool
init(state: ContactState) {
dbContact = state.dbContact
xxContact = state.xxContact
xxContactIsSet = state.xxContact != nil
xxContactUsername = try? state.xxContact?.getFact(.username)?.fact
xxContactEmail = try? state.xxContact?.getFact(.email)?.fact
xxContactPhone = try? state.xxContact?.getFact(.phone)?.fact
importUsername = state.importUsername
importEmail = state.importEmail
importPhone = state.importPhone
......@@ -32,13 +38,13 @@ public struct ContactView: View {
public var body: some View {
WithViewStore(store.scope(state: ViewState.init)) { viewStore in
Form {
if let xxContact = viewStore.xxContact {
if viewStore.xxContactIsSet {
Section {
Button {
viewStore.send(.set(\.$importUsername, !viewStore.importUsername))
} label: {
HStack {
Label(xxContact.username ?? "", systemImage: "person")
Label(viewStore.xxContactUsername ?? "", systemImage: "person")
.tint(Color.primary)
Spacer()
Image(systemName: viewStore.importUsername ? "checkmark.circle.fill" : "circle")
......@@ -50,7 +56,7 @@ public struct ContactView: View {
viewStore.send(.set(\.$importEmail, !viewStore.importEmail))
} label: {
HStack {
Label(xxContact.email ?? "", systemImage: "envelope")
Label(viewStore.xxContactEmail ?? "", systemImage: "envelope")
.tint(Color.primary)
Spacer()
Image(systemName: viewStore.importEmail ? "checkmark.circle.fill" : "circle")
......@@ -62,7 +68,7 @@ public struct ContactView: View {
viewStore.send(.set(\.$importPhone, !viewStore.importPhone))
} label: {
HStack {
Label(xxContact.phone ?? "", systemImage: "phone")
Label(viewStore.xxContactPhone ?? "", systemImage: "phone")
.tint(Color.primary)
Spacer()
Image(systemName: viewStore.importPhone ? "checkmark.circle.fill" : "circle")
......
......@@ -83,10 +83,7 @@ public let registerReducer = Reducer<RegisterState, RegisterAction, RegisterEnvi
let db = try env.db()
try env.messenger.register(username: username)
var contact = try env.messenger.e2e.tryGet().getContact()
var facts: [Fact] = try contact.getFacts()
facts.removeAll(where: { $0.type == 0 })
facts.append(Fact(fact: username, type: 0))
try contact.setFacts(facts)
try contact.setFact(.username, username)
try db.saveContact(Contact(
id: try contact.getId(),
marshaled: contact.data,
......
......@@ -110,13 +110,13 @@ public let sendRequestReducer = Reducer<SendRequestState, SendRequestAction, Sen
try updateAuthStatus(.requesting)
let myFacts = try state.myContact?.getFacts() ?? []
var includedFacts: [Fact] = []
if state.sendUsername, let fact = myFacts.first(where: { $0.type == 0 }) {
if state.sendUsername, let fact = myFacts.get(.username) {
includedFacts.append(fact)
}
if state.sendEmail, let fact = myFacts.first(where: { $0.type == 1 }) {
if state.sendEmail, let fact = myFacts.get(.email) {
includedFacts.append(fact)
}
if state.sendPhone, let fact = myFacts.first(where: { $0.type == 2 }) {
if state.sendPhone, let fact = myFacts.get(.phone) {
includedFacts.append(fact)
}
_ = try env.messenger.e2e.tryGet().requestAuthenticatedChannel(
......
......@@ -11,8 +11,12 @@ public struct SendRequestView: View {
let store: Store<SendRequestState, SendRequestAction>
struct ViewState: Equatable {
var contact: XXClient.Contact
var myContact: XXClient.Contact?
var contactUsername: String?
var contactEmail: String?
var contactPhone: String?
var myUsername: String?
var myEmail: String?
var myPhone: String?
var sendUsername: Bool
var sendEmail: Bool
var sendPhone: Bool
......@@ -20,8 +24,12 @@ public struct SendRequestView: View {
var failure: String?
init(state: SendRequestState) {
contact = state.contact
myContact = state.myContact
contactUsername = try? state.contact.getFact(.username)?.fact
contactEmail = try? state.contact.getFact(.email)?.fact
contactPhone = try? state.contact.getFact(.phone)?.fact
myUsername = try? state.myContact?.getFact(.username)?.fact
myEmail = try? state.myContact?.getFact(.email)?.fact
myPhone = try? state.myContact?.getFact(.phone)?.fact
sendUsername = state.sendUsername
sendEmail = state.sendEmail
sendPhone = state.sendPhone
......@@ -38,7 +46,7 @@ public struct SendRequestView: View {
viewStore.send(.set(\.$sendUsername, !viewStore.sendUsername))
} label: {
HStack {
Label(viewStore.myContact?.username ?? "", systemImage: "person")
Label(viewStore.myUsername ?? "", systemImage: "person")
.tint(Color.primary)
Spacer()
Image(systemName: viewStore.sendUsername ? "checkmark.circle.fill" : "circle")
......@@ -51,7 +59,7 @@ public struct SendRequestView: View {
viewStore.send(.set(\.$sendEmail, !viewStore.sendEmail))
} label: {
HStack {
Label(viewStore.myContact?.email ?? "", systemImage: "envelope")
Label(viewStore.myEmail ?? "", systemImage: "envelope")
.tint(Color.primary)
Spacer()
Image(systemName: viewStore.sendEmail ? "checkmark.circle.fill" : "circle")
......@@ -64,7 +72,7 @@ public struct SendRequestView: View {
viewStore.send(.set(\.$sendPhone, !viewStore.sendPhone))
} label: {
HStack {
Label(viewStore.myContact?.phone ?? "", systemImage: "phone")
Label(viewStore.myPhone ?? "", systemImage: "phone")
.tint(Color.primary)
Spacer()
Image(systemName: viewStore.sendPhone ? "checkmark.circle.fill" : "circle")
......@@ -78,9 +86,9 @@ public struct SendRequestView: View {
.disabled(viewStore.isSending)
Section {
Label(viewStore.contact.username ?? "", systemImage: "person")
Label(viewStore.contact.email ?? "", systemImage: "envelope")
Label(viewStore.contact.phone ?? "", systemImage: "phone")
Label(viewStore.contactUsername ?? "", systemImage: "person")
Label(viewStore.contactEmail ?? "", systemImage: "envelope")
Label(viewStore.contactPhone ?? "", systemImage: "phone")
} header: {
Text("Contact")
}
......
......@@ -44,9 +44,9 @@ public let userSearchResultReducer = Reducer<UserSearchResultState, UserSearchRe
{ state, action, env in
switch action {
case .start:
state.username = state.xxContact.username
state.email = state.xxContact.email
state.phone = state.xxContact.phone
state.username = try? state.xxContact.getFact(.username)?.fact
state.email = try? state.xxContact.getFact(.email)?.fact
state.phone = try? state.xxContact.getFact(.phone)?.fact
return .none
case .tapped:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment