From 5e9b0438f25b4aba2e2f3a6da27e1e0080ca51b4 Mon Sep 17 00:00:00 2001 From: Bruno Muniz Azevedo Filho <bruno@elixxir.io> Date: Wed, 22 Jun 2022 01:12:08 -0300 Subject: [PATCH] Cleaned Session.swift except for FT --- Sources/Integration/Client.swift | 63 ++++---- Sources/Integration/Extensions.swift | 5 +- .../Implementations/Bindings.swift | 3 +- .../Implementations/GroupManager.swift | 1 + .../Implementations/UserDiscovery.swift | 1 + .../Interfaces/GroupManagerInterface.swift | 1 + Sources/Integration/Listeners.swift | 11 +- .../Integration/Mocks/GroupManagerMock.swift | 1 + .../Integration/Session/Session+Chat.swift | 79 ++-------- .../Session/Session+Contacts.swift | 94 +++++------- .../Integration/Session/Session+Group.swift | 73 ++++----- Sources/Integration/Session/Session+UD.swift | 1 + Sources/Integration/Session/Session.swift | 34 ++--- Sources/Integration/Session/SessionType.swift | 8 +- Sources/Models/GroupChatInfo.swift | 44 +++--- Sources/Models/GroupMember.swift | 84 +++++------ Sources/Models/GroupMessage.swift | 112 +++++++------- Sources/Models/Message.swift | 140 +++++++++--------- 18 files changed, 323 insertions(+), 432 deletions(-) diff --git a/Sources/Integration/Client.swift b/Sources/Integration/Client.swift index bdd6784d..34b4cc4f 100644 --- a/Sources/Integration/Client.swift +++ b/Sources/Integration/Client.swift @@ -2,8 +2,9 @@ import Retry import Models import Combine import Defaults -import Foundation import Bindings +import XXModels +import Foundation public class Client { @KeyObject(.inappnotifications, defaultValue: true) var inappnotifications: Bool @@ -23,8 +24,6 @@ public class Client { var events: AnyPublisher<BackendEvent, Never> { eventsSubject.eraseToAnyPublisher() } var requestsSent: AnyPublisher<Contact, Never> { requestsSentSubject.eraseToAnyPublisher() } var confirmations: AnyPublisher<Contact, Never> { confirmationsSubject.eraseToAnyPublisher() } - var groupMessages: AnyPublisher<GroupMessage, Never> { groupMessagesSubject.eraseToAnyPublisher() } - var incomingTransfers: AnyPublisher<FileTransfer, Never> { transfersSubject.eraseToAnyPublisher() } var groupRequests: AnyPublisher<(Group, [Data], String?), Never> { groupRequestsSubject.eraseToAnyPublisher() } private let backupSubject = PassthroughSubject<Data, Never>() @@ -35,8 +34,6 @@ public class Client { private let eventsSubject = PassthroughSubject<BackendEvent, Never>() private let requestsSentSubject = PassthroughSubject<Contact, Never>() private let confirmationsSubject = PassthroughSubject<Contact, Never>() - private let transfersSubject = PassthroughSubject<FileTransfer, Never>() - private let groupMessagesSubject = PassthroughSubject<GroupMessage, Never>() private let groupRequestsSubject = PassthroughSubject<(Group, [Data], String?), Never>() private var isBackupInitialization = false @@ -110,7 +107,7 @@ public class Client { switch $0 { case .success(var contact): - contact.status = .requested + contact.authStatus = .requested self.requestsSentSubject.send(contact) print(">>> Restored \(contact.username). Setting status as requested") case .failure(let error): @@ -165,8 +162,8 @@ public class Client { groupManager = try bindings.listenGroupRequests { [weak groupRequestsSubject] request, members, welcome in groupRequestsSubject?.send((request, members, welcome)) - } groupMessages: { [weak groupMessagesSubject] in - groupMessagesSubject?.send($0) + } groupMessages: { [weak messagesSubject] in + messagesSubject?.send($0) } bindings.listenPreImageUpdates() @@ -179,31 +176,31 @@ public class Client { } private func instantiateTransferManager() throws { - transferManager = try bindings.generateTransferManager { [weak transfersSubject] tid, name, type, sender in - - /// Someone transfered something to me - /// but I haven't received yet. I'll store an - /// IncomingTransfer object so later on I can - /// pull up whatever this contact has sent me. - /// - guard let name = name, - let type = type, - let contact = sender, - let _extension = Attachment.Extension.from(type) else { - log(string: "Transfer of \(name ?? "nil").\(type ?? "nil") is being dismissed", type: .error) - return - } - - transfersSubject?.send( - FileTransfer( - tid: tid, - contact: contact, - fileName: name, - fileType: _extension.written, - isIncoming: true - ) - ) - } +// transferManager = try bindings.generateTransferManager { [weak transfersSubject] tid, name, type, sender in +// +// /// Someone transfered something to me +// /// but I haven't received yet. I'll store an +// /// IncomingTransfer object so later on I can +// /// pull up whatever this contact has sent me. +// /// +// guard let name = name, +// let type = type, +// let contact = sender, +// let _extension = Attachment.Extension.from(type) else { +// log(string: "Transfer of \(name ?? "nil").\(type ?? "nil") is being dismissed", type: .error) +// return +// } +// +// transfersSubject?.send( +// FileTransfer( +// tid: tid, +// contact: contact, +// fileName: name, +// fileType: _extension.written, +// isIncoming: true +// ) +// ) +// } } private func instantiateUserDiscovery() throws { diff --git a/Sources/Integration/Extensions.swift b/Sources/Integration/Extensions.swift index 93cf186a..74835b71 100644 --- a/Sources/Integration/Extensions.swift +++ b/Sources/Integration/Extensions.swift @@ -1,8 +1,9 @@ import Models +import XXModels import Bindings extension Contact { - init(with contact: BindingsContact, status: Contact.Status) { + init(with contact: BindingsContact, status: Contact.AuthStatus) { self.init( photo: nil, userId: contact.getID()!, @@ -33,9 +34,7 @@ extension Message { roundURL: message.getRoundURL() ) } -} -extension GroupMessage { init(with message: BindingsGroupMessageReceive) { guard let payload = try? Payload(with: message.getPayload()!) else { fatalError() } diff --git a/Sources/Integration/Implementations/Bindings.swift b/Sources/Integration/Implementations/Bindings.swift index ce843f4a..6aac71d4 100644 --- a/Sources/Integration/Implementations/Bindings.swift +++ b/Sources/Integration/Implementations/Bindings.swift @@ -1,8 +1,9 @@ import Shared import Models import Bindings -import DependencyInjection +import XXModels import Foundation +import DependencyInjection public let evaluateNotification: NotificationEvaluation = BindingsNotificationsForMe diff --git a/Sources/Integration/Implementations/GroupManager.swift b/Sources/Integration/Implementations/GroupManager.swift index c51522be..1fcdbccf 100644 --- a/Sources/Integration/Implementations/GroupManager.swift +++ b/Sources/Integration/Implementations/GroupManager.swift @@ -1,4 +1,5 @@ import Models +import XXModels import Bindings extension BindingsGroupChat: GroupManagerInterface { diff --git a/Sources/Integration/Implementations/UserDiscovery.swift b/Sources/Integration/Implementations/UserDiscovery.swift index b88afa0d..56c9b4de 100644 --- a/Sources/Integration/Implementations/UserDiscovery.swift +++ b/Sources/Integration/Implementations/UserDiscovery.swift @@ -1,5 +1,6 @@ import Retry import Models +import XXModels import Bindings import Foundation diff --git a/Sources/Integration/Interfaces/GroupManagerInterface.swift b/Sources/Integration/Interfaces/GroupManagerInterface.swift index c1c5523c..dcddfa9e 100644 --- a/Sources/Integration/Interfaces/GroupManagerInterface.swift +++ b/Sources/Integration/Interfaces/GroupManagerInterface.swift @@ -1,4 +1,5 @@ import Models +import XXModels import Foundation public protocol GroupManagerInterface { diff --git a/Sources/Integration/Listeners.swift b/Sources/Integration/Listeners.swift index 23f9f223..3859566e 100644 --- a/Sources/Integration/Listeners.swift +++ b/Sources/Integration/Listeners.swift @@ -1,13 +1,10 @@ import Models import Shared -import Bindings -import Foundation import os.log import Combine - -import Combine - -import Combine +import XXModels +import Bindings +import Foundation public extension BindingsClient { static func listenLogs() { @@ -111,7 +108,7 @@ public extension BindingsClient { func listenGroupRequests( _ groupRequests: @escaping (Group, [Data], String?) -> Void, - groupMessages: @escaping (GroupMessage) -> Void + groupMessages: @escaping (Message) -> Void ) throws -> GroupManagerInterface? { var error: NSError? diff --git a/Sources/Integration/Mocks/GroupManagerMock.swift b/Sources/Integration/Mocks/GroupManagerMock.swift index ecec61c7..137cfca6 100644 --- a/Sources/Integration/Mocks/GroupManagerMock.swift +++ b/Sources/Integration/Mocks/GroupManagerMock.swift @@ -1,4 +1,5 @@ import Models +import XXModels import Foundation final class GroupManagerMock: GroupManagerInterface { diff --git a/Sources/Integration/Session/Session+Chat.swift b/Sources/Integration/Session/Session+Chat.swift index 5bdf71c6..814df83d 100644 --- a/Sources/Integration/Session/Session+Chat.swift +++ b/Sources/Integration/Session/Session+Chat.swift @@ -1,49 +1,10 @@ -import Models -import Foundation import UIKit +import Models import Shared +import XXModels +import Foundation extension Session { - public func readAll(from contact: Contact) { - do { - try dbManager.updateAll( - Message.self, - Message.Request.unreadsFromContactId(contact.userId), - with: [Message.Column.unread.set(to: false)] - ) - } catch { - log(string: error.localizedDescription, type: .error) - } - } - - public func readAll(from group: Group) { - do { - try dbManager.updateAll( - GroupMessage.self, - GroupMessage.Request.unreadsFromGroup(group.groupId), - with: [GroupMessage.Column.unread.set(to: false)] - ) - } catch { - log(string: error.localizedDescription, type: .error) - } - } - - public func deleteAll(from contact: Contact) { - do { - try dbManager.delete(Message.self, .withContact(contact.userId)) - } catch { - log(string: error.localizedDescription, type: .error) - } - } - - public func deleteAll(from group: Group) { - do { - try dbManager.delete(GroupMessage.self, .fromGroup(group.groupId)) - } catch { - log(string: error.localizedDescription, type: .error) - } - } - public func send(imageData: Data, to contact: Contact, completion: @escaping (Result<Void, Error>) -> Void) { client.bindings.compress(image: imageData) { [weak self] in guard let self = self else { @@ -68,39 +29,29 @@ extension Session { public func send(_ payload: Payload, toContact contact: Contact) { var message = Message( sender: client.bindings.meMarshalled, - receiver: contact.userId, + receiver: contact.id, payload: payload, unread: false, timestamp: Date.asTimestamp, uniqueId: nil, - status: payload.attachment == nil ? .sending : .sendingAttachment + status: .sending ) do { - message = try dbManager.save(message) + message = try dbManager.saveMessage(message) send(message: message) } catch { log(string: error.localizedDescription, type: .error) } } - public func delete(messages: [Int64]) { - messages.forEach { - do { - try dbManager.delete(Message.self, .withId($0)) - } catch { - log(string: error.localizedDescription, type: .error) - } - } - } - public func retryMessage(_ id: Int64) { guard var message: Message = try? dbManager.fetch(withId: id) else { return } message.timestamp = Date.asTimestamp - message.status = message.payload.attachment == nil ? .sending : .sendingAttachment + message.status = .sending do { - message = try dbManager.save(message) + message = try dbManager.saveMessage(message) send(message: message) } catch { log(string: error.localizedDescription, type: .error) @@ -147,13 +98,13 @@ extension Session { } } case .failure(let error): - message.status = .failedToSend + message.status = .sendingFailed log(string: error.localizedDescription, type: .error) } DispatchQueue.main.async { do { - _ = try self.dbManager.save(message) + _ = try self.dbManager.saveMessage(message) } catch { log(string: error.localizedDescription, type: .error) } @@ -204,20 +155,20 @@ extension Session { ) message.payload.attachment?.transferId = tid - message.status = .sendingAttachment + message.status = .sending do { - _ = try self.dbManager.save(message) + _ = try self.dbManager.saveMessage(message) _ = try self.dbManager.save(transfer) } catch { log(string: error.localizedDescription, type: .error) } } catch { - message.status = .failedToSend + message.status = .sendingFailed log(string: error.localizedDescription, type: .error) do { - _ = try self.dbManager.save(message) + _ = try self.dbManager.saveMessage(message) } catch let otherError { log(string: otherError.localizedDescription, type: .error) } @@ -267,7 +218,7 @@ extension Session { ) do { - message = try self.dbManager.save(message) + message = try self.dbManager.saveMessage(message) try self.dbManager.save(transfer) } catch { log(string: "Failed to save message/transfer to the database. Will not start listening to transfer... \(error.localizedDescription)", type: .info) diff --git a/Sources/Integration/Session/Session+Contacts.swift b/Sources/Integration/Session/Session+Contacts.swift index af09d609..1752883c 100644 --- a/Sources/Integration/Session/Session+Contacts.swift +++ b/Sources/Integration/Session/Session+Contacts.swift @@ -1,6 +1,7 @@ import Retry import Models import Shared +import XXModels import Foundation extension Session { @@ -12,10 +13,10 @@ extension Session { log(string: "Requested verification of \(contact.username)", type: .crumbs) var contact = contact - contact.status = .verificationInProgress + contact.authStatus = .verificationInProgress do { - contact = try dbManager.save(contact) + contact = try dbManager.saveContact(contact) } catch { log(string: "Failed to store contact request upon verification. Returning, request will be abandoned to not crash", type: .error) } @@ -35,11 +36,11 @@ extension Session { let resultClosure: (Result<Contact, Error>) -> Void = { result in switch result { case .success(let mightBe): - guard try! self.client.bindings.verify(marshaled: contact.marshaled, verifiedMarshaled: mightBe.marshaled) else { + guard try! self.client.bindings.verify(marshaled: contact.marshaled!, verifiedMarshaled: mightBe.marshaled!) else { log(string: "\(contact.username) is fake. Deleted!", type: .info) do { - try self.dbManager.delete(contact) + try self.dbManager.deleteContact(contact) } catch { log(string: error.localizedDescription, type: .error) } @@ -47,7 +48,7 @@ extension Session { return } - contact.status = .verified + contact.authStatus = .verified log(string: "Verified \(contact.username)", type: .info) do { @@ -58,7 +59,7 @@ extension Session { case .failure(let error): log(string: "Verification of \(contact.username) failed: \(error.localizedDescription)", type: .error) - contact.status = .verificationFailed + contact.authStatus = .verificationFailed do { try self.dbManager.saveContact(contact) @@ -74,7 +75,7 @@ extension Session { let hasPhone = contact.phone != nil guard hasEmail || hasPhone else { - ud.lookup(forUserId: contact.userId, resultClosure) + ud.lookup(forUserId: contact.id, resultClosure) return } @@ -90,10 +91,10 @@ extension Session { try ud.search(fact: fact, resultClosure) } catch { log(string: error.localizedDescription, type: .error) - contact.status = .verificationFailed + contact.authStatus = .verificationFailed do { - try self.dbManager.save(contact) + try self.dbManager.saveContact(contact) } catch { log(string: error.localizedDescription, type: .error) } @@ -103,7 +104,7 @@ extension Session { public func retryRequest(_ contact: Contact) throws { log(string: "Retrying to request a contact", type: .info) - client.bindings.add(contact.marshaled, from: myQR) { [weak self, contact] in + client.bindings.add(contact.marshaled!, from: myQR) { [weak self, contact] in var contact = contact guard let self = self else { return } @@ -111,13 +112,13 @@ extension Session { switch $0 { case .success: log(string: "Retrying to request a contact -- Success", type: .info) - contact.status = .requested + contact.authStatus = .requested case .failure(let error): log(string: "Retrying to request a contact -- Failed: \(error.localizedDescription)", type: .error) contact.createdAt = Date() } - _ = try self.dbManager.save(contact) + _ = try self.dbManager.saveContact(contact) } catch { log(string: error.localizedDescription, type: .error) } @@ -131,23 +132,23 @@ extension Session { var contactToOperate: Contact! - if contact.status == .requestFailed || contact.status == .confirmationFailed { + if contact.authStatus == .requestFailed || contact.authStatus == .confirmationFailed { contactToOperate = contact } else { guard (try? dbManager.fetch(.withUsername(contact.username)).first as Contact?) == nil else { throw NSError.create("This user has already been requested") } - contactToOperate = try dbManager.save(contact) + contactToOperate = try dbManager.saveContact(contact) } - guard contactToOperate.status != .confirmationFailed else { + guard contactToOperate.authStatus != .confirmationFailed else { contactToOperate.createdAt = Date() try confirm(contact) return } - contactToOperate.status = .requesting + contactToOperate.authStatus = .requesting let myself = client.bindings.meMarshalled( username!, @@ -155,77 +156,50 @@ extension Session { phone: isSharingPhone ? phone : nil ) - client.bindings.add(contactToOperate.marshaled, from: myself) { [weak self, contactToOperate] in + client.bindings.add(contactToOperate.marshaled!, from: myself) { [weak self, contactToOperate] in guard let self = self, var contactToOperate = contactToOperate else { return } - let safeName = contactToOperate.nickname ?? contactToOperate.username - let title = "\(safeName.prefix(2))...\(safeName.suffix(3))" do { switch $0 { case .success(let success): - contactToOperate.status = success ? .requested : .requestFailed - contactToOperate = try self.dbManager.save(contactToOperate) + contactToOperate.authStatus = success ? .requested : .requestFailed + contactToOperate = try self.dbManager.saveContact(contactToOperate) - log(string: "Successfully added \(title)", type: .info) case .failure(let error): - contactToOperate.status = .requestFailed + contactToOperate.authStatus = .requestFailed contactToOperate.createdAt = Date() - contactToOperate = try self.dbManager.save(contactToOperate) - - log(string: "Failed when adding \(title):\n\(error.localizedDescription)", type: .error) + contactToOperate = try self.dbManager.saveContact(contactToOperate) self.toastController.enqueueToast(model: .init( - title: Localized.Requests.Failed.toast(contactToOperate.nickname ?? contact.username), + title: Localized.Requests.Failed.toast(contactToOperate.nickname ?? contact.username!), color: Asset.accentDanger.color, leftImage: Asset.requestFailedToaster.image )) } } catch { - log(string: "Error adding \(title):\n\(error.localizedDescription)", type: .error) + print(error.localizedDescription) } } } public func confirm(_ contact: Contact) throws { var contact = contact - contact.status = .confirming - contact = try dbManager.save(contact) - - client.bindings.confirm(contact.marshaled) { [weak self] in - let safeName = contact.nickname ?? contact.username - let title = "\(safeName.prefix(2))...\(safeName.suffix(3))" + contact.authStatus = .confirming + contact = try dbManager.saveContact(contact) + client.bindings.confirm(contact.marshaled!) { [weak self] in switch $0 { case .success(let confirmed): contact.isRecent = true contact.createdAt = Date() - contact.status = confirmed ? .friend : .confirmationFailed - log(string: "Confirming request from \(title) = \(confirmed)", type: confirmed ? .info : .error) - case .failure(let error): - contact.status = .confirmationFailed - log(string: "Error confirming request from \(title):\n\(error.localizedDescription)", type: .error) - } - - _ = try? self?.dbManager.save(contact) - } - } - - public func find(by username: String) -> Contact? { - log(string: "Trying to find contact with username: \(username)", type: .info) + contact.authStatus = confirmed ? .friend : .confirmationFailed - do { - if let contact: Contact = try dbManager.fetch(.withUsername(username)).first { - log(string: "Found \(username)!", type: .info) - return contact - } else { - log(string: "No such contact with username: \(username)", type: .info) - return nil + case .failure: + contact.authStatus = .confirmationFailed } - } catch { - log(string: "Error trying to find a contact: \(error.localizedDescription)", type: .error) - } - return nil + _ = try? self?.dbManager.saveContact(contact) + } } public func deleteContact(_ contact: Contact) throws { @@ -235,7 +209,7 @@ extension Session { print("No pending transfer with this contact. Free to delete") } - try client.bindings.removeContact(contact.marshaled) - try dbManager.delete(contact) + try client.bindings.removeContact(contact.marshaled!) + try dbManager.deleteContact(contact) } } diff --git a/Sources/Integration/Session/Session+Group.swift b/Sources/Integration/Session/Session+Group.swift index 78670c9b..423c976c 100644 --- a/Sources/Integration/Session/Session+Group.swift +++ b/Sources/Integration/Session/Session+Group.swift @@ -1,4 +1,5 @@ import Models +import XXModels import Foundation public typealias GroupCompletion = (Result<(Group, [GroupMember]), Error>) -> Void @@ -7,24 +8,24 @@ extension Session { public func join(group: Group) throws { guard let manager = client.groupManager else { fatalError("A group manager was not created") } - try manager.join(group.serialize) + try manager.join(group.serialized) var group = group - group.status = .participating + group.authStatus = .participating scanStrangers {} - try dbManager.save(group) + try dbManager.saveGroup(group) } public func leave(group: Group) throws { guard let manager = client.groupManager else { fatalError("A group manager was not created") } - try manager.leave(group.groupId) - try dbManager.delete(group) + try manager.leave(group.id) + try dbManager.deleteGroup(group) } public func createGroup(name: String, welcome: String?, members: [Contact], _ completion: @escaping GroupCompletion) { guard let manager = client.groupManager else { fatalError("A group manager was not created") } let me = client.bindings.meMarshalled - let memberIds = members.map { $0.userId } + let memberIds = members.map { $0.id } manager.create(me: me, name: name, welcome: welcome, with: memberIds) { [weak self] in guard let self = self else { return } @@ -41,10 +42,10 @@ extension Session { @discardableResult func processGroupCreation(_ group: Group, memberIds: [Data], welcome: String?) -> [GroupMember] { - try! dbManager.save(group) + try! dbManager.saveGroup(group) if let welcome = welcome { - try! dbManager.save(GroupMessage(group: group, text: welcome, me: client.bindings.meMarshalled)) + try! dbManager.save(Message(group: group, text: welcome, me: client.bindings.meMarshalled)) } var members: [GroupMember] = [] @@ -54,7 +55,7 @@ extension Session { } let strangersOnGroup = memberIds - .filter { !members.map { $0.userId }.contains($0) } + .filter { !members.map { $0.contactId }.contains($0) } .filter { $0 != client.bindings.myId } if !strangersOnGroup.isEmpty { @@ -69,7 +70,7 @@ extension Session { } } - members.forEach { try! dbManager.save($0) } + members.forEach { try! dbManager.saveGroupMember($0) } if group.leader != client.bindings.meMarshalled, inappnotifications { DeviceFeedback.sound(.contactAdded) @@ -84,18 +85,8 @@ extension Session { // MARK: - GroupMessages extension Session { - public func delete(groupMessages: [Int64]) { - groupMessages.forEach { - do { - try dbManager.delete(GroupMessage.self, .id($0)) - } catch { - log(string: error.localizedDescription, type: .error) - } - } - } - public func send(_ payload: Payload, toGroup group: Group) { - var groupMessage = GroupMessage( + var message = Message( sender: client.bindings.meMarshalled, groupId: group.groupId, payload: payload, @@ -106,8 +97,8 @@ extension Session { ) do { - groupMessage = try dbManager.save(groupMessage) - send(groupMessage: groupMessage) + message = try dbManager.saveMessage(message) + send(message: message) } catch { log(string: error.localizedDescription, type: .error) } @@ -117,41 +108,41 @@ extension Session { guard var message: GroupMessage = try? dbManager.fetch(withId: id) else { return } message.timestamp = Date.asTimestamp message.status = .sending - send(groupMessage: try! dbManager.save(message)) + send(groupMessage: try! dbManager.saveMessage(message)) } - private func send(groupMessage: GroupMessage) { + private func send(message: Message) { guard let manager = client.groupManager else { fatalError("A group manager was not created") } - var groupMessage = groupMessage + var message = message DispatchQueue.global().async { [weak self] in guard let self = self else { return } - switch manager.send(groupMessage.payload.asData(), to: groupMessage.groupId) { + switch manager.send(message.payload.asData(), to: message.groupId) { case .success((let roundId, let uniqueId, let roundURL)): - groupMessage.roundURL = roundURL + message.roundURL = roundURL self.client.bindings.listenRound(id: Int(roundId)) { result in switch result { case .success(let succeeded): - groupMessage.uniqueId = uniqueId - groupMessage.status = succeeded ? .sent : .failed + message.uniqueId = uniqueId + message.status = succeeded ? .sent : .failed case .failure: - groupMessage.status = .failed + message.status = .failed } do { - try self.dbManager.save(groupMessage) + try self.dbManager.saveMessage(message) } catch { log(string: error.localizedDescription, type: .error) } } case .failure: - groupMessage.status = .failed + message.status = .sendingFailed } do { - try self.dbManager.save(groupMessage) + try self.dbManager.saveMessage(message) } catch { log(string: error.localizedDescription, type: .error) } @@ -209,20 +200,6 @@ extension Session { } } -private extension GroupMessage { - init(group: Group, text: String, me: Data) { - self.init( - sender: group.leader, - groupId: group.groupId, - payload: .init(text: text, reply: nil, attachment: nil), - unread: false, - timestamp: Date.asTimestamp, - uniqueId: nil, - status: group.leader == me ? .sent : .received - ) - } -} - private extension GroupMember { init(contact: Contact, group: Group) { self.init( diff --git a/Sources/Integration/Session/Session+UD.swift b/Sources/Integration/Session/Session+UD.swift index 82c1e427..57422a7d 100644 --- a/Sources/Integration/Session/Session+UD.swift +++ b/Sources/Integration/Session/Session+UD.swift @@ -1,4 +1,5 @@ import Models +import XXModels import Foundation extension Session { diff --git a/Sources/Integration/Session/Session.swift b/Sources/Integration/Session/Session.swift index 6c48b77c..0bad0077 100644 --- a/Sources/Integration/Session/Session.swift +++ b/Sources/Integration/Session/Session.swift @@ -229,15 +229,17 @@ public final class Session: SessionType { private func setupBindings() { client.requests - .sink { [unowned self] request in - if let _: Contact = try? dbManager.fetch(.withUserId(request.userId)).first { return } + .sink { [unowned self] in + if let _ = try? dbManager.fetchContacts(.init(id: [$0.id])).first { + return + } if self.inappnotifications { DeviceFeedback.sound(.contactAdded) DeviceFeedback.shake(.notification) } - verify(contact: request) + verify(contact: $0) }.store(in: &cancellables) client.requestsSent @@ -255,7 +257,7 @@ public final class Session: SessionType { /// TODO: Hold a record on the chat that this contact restored. /// var contact = $0 - contact.status = .friend + contact.authStatus = .friend _ = try? dbManager.saveContact(contact) }.store(in: &cancellables) @@ -284,31 +286,25 @@ public final class Session: SessionType { .sink { print($0) } .store(in: &cancellables) - client.groupMessages - .sink { [unowned self] in _ = try? dbManager.saveMessage($0) } - .store(in: &cancellables) - client.messages .sink { [unowned self] in - if var contact: Contact = try? dbManager.fetch(.withUserId($0.sender)).first { + if var contact = try? dbManager.fetchContacts(.init(id: [$0.senderId])).first { contact.isRecent = false - _ = try? dbManager.save(contact) + _ = try? dbManager.saveContact(contact) } - _ = try? dbManager.save($0) + _ = try? dbManager.saveMessage($0) }.store(in: &cancellables) client.network .sink { [unowned self] in networkMonitor.update($0) } .store(in: &cancellables) - client.incomingTransfers - .sink { [unowned self] in handle(incomingTransfer: $0) } - .store(in: &cancellables) - client.groupRequests .sink { [unowned self] request in - if let _: Group = try? dbManager.fetch(.withGroupId(request.0.groupId)).first { return } + if let _ = try? dbManager.fetchGroups(.init(id: [request.0.id])).first { + return + } DispatchQueue.global().async { [weak self] in self?.processGroupCreation(request.0, memberIds: request.1, welcome: request.2) @@ -317,14 +313,14 @@ public final class Session: SessionType { client.confirmations .sink { [unowned self] in - if var contact: Contact = try? dbManager.fetch(.withUserId($0.userId)).first { - contact.status = .friend + if var contact = try? dbManager.fetchContacts(.init(id: [$0.id])).first { + contact.authStatus = .friend contact.isRecent = true contact.createdAt = Date() _ = try? dbManager.saveContact(contact) toastController.enqueueToast(model: .init( - title: contact.nickname ?? contact.username, + title: contact.nickname ?? contact.username!, subtitle: Localized.Requests.Confirmations.toaster, leftImage: Asset.sharedSuccess.image )) diff --git a/Sources/Integration/Session/SessionType.swift b/Sources/Integration/Session/SessionType.swift index 0c5d6782..f2badbfa 100644 --- a/Sources/Integration/Session/SessionType.swift +++ b/Sources/Integration/Session/SessionType.swift @@ -1,5 +1,6 @@ import Models import Combine +import XXModels import Foundation public protocol SessionType { @@ -38,21 +39,14 @@ public protocol SessionType { // Messages - func readAll(from: Group) - func readAll(from: Contact) func retryMessage(_: Int64) func retryGroupMessage(_: Int64) - func deleteAll(from: Group) - func deleteAll(from: Contact) - func delete(messages: [Int64]) - func delete(groupMessages: [Int64]) func send(_: Payload, toContact: Contact) // Contacts func add(_: Contact) throws func confirm(_: Contact) throws - func find(by: String) -> Contact? func deleteContact(_: Contact) throws func retryRequest(_: Contact) throws diff --git a/Sources/Models/GroupChatInfo.swift b/Sources/Models/GroupChatInfo.swift index 9b39ff6d..e2d56675 100644 --- a/Sources/Models/GroupChatInfo.swift +++ b/Sources/Models/GroupChatInfo.swift @@ -1,22 +1,22 @@ -import Foundation - -public struct GroupChatInfo: Codable, Equatable, Hashable { - public enum Request { - case accepted - case fromGroup(Data) - } - - public var group: Group - public var members: [GroupMember] - public var lastMessage: GroupMessage? - - public init( - group: Group, - members: [GroupMember], - lastMessage: GroupMessage? = nil - ) { - self.group = group - self.members = members - self.lastMessage = lastMessage - } -} +//import Foundation +// +//public struct GroupChatInfo: Codable, Equatable, Hashable { +// public enum Request { +// case accepted +// case fromGroup(Data) +// } +// +// public var group: Group +// public var members: [GroupMember] +// public var lastMessage: GroupMessage? +// +// public init( +// group: Group, +// members: [GroupMember], +// lastMessage: GroupMessage? = nil +// ) { +// self.group = group +// self.members = members +// self.lastMessage = lastMessage +// } +//} diff --git a/Sources/Models/GroupMember.swift b/Sources/Models/GroupMember.swift index 25c619f3..c0f7123f 100644 --- a/Sources/Models/GroupMember.swift +++ b/Sources/Models/GroupMember.swift @@ -1,42 +1,42 @@ -import Foundation - -public struct GroupMember { - public enum Request { - case all - case strangers - case fromGroup(Data) - case withUserId(Data) - } - - public enum Status: Int64, Codable { - case usernameSet - case pendingUsername - } - - public var id: Int64? - public var userId: Data - public var groupId: Data - public var status: Status - public var username: String - public var photo: Data? - - public init( - id: Int64? = nil, - userId: Data, - groupId: Data, - status: Status, - username: String, - photo: Data? = nil - ) { - self.id = id - self.userId = userId - self.groupId = groupId - self.username = username - self.status = status - self.photo = photo - } -} - -extension GroupMember: Codable {} -extension GroupMember: Hashable {} -extension GroupMember: Equatable {} +//import Foundation +// +//public struct GroupMember { +// public enum Request { +// case all +// case strangers +// case fromGroup(Data) +// case withUserId(Data) +// } +// +// public enum Status: Int64, Codable { +// case usernameSet +// case pendingUsername +// } +// +// public var id: Int64? +// public var userId: Data +// public var groupId: Data +// public var status: Status +// public var username: String +// public var photo: Data? +// +// public init( +// id: Int64? = nil, +// userId: Data, +// groupId: Data, +// status: Status, +// username: String, +// photo: Data? = nil +// ) { +// self.id = id +// self.userId = userId +// self.groupId = groupId +// self.username = username +// self.status = status +// self.photo = photo +// } +//} +// +//extension GroupMember: Codable {} +//extension GroupMember: Hashable {} +//extension GroupMember: Equatable {} diff --git a/Sources/Models/GroupMessage.swift b/Sources/Models/GroupMessage.swift index ffdb6df4..771d4ceb 100644 --- a/Sources/Models/GroupMessage.swift +++ b/Sources/Models/GroupMessage.swift @@ -1,56 +1,56 @@ -import Foundation - -public struct GroupMessage: Codable, Equatable, Hashable { - public enum Request { - case withUniqueId(Data) - case id(Int64) - case sending - case fromGroup(Data) - case unreadsFromGroup(Data) - } - - public static var databaseTableName: String { "groupMessages" } - - public enum Status: Int64, Codable { - case sent - case read - case failed - case sending - case received - } - - public var id: Int64? - public var uniqueId: Data? - public var groupId: Data - public var sender: Data - public var roundId: Int64? - public var payload: Payload - public var status: Status - public var roundURL: String? - public var unread: Bool - public var timestamp: Int - - public init( - id: Int64? = nil, - sender: Data, - groupId: Data, - payload: Payload, - unread: Bool, - timestamp: Int = 0, - uniqueId: Data?, - status: Status, - roundId: Int64? = nil, - roundURL: String? = nil - ) { - self.id = id - self.sender = sender - self.groupId = groupId - self.payload = payload - self.unread = unread - self.timestamp = timestamp - self.uniqueId = uniqueId - self.status = status - self.roundId = roundId - self.roundURL = roundURL - } -} +//import Foundation +// +//public struct GroupMessage: Codable, Equatable, Hashable { +// public enum Request { +// case withUniqueId(Data) +// case id(Int64) +// case sending +// case fromGroup(Data) +// case unreadsFromGroup(Data) +// } +// +// public static var databaseTableName: String { "groupMessages" } +// +// public enum Status: Int64, Codable { +// case sent +// case read +// case failed +// case sending +// case received +// } +// +// public var id: Int64? +// public var uniqueId: Data? +// public var groupId: Data +// public var sender: Data +// public var roundId: Int64? +// public var payload: Payload +// public var status: Status +// public var roundURL: String? +// public var unread: Bool +// public var timestamp: Int +// +// public init( +// id: Int64? = nil, +// sender: Data, +// groupId: Data, +// payload: Payload, +// unread: Bool, +// timestamp: Int = 0, +// uniqueId: Data?, +// status: Status, +// roundId: Int64? = nil, +// roundURL: String? = nil +// ) { +// self.id = id +// self.sender = sender +// self.groupId = groupId +// self.payload = payload +// self.unread = unread +// self.timestamp = timestamp +// self.uniqueId = uniqueId +// self.status = status +// self.roundId = roundId +// self.roundURL = roundURL +// } +//} diff --git a/Sources/Models/Message.swift b/Sources/Models/Message.swift index fec18587..77ae89db 100644 --- a/Sources/Models/Message.swift +++ b/Sources/Models/Message.swift @@ -1,70 +1,70 @@ -import Foundation -import DifferenceKit - -public struct Message: Codable, Equatable, Hashable { - public enum Request { - case sending - case withUniqueId(Data) - case withId(Int64) - case sendingAttachment - case withContact(Data) - case unreadsFromContactId(Data) - case latestOnesFromContactIds([Data]) - } - - public enum Status: Int64, Codable { - case read - case sent - case sending - case sendingAttachment - case receivingAttachment - case received - case failedToSend - case timedOut - } - - public var id: Int64? - public var unread: Bool - public let sender: Data - public var roundURL: String? - public var report: Data? - public var status: Status - public let receiver: Data - public var timestamp: Int - public var uniqueId: Data? - public var payload: Payload - public static var databaseTableName: String { "messages" } - - public init ( - sender: Data, - receiver: Data, - payload: Payload, - unread: Bool, - timestamp: Int, - uniqueId: Data?, - status: Status, - roundURL: String? = nil - ) { - self.sender = sender - self.unread = unread - self.status = status - self.payload = payload - self.receiver = receiver - self.uniqueId = uniqueId - self.timestamp = timestamp - self.roundURL = roundURL - } -} - -public extension Message.Status { - var canReply: Bool { - switch self { - case .sent, .received, .read: - return true - default: - return false - } - } -} - -extension Message: Differentiable {} +//import Foundation +//import DifferenceKit +// +//public struct Message: Codable, Equatable, Hashable { +// public enum Request { +// case sending +// case withUniqueId(Data) +// case withId(Int64) +// case sendingAttachment +// case withContact(Data) +// case unreadsFromContactId(Data) +// case latestOnesFromContactIds([Data]) +// } +// +// public enum Status: Int64, Codable { +// case read +// case sent +// case sending +// case sendingAttachment +// case receivingAttachment +// case received +// case failedToSend +// case timedOut +// } +// +// public var id: Int64? +// public var unread: Bool +// public let sender: Data +// public var roundURL: String? +// public var report: Data? +// public var status: Status +// public let receiver: Data +// public var timestamp: Int +// public var uniqueId: Data? +// public var payload: Payload +// public static var databaseTableName: String { "messages" } +// +// public init ( +// sender: Data, +// receiver: Data, +// payload: Payload, +// unread: Bool, +// timestamp: Int, +// uniqueId: Data?, +// status: Status, +// roundURL: String? = nil +// ) { +// self.sender = sender +// self.unread = unread +// self.status = status +// self.payload = payload +// self.receiver = receiver +// self.uniqueId = uniqueId +// self.timestamp = timestamp +// self.roundURL = roundURL +// } +//} +// +//public extension Message.Status { +// var canReply: Bool { +// switch self { +// case .sent, .received, .read: +// return true +// default: +// return false +// } +// } +//} +// +//extension Message: Differentiable {} -- GitLab