mv-experiment #1
75
ConversationsClassic/AppData/Client/Client+MartinChats.swift
Normal file
75
ConversationsClassic/AppData/Client/Client+MartinChats.swift
Normal file
|
@ -0,0 +1,75 @@
|
|||
import Foundation
|
||||
import GRDB
|
||||
import Martin
|
||||
|
||||
final class ClientMartinChatsManager: Martin.ChatManager {
|
||||
func chats(for context: Martin.Context) -> [any Martin.ChatProtocol] {
|
||||
do {
|
||||
let chats: [Chat] = try Database.shared.dbQueue.read { db in
|
||||
try Chat.filter(Column("account") == context.userBareJid.stringValue).fetchAll(db)
|
||||
}
|
||||
return chats.map { chat in
|
||||
Martin.ChatBase(context: context, jid: BareJID(chat.participant))
|
||||
}
|
||||
} catch {
|
||||
logIt(.error, "Error fetching chats: \(error.localizedDescription)")
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
func chat(for context: Martin.Context, with: Martin.BareJID) -> (any Martin.ChatProtocol)? {
|
||||
do {
|
||||
let chat: Chat? = try Database.shared.dbQueue.read { db in
|
||||
try Chat
|
||||
.filter(Column("account") == context.userBareJid.stringValue)
|
||||
.filter(Column("participant") == with.stringValue)
|
||||
.fetchOne(db)
|
||||
}
|
||||
if chat != nil {
|
||||
return Martin.ChatBase(context: context, jid: with)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
logIt(.error, "Error fetching chat: \(error.localizedDescription)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func createChat(for context: Martin.Context, with: Martin.BareJID) -> (any Martin.ChatProtocol)? {
|
||||
do {
|
||||
let chat: Chat? = try Database.shared.dbQueue.read { db in
|
||||
try Chat
|
||||
.filter(Column("account") == context.userBareJid.stringValue)
|
||||
.filter(Column("participant") == with.stringValue)
|
||||
.fetchOne(db)
|
||||
}
|
||||
if chat != nil {
|
||||
return Martin.ChatBase(context: context, jid: with)
|
||||
} else {
|
||||
let chat = Chat(
|
||||
id: UUID().uuidString,
|
||||
account: context.userBareJid.stringValue,
|
||||
participant: with.stringValue,
|
||||
type: .chat
|
||||
)
|
||||
try Database.shared.dbQueue.write { db in
|
||||
try chat.save(db)
|
||||
}
|
||||
return Martin.ChatBase(context: context, jid: with)
|
||||
}
|
||||
} catch {
|
||||
logIt(.error, "Error fetching chat: \(error.localizedDescription)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func close(chat: any Martin.ChatProtocol) -> Bool {
|
||||
// not used in Martin library for now
|
||||
print("Closing chat: \(chat)")
|
||||
return false
|
||||
}
|
||||
|
||||
func initialize(context _: Martin.Context) {}
|
||||
func deinitialize(context _: Martin.Context) {}
|
||||
}
|
|
@ -23,11 +23,12 @@ final class Client: ObservableObject {
|
|||
private var rostersCancellable: AnyCancellable?
|
||||
|
||||
private var rosterManager = ClientMartinRosterManager()
|
||||
private var chatsManager = ClientMartinChatsManager()
|
||||
|
||||
init(credentials: Credentials) {
|
||||
self.credentials = credentials
|
||||
state = credentials.isActive ? .enabled(.disconnected) : .disabled
|
||||
connection = Self.prepareConnection(credentials, rosterManager)
|
||||
connection = Self.prepareConnection(credentials, rosterManager, chatsManager)
|
||||
connectionCancellable = connection.$state
|
||||
.sink { [weak self] state in
|
||||
guard let self = self else { return }
|
||||
|
@ -92,7 +93,7 @@ extension Client {
|
|||
}
|
||||
|
||||
private extension Client {
|
||||
static func prepareConnection(_ credentials: Credentials, _ roster: RosterManager) -> XMPPClient {
|
||||
static func prepareConnection(_ credentials: Credentials, _ roster: RosterManager, _ chat: ChatManager) -> XMPPClient {
|
||||
let client = XMPPClient()
|
||||
|
||||
// register modules
|
||||
|
@ -109,7 +110,7 @@ private extension Client {
|
|||
client.modulesManager.register(PresenceModule())
|
||||
|
||||
// client.modulesManager.register(PubSubModule())
|
||||
// client.modulesManager.register(MessageModule(chatManager: manager))
|
||||
client.modulesManager.register(MessageModule(chatManager: chat))
|
||||
// client.modulesManager.register(MessageArchiveManagementModule())
|
||||
|
||||
// client.modulesManager.register(MessageCarbonsModule())
|
||||
|
|
19
ConversationsClassic/AppData/Model/Chat.swift
Normal file
19
ConversationsClassic/AppData/Model/Chat.swift
Normal file
|
@ -0,0 +1,19 @@
|
|||
import Foundation
|
||||
import GRDB
|
||||
|
||||
enum ConversationType: Int, Codable, DatabaseValueConvertible {
|
||||
case chat = 0
|
||||
case room = 1
|
||||
case channel = 2
|
||||
}
|
||||
|
||||
struct Chat: DBStorable {
|
||||
static let databaseTableName = "chats"
|
||||
|
||||
var id: String
|
||||
var account: String
|
||||
var participant: String
|
||||
var type: ConversationType
|
||||
}
|
||||
|
||||
extension Chat: Equatable {}
|
|
@ -34,6 +34,14 @@ extension Database {
|
|||
table.primaryKey(["bareJid", "contactBareJid"], onConflict: .replace)
|
||||
table.column("locallyDeleted", .boolean).notNull().defaults(to: false)
|
||||
}
|
||||
|
||||
// chats
|
||||
try db.create(table: "chats", options: [.ifNotExists]) { table in
|
||||
table.column("id", .text).notNull().primaryKey().unique(onConflict: .replace)
|
||||
table.column("account", .text).notNull()
|
||||
table.column("participant", .text).notNull()
|
||||
table.column("type", .integer).notNull()
|
||||
}
|
||||
}
|
||||
|
||||
// return migrator
|
||||
|
|
Loading…
Reference in a new issue