diff --git a/ConversationsClassic/AppCore/Database/Database+Martin.swift b/ConversationsClassic/AppCore/Database/Database+Martin.swift index 38cc515..3a52e93 100644 --- a/ConversationsClassic/AppCore/Database/Database+Martin.swift +++ b/ConversationsClassic/AppCore/Database/Database+Martin.swift @@ -2,8 +2,8 @@ import Foundation import GRDB import Martin -extension Database: MartinsManager { - // MARK: - Martin's roster manager +// MARK: - Martin's roster manager +extension Database: Martin.RosterManager { func clear(for context: Martin.Context) { print("Clearing roster for context: \(context)") do { @@ -151,8 +151,10 @@ extension Database: MartinsManager { func initialize(context _: Martin.Context) {} func deinitialize(context _: Martin.Context) {} +} - // MARK: - Martin's chats manager +// MARK: - Martin's chats manager +extension Database: Martin.ChatManager { func chats(for context: Martin.Context) -> [any Martin.ChatProtocol] { do { let chats: [Chat] = try _db.read { db in @@ -220,3 +222,52 @@ extension Database: MartinsManager { return false } } + +// MARK: - Martin's rooms manager +extension Database: Martin.RoomManager { + func rooms(for _: Martin.Context) -> [any Martin.RoomProtocol] { + [] + } + + func room(for _: Martin.Context, with _: Martin.BareJID) -> (any Martin.RoomProtocol)? { + nil + } + + func createRoom(for _: Martin.Context, with _: Martin.BareJID, nickname _: String, password _: String?) -> (any Martin.RoomProtocol)? { + nil + } + + func close(room _: any Martin.RoomProtocol) -> Bool { + false + } +} + +// MARK: - Martin's channels manager +extension Database: Martin.ChannelManager { + func channels(for _: Martin.Context) -> [any Martin.ChannelProtocol] { + [] + // do { + // let channels: [Channel] = try _db.read { db in + // try Channel.filter(Column("account") == context.userBareJid.stringValue).fetchAll(db) + // } + // return channels.map { channel in + // Martin.ChannelBase(context: context, channelJid: channel.channel, participantId: , nickname: , state: ) + // } + // } catch { + // logIt(.error, "Error fetching channels: \(error.localizedDescription)") + // return [] + // } + } + + func createChannel(for _: Martin.Context, with _: Martin.BareJID, participantId _: String, nick _: String?, state _: Martin.ChannelState) -> Martin.ConversationCreateResult { + .none + } + + func channel(for _: Martin.Context, with _: Martin.BareJID) -> (any Martin.ChannelProtocol)? { + nil + } + + func close(channel _: any Martin.ChannelProtocol) -> Bool { + false + } +} diff --git a/ConversationsClassic/AppCore/Database/Database+Migrations.swift b/ConversationsClassic/AppCore/Database/Database+Migrations.swift index 7b0c2d6..d68af45 100644 --- a/ConversationsClassic/AppCore/Database/Database+Migrations.swift +++ b/ConversationsClassic/AppCore/Database/Database+Migrations.swift @@ -66,6 +66,21 @@ extension Database { } } + // 2nd migration - channels/rooms + migrator.registerMigration("Add channels/rooms") { db in + // channels + try db.create(table: "channels", options: [.ifNotExists]) { table in + table.column("id", .text).notNull().primaryKey().unique(onConflict: .replace) + table.column("account", .text).notNull() + table.column("channel", .text).notNull() + } + + // rooms + // try db.create(table: "rooms", options: [.ifNotExists]) { table in + // table.column("id", .text).notNull().primaryKey().unique(onConflict: .replace) + // } + } + // return migrator return migrator }() diff --git a/ConversationsClassic/AppCore/Models/Channel.swift b/ConversationsClassic/AppCore/Models/Channel.swift new file mode 100644 index 0000000..9c8275f --- /dev/null +++ b/ConversationsClassic/AppCore/Models/Channel.swift @@ -0,0 +1,15 @@ +import Foundation +import GRDB +import Martin +import SwiftUI + +// MARK: - Account +struct Channel: DBStorable { + var id: String + var account: String + var channel: String +} + +extension Channel { + static let channelTableName = "channels" +} diff --git a/ConversationsClassic/AppCore/Models/Room.swift b/ConversationsClassic/AppCore/Models/Room.swift new file mode 100644 index 0000000..b72cae6 --- /dev/null +++ b/ConversationsClassic/AppCore/Models/Room.swift @@ -0,0 +1,13 @@ +import Foundation +import GRDB +import Martin +import SwiftUI + +// MARK: - Account +struct Room: DBStorable { + var id: String +} + +extension Room { + static let roomTableName = "rooms" +} diff --git a/ConversationsClassic/AppCore/XMPP/XMPPService.swift b/ConversationsClassic/AppCore/XMPP/XMPPService.swift index 87d09d6..4f50cf1 100644 --- a/ConversationsClassic/AppCore/XMPP/XMPPService.swift +++ b/ConversationsClassic/AppCore/XMPP/XMPPService.swift @@ -3,15 +3,18 @@ import Foundation import GRDB import Martin -protocol MartinsManager: Martin.RosterManager & Martin.ChatManager {} +protocol MartinsManager: Martin.RosterManager & Martin.ChatManager & Martin.ChannelManager & Martin.RoomManager {} final class XMPPService: ObservableObject { private let manager: MartinsManager + private let clientStatePublisher = PassthroughSubject<(XMPPClient, XMPPClient.State), Never>() - private let clientMessagesPublisher = PassthroughSubject<(XMPPClient, Martin.Message), Never>() - private let clientFeaturesPublisher = PassthroughSubject<(XMPPClient, [String]), Never>() private var clientStateCancellables: Set = [] + + private let clientMessagesPublisher = PassthroughSubject<(XMPPClient, Martin.Message), Never>() private var clientMessagesCancellables: Set = [] + + private let clientFeaturesPublisher = PassthroughSubject<(XMPPClient, [String]), Never>() private var clientFeaturesCancellables: Set = [] @Published private(set) var clients: [XMPPClient] = [] @@ -130,6 +133,12 @@ final class XMPPService: ObservableObject { client.connectionConfiguration.userJid = .init(account.bareJid) client.connectionConfiguration.credentials = .password(password: account.pass) + // channels + client.modulesManager.register(MixModule(channelManager: manager)) + + // group chats + // client.modulesManager.register(MucModule(roomManager: manager)) + // add client to clients return client }