wip
This commit is contained in:
parent
dc993147f5
commit
1b0a62db32
|
@ -23,6 +23,7 @@ final class AppState: ObservableObject {
|
|||
private let accountsService: AccountsService
|
||||
private let rostersService: RostersService
|
||||
private let chatService: ChatsService
|
||||
private var conversationService: ConversationService?
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
// publishers
|
||||
|
@ -102,11 +103,23 @@ extension AppState {
|
|||
}
|
||||
|
||||
// Chats
|
||||
func startChat(_: Chat) {
|
||||
// chatService.startChat(chat)
|
||||
func startChat(_ chat: Chat) {
|
||||
let client = xmppService.getClient(for: chat.account)
|
||||
let roster = rostersService.getRoster(ownerJID: chat.account, contactJID: chat.participant)
|
||||
let account = accountsService.getAccount(jid: chat.account)
|
||||
if let client, let roster, let account {
|
||||
conversationService = ConversationService(account: account, chat: chat, roster: roster, db: Database()._db, client: client)
|
||||
flow = .chat
|
||||
}
|
||||
}
|
||||
|
||||
func startChat(_: Roster) {
|
||||
// chatService.startChat(roster)
|
||||
func startChat(_ roster: Roster) {
|
||||
let client = xmppService.getClient(for: roster.bareJid)
|
||||
let account = accountsService.getAccount(jid: roster.bareJid)
|
||||
let chat = chatService.getChat(roster.bareJid, roster.contactBareJid)
|
||||
if let client, let chat, let account {
|
||||
conversationService = ConversationService(account: account, chat: chat, roster: roster, db: Database()._db, client: client)
|
||||
flow = .chat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ final class AccountsService: ObservableObject {
|
|||
}
|
||||
|
||||
// MARK: - Account actions
|
||||
func getAccount(jid: String) -> Account? {
|
||||
accounts.first(where: { $0.bareJid == jid })
|
||||
}
|
||||
|
||||
func addAccount(jid: String, password: String) {
|
||||
guard let db = database else { return }
|
||||
let account = Account(bareJid: jid, pass: password, isActive: true)
|
||||
|
|
|
@ -27,40 +27,26 @@ final class ChatsService: ObservableObject {
|
|||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
// MARK: - Chats actions
|
||||
// func makeChatActive(_ chat: Chat) {
|
||||
// guard let client = xmppClients.first(where: { $0.connectionConfiguration.userJid.stringValue == chat.account }) else { return }
|
||||
// guard let roster = rosters.first(where: { $0.bareJid == chat.account && $0.contactBareJid == chat.participant }) else { return }
|
||||
// guard let account = accounts.first(where: { $0.bareJid == chat.account }) else { return }
|
||||
// activeChat = ConversationState(account: account, chat: chat, roster: roster, dbService: dbService, client: client)
|
||||
// }
|
||||
//
|
||||
// func makeChatActive(_ roster: Roster) {
|
||||
// guard let client = xmppClients.first(where: { $0.connectionConfiguration.userJid.stringValue == roster.bareJid }) else { return }
|
||||
// let chat = getChat(roster.bareJid, roster.contactBareJid)
|
||||
// guard let account = accounts.first(where: { $0.bareJid == chat.account }) else { return }
|
||||
// activeChat = ConversationState(account: account, chat: chat, roster: roster, dbService: dbService, client: client)
|
||||
// }
|
||||
//
|
||||
// // get existing chat or create a new one
|
||||
// private func getChat(_ account: String, _ participant: String) -> Chat {
|
||||
// if let chat = chats.first(where: { $0.account == account && $0.participant == participant }) {
|
||||
// return chat
|
||||
// } else {
|
||||
// let chat = Chat(
|
||||
// id: UUID().uuidString,
|
||||
// account: account,
|
||||
// participant: participant,
|
||||
// type: .chat
|
||||
// )
|
||||
// do {
|
||||
// try dbService._db.write { db in
|
||||
// try chat.save(db)
|
||||
// }
|
||||
// } catch {
|
||||
// logIt(.error, "Failed to create chat: \(error)")
|
||||
// }
|
||||
// return chat
|
||||
// }
|
||||
// }
|
||||
// get existing chat or create a new one
|
||||
func getChat(_ account: String, _ participant: String) -> Chat? {
|
||||
guard let db = database else { return nil }
|
||||
if let chat = chats.first(where: { $0.account == account && $0.participant == participant }) {
|
||||
return chat
|
||||
} else {
|
||||
let chat = Chat(
|
||||
id: UUID().uuidString,
|
||||
account: account,
|
||||
participant: participant,
|
||||
type: .chat
|
||||
)
|
||||
do {
|
||||
try db.write { db in
|
||||
try chat.save(db)
|
||||
}
|
||||
} catch {
|
||||
logIt(.error, "Failed to create chat: \(error)")
|
||||
}
|
||||
return chat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,22 +3,22 @@ import Foundation
|
|||
import GRDB
|
||||
import Martin
|
||||
|
||||
final class ConversationState: ObservableObject {
|
||||
final class ConversationService: ObservableObject {
|
||||
private var account: Account
|
||||
private var chat: Chat
|
||||
private var roster: Roster
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
weak var dbService: Database?
|
||||
weak var database: DatabaseQueue?
|
||||
weak var client: XMPPClient?
|
||||
|
||||
@Published var messages: [Message] = []
|
||||
|
||||
init(account: Account, chat: Chat, roster: Roster, dbService: Database, client: XMPPClient) {
|
||||
init(account: Account, chat: Chat, roster: Roster, db: DatabaseQueue, client: XMPPClient) {
|
||||
self.account = account
|
||||
self.chat = chat
|
||||
self.roster = roster
|
||||
self.dbService = dbService
|
||||
database = db
|
||||
self.client = client
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
import GRDB
|
||||
import Martin
|
||||
|
||||
final class XMPPMessageService {
|
||||
final class MessageService {
|
||||
func processMessage(_ message: Martin.Message, _ chat: Martin.ChatProtocol) {
|
||||
print("---Message received: \(message.body) from \(message.from)\n--Chat: \(chat)")
|
||||
}
|
|
@ -35,6 +35,10 @@ final class RostersService: ObservableObject {
|
|||
}
|
||||
|
||||
// MARK: - Roster actions
|
||||
func getRoster(ownerJID: String, contactJID: String) -> Roster? {
|
||||
rosters.first(where: { $0.bareJid == ownerJID && $0.contactBareJid == contactJID })
|
||||
}
|
||||
|
||||
func addRoster(ownerJID: String, contactJID: String, name: String? = nil, groups: [String] = [], completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let service = xmppService, let client = service.clients.first(where: { $0.connectionConfiguration.userJid.stringValue == ownerJID }) else {
|
||||
return completion(.failure(XMPPError.item_not_found))
|
||||
|
|
|
@ -73,4 +73,8 @@ final class XMPPService: ObservableObject {
|
|||
_ = client.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
func getClient(for jid: String) -> XMPPClient? {
|
||||
clients.first { $0.connectionConfiguration.userJid.stringValue == jid }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
import Combine
|
||||
import Foundation
|
||||
import GRDB
|
||||
import Martin
|
||||
|
||||
protocol MartinsManager: Martin.RosterManager & Martin.ChatManager {}
|
||||
|
||||
final class XMPPService: ObservableObject {
|
||||
private let manager: MartinsManager
|
||||
|
||||
@Published private(set) var clients: [XMPPClient] = []
|
||||
|
||||
init(manager: MartinsManager) {
|
||||
self.manager = manager
|
||||
}
|
||||
|
||||
func updateClients(for accounts: [Account]) {
|
||||
// get simple diff
|
||||
let forAdd = accounts
|
||||
.filter { !self.clients.map { $0.connectionConfiguration.userJid.stringValue }.contains($0.bareJid) }
|
||||
let forRemove = clients
|
||||
.map { $0.connectionConfiguration.userJid.stringValue }
|
||||
.filter { !accounts.map { $0.bareJid }.contains($0) }
|
||||
|
||||
// init and add clients
|
||||
for account in forAdd {
|
||||
let client = makeClient(for: account, with: manager)
|
||||
clients.append(client)
|
||||
// doClientSubscription(for: client)
|
||||
client.login()
|
||||
}
|
||||
|
||||
// remove clients
|
||||
for jid in forRemove {
|
||||
deinitClient(jid: jid)
|
||||
}
|
||||
}
|
||||
|
||||
private func makeClient(for account: Account, with manager: MartinsManager) -> XMPPClient {
|
||||
let client = XMPPClient()
|
||||
|
||||
// register modules
|
||||
// core modules RFC 6120
|
||||
client.modulesManager.register(StreamFeaturesModule())
|
||||
client.modulesManager.register(SaslModule())
|
||||
client.modulesManager.register(AuthModule())
|
||||
client.modulesManager.register(SessionEstablishmentModule())
|
||||
client.modulesManager.register(ResourceBinderModule())
|
||||
client.modulesManager.register(DiscoveryModule(identity: .init(category: "client", type: "iOS", name: Const.appName)))
|
||||
|
||||
// messaging modules RFC 6121
|
||||
client.modulesManager.register(RosterModule(rosterManager: manager))
|
||||
client.modulesManager.register(PresenceModule())
|
||||
|
||||
client.modulesManager.register(PubSubModule())
|
||||
client.modulesManager.register(MessageModule(chatManager: manager))
|
||||
client.modulesManager.register(MessageCarbonsModule())
|
||||
client.modulesManager.register(MessageArchiveManagementModule())
|
||||
|
||||
// extensions
|
||||
client.modulesManager.register(SoftwareVersionModule())
|
||||
client.modulesManager.register(PingModule())
|
||||
client.connectionConfiguration.userJid = .init(account.bareJid)
|
||||
client.connectionConfiguration.credentials = .password(password: account.pass)
|
||||
|
||||
// add client to clients
|
||||
return client
|
||||
}
|
||||
|
||||
func deinitClient(jid: String) {
|
||||
if let index = clients.firstIndex(where: { $0.connectionConfiguration.userJid.stringValue == jid }) {
|
||||
let client = clients.remove(at: index)
|
||||
_ = client.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue