mv-experiment #1
|
@ -1,4 +1,5 @@
|
||||||
import Combine
|
import Combine
|
||||||
|
import Foundation
|
||||||
import GRDB
|
import GRDB
|
||||||
import Martin
|
import Martin
|
||||||
|
|
||||||
|
@ -12,66 +13,66 @@ final class ClientMartinMessagesManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleClientMessage(_ martinMessage: MessageModule.MessageReceived) {
|
private func handleClientMessage(_ received: MessageModule.MessageReceived) {
|
||||||
|
let message = received.message
|
||||||
|
let chat = received.chat
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
print("---")
|
print("---")
|
||||||
print("Message received: \(martinMessage)")
|
print("Message received: \(message)")
|
||||||
|
print("In chat: \(chat)")
|
||||||
print("---")
|
print("---")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check that the message type is supported
|
||||||
|
let chatTypes: [StanzaType] = [.chat, .groupchat]
|
||||||
|
guard let mType = message.type, chatTypes.contains(mType) else {
|
||||||
|
#if DEBUG
|
||||||
|
print("Unsupported message type: \(message.type?.rawValue ?? "nil")")
|
||||||
|
#endif
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type
|
||||||
|
let type = MessageType(rawValue: message.type?.rawValue ?? "") ?? .chat
|
||||||
|
|
||||||
|
// Content type
|
||||||
|
var contentType: MessageContentType = .text
|
||||||
|
if message.hints.contains(.noStore) {
|
||||||
|
contentType = .typing
|
||||||
|
}
|
||||||
|
|
||||||
|
// From/To
|
||||||
|
let from = message.from?.bareJid.stringValue ?? ""
|
||||||
|
let to = message.to?.bareJid.stringValue
|
||||||
|
|
||||||
|
// Extract date or set current
|
||||||
|
var date = Date()
|
||||||
|
if let timestampStr = message.attribute("archived_date"), let timeInterval = TimeInterval(timestampStr) {
|
||||||
|
date = Date(timeIntervalSince1970: timeInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Msg
|
||||||
|
let msg = Message(
|
||||||
|
id: message.id ?? UUID().uuidString,
|
||||||
|
type: type,
|
||||||
|
date: date,
|
||||||
|
contentType: contentType,
|
||||||
|
status: .sent,
|
||||||
|
from: from,
|
||||||
|
to: to,
|
||||||
|
body: message.body,
|
||||||
|
subject: message.subject,
|
||||||
|
thread: message.thread,
|
||||||
|
oobUrl: message.oob
|
||||||
|
)
|
||||||
|
|
||||||
|
// Save message
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
try await msg.save()
|
||||||
|
} catch {
|
||||||
|
logIt(.error, "Error saving message: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// extension Message {
|
|
||||||
// static func map(from martinMessage: Martin.Message) -> Message? {
|
|
||||||
// #if DEBUG
|
|
||||||
// print("---")
|
|
||||||
// print("Message received: \(martinMessage)")
|
|
||||||
// print("---")
|
|
||||||
// #endif
|
|
||||||
//
|
|
||||||
// // Check that the message type is supported
|
|
||||||
// let chatTypes: [StanzaType] = [.chat, .groupchat]
|
|
||||||
// guard let mType = martinMessage.type, chatTypes.contains(mType) else {
|
|
||||||
// #if DEBUG
|
|
||||||
// print("Unsupported message type: \(martinMessage.type?.rawValue ?? "nil")")
|
|
||||||
// #endif
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Type
|
|
||||||
// let type = MessageType(rawValue: martinMessage.type?.rawValue ?? "") ?? .chat
|
|
||||||
//
|
|
||||||
// // Content type
|
|
||||||
// var contentType: MessageContentType = .text
|
|
||||||
// if martinMessage.hints.contains(.noStore) {
|
|
||||||
// contentType = .typing
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // From/To
|
|
||||||
// let from = martinMessage.from?.bareJid.stringValue ?? ""
|
|
||||||
// let to = martinMessage.to?.bareJid.stringValue
|
|
||||||
//
|
|
||||||
// // Extract date or set current
|
|
||||||
// var date = Date()
|
|
||||||
// if let timestampStr = martinMessage.attribute("archived_date"), let timeInterval = TimeInterval(timestampStr) {
|
|
||||||
// date = Date(timeIntervalSince1970: timeInterval)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Msg
|
|
||||||
// let msg = Message(
|
|
||||||
// id: martinMessage.id ?? UUID().uuidString,
|
|
||||||
// type: type,
|
|
||||||
// date: date,
|
|
||||||
// contentType: contentType,
|
|
||||||
// status: .sent,
|
|
||||||
// from: from,
|
|
||||||
// to: to,
|
|
||||||
// body: martinMessage.body,
|
|
||||||
// subject: martinMessage.subject,
|
|
||||||
// thread: martinMessage.thread,
|
|
||||||
// oobUrl: martinMessage.oob
|
|
||||||
// )
|
|
||||||
// return msg
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
|
@ -36,3 +36,11 @@ struct Message: DBStorable, Equatable {
|
||||||
let thread: String?
|
let thread: String?
|
||||||
let oobUrl: String?
|
let oobUrl: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Message {
|
||||||
|
func save() async throws {
|
||||||
|
try await Database.shared.dbQueue.write { db in
|
||||||
|
try self.insert(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,57 @@
|
||||||
|
import Collections
|
||||||
|
import Combine
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import GRDB
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
final class ConversationStore: ObservableObject {
|
final class ConversationStore: ObservableObject {
|
||||||
@Published private(set) var roster: Roster
|
@Published private(set) var messages: Deque<Message> = []
|
||||||
@Published private(set) var messages: [String] = []
|
private(set) var roster: Roster
|
||||||
@Published private(set) var test = true
|
|
||||||
|
|
||||||
private let client: Client
|
private let client: Client
|
||||||
|
private let blockSize = Const.messagesPageSize
|
||||||
|
private let messagesMax = Const.messagesMaxSize
|
||||||
|
|
||||||
|
private var messagesObservation: AnyDatabaseCancellable
|
||||||
|
|
||||||
init(roster: Roster, client: Client) {
|
init(roster: Roster, client: Client) {
|
||||||
self.client = client
|
self.client = client
|
||||||
self.roster = roster
|
self.roster = roster
|
||||||
|
|
||||||
|
// observe change messages in database
|
||||||
|
messagesObservation = DatabaseRegionObservation(tracking: Message.all()).start(in: Database.shared.dbQueue) { _ in
|
||||||
|
// Handle error
|
||||||
|
} onChange: { _ in
|
||||||
|
print("Messages were changed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ConversationStore {
|
||||||
|
func loadMoreBackward() async {
|
||||||
|
// guard let lastMessage = messages.last else { return }
|
||||||
|
// let messages = await fetchBlock(lastMessage.date, nil)
|
||||||
|
// self.messages.append(contentsOf: messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadMoreForward() async {
|
||||||
|
// guard let firstMessage = messages.first else { return }
|
||||||
|
// let messages = await fetchBlock(nil, firstMessage.date)
|
||||||
|
// self.messages.insert(contentsOf: messages, at: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ConversationStore {
|
||||||
|
private func fetchBlock(_ beforeDate: Date?, _ afterDate: Date?) async -> [Message] {
|
||||||
|
print(beforeDate, afterDate)
|
||||||
|
return []
|
||||||
|
// let messages = await client.fetchMessages()
|
||||||
|
// self.messages.append(contentsOf: messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func cutMessages() {
|
||||||
|
// if messages.count > messagesMax {
|
||||||
|
// messages.removeFirst(messages.count - messagesMax)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,6 @@ enum Const {
|
||||||
static let mamRequestDaysLength = 30
|
static let mamRequestDaysLength = 30
|
||||||
|
|
||||||
// Limits for messages pagination
|
// Limits for messages pagination
|
||||||
static let messagesPageMin = 20
|
static let messagesPageSize = 20 // size for block requesting
|
||||||
static let messagesPageMax = 100
|
static let messagesMaxSize = 100 // total messages in memory
|
||||||
}
|
}
|
||||||
|
|
10
project.yml
10
project.yml
|
@ -5,6 +5,12 @@ options:
|
||||||
postGenCommand: swiftgen
|
postGenCommand: swiftgen
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
Collections:
|
||||||
|
url: https://github.com/apple/swift-collections
|
||||||
|
majorVersion: 1.1.2
|
||||||
|
Algorithms:
|
||||||
|
url: https://github.com/apple/swift-algorithms
|
||||||
|
majorVersion: 1.2.0
|
||||||
SwiftfulRouting:
|
SwiftfulRouting:
|
||||||
url: https://github.com/SwiftfulThinking/SwiftfulRouting
|
url: https://github.com/SwiftfulThinking/SwiftfulRouting
|
||||||
majorVersion: 5.3.5
|
majorVersion: 5.3.5
|
||||||
|
@ -77,6 +83,10 @@ targets:
|
||||||
- sdk: Security.framework
|
- sdk: Security.framework
|
||||||
# - framework: Lib/WebRTC.xcframework
|
# - framework: Lib/WebRTC.xcframework
|
||||||
# - target: Engine
|
# - target: Engine
|
||||||
|
- package: Collections
|
||||||
|
link: true
|
||||||
|
- package: Algorithms
|
||||||
|
link: true
|
||||||
- package: SwiftfulRouting
|
- package: SwiftfulRouting
|
||||||
link: true
|
link: true
|
||||||
- package: MartinOMEMO
|
- package: MartinOMEMO
|
||||||
|
|
Loading…
Reference in a new issue