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 rostersCancellable: AnyCancellable?
|
||||||
|
|
||||||
private var rosterManager = ClientMartinRosterManager()
|
private var rosterManager = ClientMartinRosterManager()
|
||||||
|
private var chatsManager = ClientMartinChatsManager()
|
||||||
|
|
||||||
init(credentials: Credentials) {
|
init(credentials: Credentials) {
|
||||||
self.credentials = credentials
|
self.credentials = credentials
|
||||||
state = credentials.isActive ? .enabled(.disconnected) : .disabled
|
state = credentials.isActive ? .enabled(.disconnected) : .disabled
|
||||||
connection = Self.prepareConnection(credentials, rosterManager)
|
connection = Self.prepareConnection(credentials, rosterManager, chatsManager)
|
||||||
connectionCancellable = connection.$state
|
connectionCancellable = connection.$state
|
||||||
.sink { [weak self] state in
|
.sink { [weak self] state in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
@ -92,7 +93,7 @@ extension Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
private 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()
|
let client = XMPPClient()
|
||||||
|
|
||||||
// register modules
|
// register modules
|
||||||
|
@ -109,7 +110,7 @@ private extension Client {
|
||||||
client.modulesManager.register(PresenceModule())
|
client.modulesManager.register(PresenceModule())
|
||||||
|
|
||||||
// client.modulesManager.register(PubSubModule())
|
// client.modulesManager.register(PubSubModule())
|
||||||
// client.modulesManager.register(MessageModule(chatManager: manager))
|
client.modulesManager.register(MessageModule(chatManager: chat))
|
||||||
// client.modulesManager.register(MessageArchiveManagementModule())
|
// client.modulesManager.register(MessageArchiveManagementModule())
|
||||||
|
|
||||||
// client.modulesManager.register(MessageCarbonsModule())
|
// 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.primaryKey(["bareJid", "contactBareJid"], onConflict: .replace)
|
||||||
table.column("locallyDeleted", .boolean).notNull().defaults(to: false)
|
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
|
// return migrator
|
||||||
|
|
Loading…
Reference in a new issue