From 1b8337db39fdc860bf2bf7c55cec0f92d8335792 Mon Sep 17 00:00:00 2001
From: Bruno Muniz Azevedo Filho <bruno@elixxir.io>
Date: Wed, 22 Jun 2022 01:28:33 -0300
Subject: [PATCH] Cleaned Session+Chats.swift

---
 .../Interfaces/BindingsInterface.swift        |   2 +-
 Sources/Integration/Mocks/BindingsMock.swift  |   2 +-
 .../Integration/Session/Session+Chat.swift    | 365 +++++++++---------
 .../Integration/Session/Session+Group.swift   |  43 ++-
 4 files changed, 209 insertions(+), 203 deletions(-)

diff --git a/Sources/Integration/Interfaces/BindingsInterface.swift b/Sources/Integration/Interfaces/BindingsInterface.swift
index f56ebccb..b2eef8f9 100644
--- a/Sources/Integration/Interfaces/BindingsInterface.swift
+++ b/Sources/Integration/Interfaces/BindingsInterface.swift
@@ -158,7 +158,7 @@ public protocol BindingsInterface {
 
     func listenGroupRequests(
         _: @escaping (Group, [Data], String?) -> Void,
-        groupMessages: @escaping (GroupMessage) -> Void
+        groupMessages: @escaping (Message) -> Void
     ) throws -> GroupManagerInterface?
 
     func listenNetworkUpdates(_: @escaping (Bool) -> Void)
diff --git a/Sources/Integration/Mocks/BindingsMock.swift b/Sources/Integration/Mocks/BindingsMock.swift
index 901ff8e6..cf886b5d 100644
--- a/Sources/Integration/Mocks/BindingsMock.swift
+++ b/Sources/Integration/Mocks/BindingsMock.swift
@@ -163,7 +163,7 @@ public final class BindingsMock: BindingsInterface {
 
     public func listenGroupRequests(
         _ groupRequests: @escaping (Group, [Data], String?) -> Void,
-        groupMessages: @escaping (GroupMessage) -> Void
+        groupMessages: @escaping (Message) -> Void
     ) throws -> GroupManagerInterface? {
         groupRequestsSubject
             .sink { groupRequests($0, [], nil) }
diff --git a/Sources/Integration/Session/Session+Chat.swift b/Sources/Integration/Session/Session+Chat.swift
index 814df83d..a76c9b3f 100644
--- a/Sources/Integration/Session/Session+Chat.swift
+++ b/Sources/Integration/Session/Session+Chat.swift
@@ -28,13 +28,17 @@ extension Session {
 
     public func send(_ payload: Payload, toContact contact: Contact) {
         var message = Message(
-            sender: client.bindings.meMarshalled,
-            receiver: contact.id,
-            payload: payload,
-            unread: false,
-            timestamp: Date.asTimestamp,
-            uniqueId: nil,
-            status: .sending
+            networkId: nil,
+            senderId: client.bindings.meMarshalled,
+            recipientId: contact.id,
+            groupId: nil,
+            date: Date(),
+            status: .sending,
+            isUnread: false,
+            text: payload.text,
+            replyMessageId: payload.reply?.messageId,
+            roundURL: nil,
+            fileTransferId: nil
         )
 
         do {
@@ -46,29 +50,30 @@ extension Session {
     }
 
     public func retryMessage(_ id: Int64) {
-        guard var message: Message = try? dbManager.fetch(withId: id) else { return }
-        message.timestamp = Date.asTimestamp
-        message.status = .sending
+        if var message = try? dbManager.fetchMessages(.init(id: [id])).first {
+            message.status = .sending
+            message.date = Date()
 
-        do {
-            message = try dbManager.saveMessage(message)
-            send(message: message)
-        } catch {
-            log(string: error.localizedDescription, type: .error)
+            do {
+                message = try dbManager.saveMessage(message)
+                send(message: message)
+            } catch {
+                print(error.localizedDescription)
+            }
         }
     }
 
     private func send(message: Message) {
         var message = message
 
-        if let _ = message.payload.attachment {
-            sendAttachment(message: message)
-            return
-        }
+//        if let _ = message.payload.attachment {
+//            sendAttachment(message: message)
+//            return
+//        }
 
         DispatchQueue.global().async { [weak self] in
             guard let self = self else { return }
-            switch self.client.bindings.send(message.payload.asData(), to: message.receiver) {
+            switch self.client.bindings.send(message.text.data(using: .utf8)!, to: message.recipientId!) {
             case .success(let report):
                 message.roundURL = report.roundURL
 
@@ -77,21 +82,21 @@ extension Session {
                     case .success(let status):
                         switch status {
                         case .failed:
-                            message.status = .failedToSend
+                            message.status = .sendingFailed
                         case .sent:
                             message.status = .sent
                         case .timedout:
-                            message.status = .timedOut
+                            message.status = .sendingTimedOut
                         }
                     case .failure:
-                        message.status = .failedToSend
+                        message.status = .sendingFailed
                     }
 
-                    message.uniqueId = report.uniqueId
-                    message.timestamp = Int(report.timestamp)
+                    message.networkId = report.uniqueId
+                    message.date = Date.fromTimestamp(Int(report.timestamp))
                     DispatchQueue.main.async {
                         do {
-                            _ = try self.dbManager.save(message)
+                            _ = try self.dbManager.saveMessage(message)
                         } catch {
                             log(string: error.localizedDescription, type: .error)
                         }
@@ -112,158 +117,158 @@ extension Session {
         }
     }
 
-    private func sendAttachment(message: Message) {
-        guard let manager = client.transferManager else { fatalError("A transfer manager was not created") }
-
-        var message = message
-        let attachment = message.payload.attachment!
-
-        DispatchQueue.global().async { [weak self] in
-            guard let self = self else { return }
-
-            do {
-                let tid = try manager.uploadFile(attachment, to: message.receiver) { completed, send, arrived, total, error in
-                    if completed {
-                        self.endTransferFrom(message: message)
-                        message.status = .sent
-                        message.payload.attachment?.progress = 1.0
-                        log(string: "FT Up finished", type: .info)
-                    } else {
-                        if let error = error {
-                            log(string: error.localizedDescription, type: .error)
-                            message.status = .failedToSend
-                        } else {
-                            let progress = Float(arrived)/Float(total)
-                            message.payload.attachment?.progress = progress
-                            log(string: "FT Up: \(progress)", type: .crumbs)
-                        }
-                    }
-
-                    do {
-                        _ = try self.dbManager.save(message) // If it fails here, means the chat was cleared.
-                    } catch {
-                        log(string: error.localizedDescription, type: .error)
-                    }
-                }
-
-                let transfer = FileTransfer(
-                    tid: tid,
-                    contact: message.receiver,
-                    fileName: attachment.name,
-                    fileType: attachment._extension.written,
-                    isIncoming: false
-                )
-
-                message.payload.attachment?.transferId = tid
-                message.status = .sending
-
-                do {
-                    _ = try self.dbManager.saveMessage(message)
-                    _ = try self.dbManager.save(transfer)
-                } catch {
-                    log(string: error.localizedDescription, type: .error)
-                }
-            } catch {
-                message.status = .sendingFailed
-                log(string: error.localizedDescription, type: .error)
-
-                do {
-                    _ = try self.dbManager.saveMessage(message)
-                } catch let otherError {
-                    log(string: otherError.localizedDescription, type: .error)
-                }
-            }
-        }
-    }
-
-    private func endTransferFrom(message: Message) {
-        guard let manager = client.transferManager else { fatalError("A transfer manager was not created") }
-        guard let tid = message.payload.attachment?.transferId else { fatalError("Tried to finish a transfer that had no TID") }
-
-        do {
-            try manager.endTransferUpload(with: tid)
-
-            if let transfer: FileTransfer = try? dbManager.fetch(.withTID(tid)).first {
-                try dbManager.delete(transfer)
-            }
-        } catch {
-            log(string: error.localizedDescription, type: .error)
-        }
-    }
-
-    func handle(incomingTransfer transfer: FileTransfer) {
-        guard let manager = client.transferManager else { fatalError("A transfer manager was not created") }
-
-        let fileExtension: Attachment.Extension = transfer.fileType == "m4a" ? .audio : .image
-        let name = "\(Date.asTimestamp)_\(transfer.fileName)"
-
-        var fakeContent: Data
-
-        if fileExtension == .image {
-            fakeContent = Asset.transferImagePlaceholder.image.jpegData(compressionQuality: 0.1)!
-        } else {
-            fakeContent = FileManager.dummyAudio()
-        }
-
-        let attachment = Attachment(name: name, data: fakeContent, transferId: transfer.tid, _extension: fileExtension)
-
-        var message = Message(
-            sender: transfer.contact,
-            receiver: client.bindings.meMarshalled,
-            payload: .init(text: "Sent you a \(fileExtension.writtenExtended)", reply: nil, attachment: attachment),
-            unread: true,
-            timestamp: Date.asTimestamp,
-            uniqueId: nil,
-            status: .receivingAttachment
-        )
-
-        do {
-            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)
-            return
-        }
-
-        log(string: "FT Down starting", type: .info)
-
-        try! manager.listenDownloadFromTransfer(with: transfer.tid) { completed, arrived, total, error in
-            if let error = error {
-                fatalError(error.localizedDescription)
-            }
-
-            if completed {
-                log(string: "FT Down finished", type: .info)
-
-                guard let rawFile = try? manager.downloadFileFromTransfer(with: transfer.tid) else {
-                    log(string: "Received finalized transfer, file was nil. Ignoring...", type: .error)
-                    return
-                }
-
-                try! FileManager.store(data: rawFile, name: name, type: fileExtension.written)
-                var realAttachment = Attachment(name: name, data: rawFile, transferId: transfer.tid, _extension: fileExtension)
-                realAttachment.progress = 1.0
-                message.payload = .init(text: "Sent you a \(transfer.fileType)", reply: nil, attachment: realAttachment)
-                message.status = .received
-
-                if let toDelete: FileTransfer = try? self.dbManager.fetch(.withTID(transfer.tid)).first {
-                    do {
-                        try self.dbManager.delete(toDelete)
-                    } catch {
-                        log(string: error.localizedDescription, type: .error)
-                    }
-                }
-            } else {
-                let progress = Float(arrived)/Float(total)
-                log(string: "FT Down: \(progress)", type: .crumbs)
-                message.payload.attachment?.progress = progress
-            }
-
-            do {
-                try self.dbManager.save(message) // If it fails here, means the chat was cleared.
-            } catch {
-                log(string: "Failed to update message model from an incoming transfer. Probably chat was cleared: \(error.localizedDescription)", type: .error)
-            }
-        }
-    }
+//    private func sendAttachment(message: Message) {
+//        guard let manager = client.transferManager else { fatalError("A transfer manager was not created") }
+//
+//        var message = message
+//        let attachment = message.payload.attachment!
+//
+//        DispatchQueue.global().async { [weak self] in
+//            guard let self = self else { return }
+//
+//            do {
+//                let tid = try manager.uploadFile(attachment, to: message.receiver) { completed, send, arrived, total, error in
+//                    if completed {
+//                        self.endTransferFrom(message: message)
+//                        message.status = .sent
+//                        message.payload.attachment?.progress = 1.0
+//                        log(string: "FT Up finished", type: .info)
+//                    } else {
+//                        if let error = error {
+//                            log(string: error.localizedDescription, type: .error)
+//                            message.status = .failedToSend
+//                        } else {
+//                            let progress = Float(arrived)/Float(total)
+//                            message.payload.attachment?.progress = progress
+//                            log(string: "FT Up: \(progress)", type: .crumbs)
+//                        }
+//                    }
+//
+//                    do {
+//                        _ = try self.dbManager.save(message) // If it fails here, means the chat was cleared.
+//                    } catch {
+//                        log(string: error.localizedDescription, type: .error)
+//                    }
+//                }
+//
+//                let transfer = FileTransfer(
+//                    tid: tid,
+//                    contact: message.receiver,
+//                    fileName: attachment.name,
+//                    fileType: attachment._extension.written,
+//                    isIncoming: false
+//                )
+//
+//                message.payload.attachment?.transferId = tid
+//                message.status = .sending
+//
+//                do {
+//                    _ = try self.dbManager.saveMessage(message)
+//                    _ = try self.dbManager.save(transfer)
+//                } catch {
+//                    log(string: error.localizedDescription, type: .error)
+//                }
+//            } catch {
+//                message.status = .sendingFailed
+//                log(string: error.localizedDescription, type: .error)
+//
+//                do {
+//                    _ = try self.dbManager.saveMessage(message)
+//                } catch let otherError {
+//                    log(string: otherError.localizedDescription, type: .error)
+//                }
+//            }
+//        }
+//    }
+//
+//    private func endTransferFrom(message: Message) {
+//        guard let manager = client.transferManager else { fatalError("A transfer manager was not created") }
+//        guard let tid = message.payload.attachment?.transferId else { fatalError("Tried to finish a transfer that had no TID") }
+//
+//        do {
+//            try manager.endTransferUpload(with: tid)
+//
+//            if let transfer: FileTransfer = try? dbManager.fetch(.withTID(tid)).first {
+//                try dbManager.delete(transfer)
+//            }
+//        } catch {
+//            log(string: error.localizedDescription, type: .error)
+//        }
+//    }
+//
+//    func handle(incomingTransfer transfer: FileTransfer) {
+//        guard let manager = client.transferManager else { fatalError("A transfer manager was not created") }
+//
+//        let fileExtension: Attachment.Extension = transfer.fileType == "m4a" ? .audio : .image
+//        let name = "\(Date.asTimestamp)_\(transfer.fileName)"
+//
+//        var fakeContent: Data
+//
+//        if fileExtension == .image {
+//            fakeContent = Asset.transferImagePlaceholder.image.jpegData(compressionQuality: 0.1)!
+//        } else {
+//            fakeContent = FileManager.dummyAudio()
+//        }
+//
+//        let attachment = Attachment(name: name, data: fakeContent, transferId: transfer.tid, _extension: fileExtension)
+//
+//        var message = Message(
+//            sender: transfer.contact,
+//            receiver: client.bindings.meMarshalled,
+//            payload: .init(text: "Sent you a \(fileExtension.writtenExtended)", reply: nil, attachment: attachment),
+//            unread: true,
+//            timestamp: Date.asTimestamp,
+//            uniqueId: nil,
+//            status: .receivingAttachment
+//        )
+//
+//        do {
+//            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)
+//            return
+//        }
+//
+//        log(string: "FT Down starting", type: .info)
+//
+//        try! manager.listenDownloadFromTransfer(with: transfer.tid) { completed, arrived, total, error in
+//            if let error = error {
+//                fatalError(error.localizedDescription)
+//            }
+//
+//            if completed {
+//                log(string: "FT Down finished", type: .info)
+//
+//                guard let rawFile = try? manager.downloadFileFromTransfer(with: transfer.tid) else {
+//                    log(string: "Received finalized transfer, file was nil. Ignoring...", type: .error)
+//                    return
+//                }
+//
+//                try! FileManager.store(data: rawFile, name: name, type: fileExtension.written)
+//                var realAttachment = Attachment(name: name, data: rawFile, transferId: transfer.tid, _extension: fileExtension)
+//                realAttachment.progress = 1.0
+//                message.payload = .init(text: "Sent you a \(transfer.fileType)", reply: nil, attachment: realAttachment)
+//                message.status = .received
+//
+//                if let toDelete: FileTransfer = try? self.dbManager.fetch(.withTID(transfer.tid)).first {
+//                    do {
+//                        try self.dbManager.delete(toDelete)
+//                    } catch {
+//                        log(string: error.localizedDescription, type: .error)
+//                    }
+//                }
+//            } else {
+//                let progress = Float(arrived)/Float(total)
+//                log(string: "FT Down: \(progress)", type: .crumbs)
+//                message.payload.attachment?.progress = progress
+//            }
+//
+//            do {
+//                try self.dbManager.save(message) // If it fails here, means the chat was cleared.
+//            } catch {
+//                log(string: "Failed to update message model from an incoming transfer. Probably chat was cleared: \(error.localizedDescription)", type: .error)
+//            }
+//        }
+//    }
 }
diff --git a/Sources/Integration/Session/Session+Group.swift b/Sources/Integration/Session/Session+Group.swift
index 423c976c..7829a545 100644
--- a/Sources/Integration/Session/Session+Group.swift
+++ b/Sources/Integration/Session/Session+Group.swift
@@ -44,10 +44,6 @@ extension Session {
     func processGroupCreation(_ group: Group, memberIds: [Data], welcome: String?) -> [GroupMember] {
         try! dbManager.saveGroup(group)
 
-        if let welcome = welcome {
-            try! dbManager.save(Message(group: group, text: welcome, me: client.bindings.meMarshalled))
-        }
-
         var members: [GroupMember] = []
 
         if let contactsOnGroup: [Contact] = try? dbManager.fetch(.withUserIds(memberIds)) {
@@ -72,12 +68,29 @@ extension Session {
 
         members.forEach { try! dbManager.saveGroupMember($0) }
 
-        if group.leader != client.bindings.meMarshalled, inappnotifications {
+        if group.leaderId != client.bindings.meMarshalled, inappnotifications {
             DeviceFeedback.sound(.contactAdded)
             DeviceFeedback.shake(.notification)
         }
 
         scanStrangers {}
+
+        if let welcome = welcome {
+            _ = try? dbManager.saveMessage(.init(
+                networkId: nil,
+                senderId: group.leaderId,
+                recipientId: client.bindings.meMarshalled,
+                groupId: group.id,
+                date: Date(),
+                status: .received,
+                isUnread: true,
+                text: welcome,
+                replyMessageId: nil,
+                roundURL: nil,
+                fileTransferId: nil
+            ))
+        }
+
         return members
     }
 }
@@ -118,17 +131,17 @@ extension Session {
         DispatchQueue.global().async { [weak self] in
             guard let self = self else { return }
 
-            switch manager.send(message.payload.asData(), to: message.groupId) {
+            switch manager.send(message.text.data(using: .utf8)!, to: message.groupId!) {
             case .success((let roundId, let uniqueId, let roundURL)):
                 message.roundURL = roundURL
 
                 self.client.bindings.listenRound(id: Int(roundId)) { result in
                     switch result {
                     case .success(let succeeded):
-                        message.uniqueId = uniqueId
-                        message.status = succeeded ? .sent : .failed
+                        message.networkId = uniqueId
+                        message.status = succeeded ? .sent : .sendingFailed
                     case .failure:
-                        message.status = .failed
+                        message.status = .sendingFailed
                     }
 
                     do {
@@ -199,15 +212,3 @@ extension Session {
         }
     }
 }
-
-private extension GroupMember {
-    init(contact: Contact, group: Group) {
-        self.init(
-            userId: contact.userId,
-            groupId: group.groupId,
-            status: .usernameSet,
-            username: contact.username,
-            photo: contact.photo
-        )
-    }
-}
-- 
GitLab