wip
This commit is contained in:
parent
7a722e200c
commit
e30ec562cb
|
@ -30,9 +30,16 @@ struct TestScreen: View {
|
||||||
.background { Color.blue.opacity(0.4) }
|
.background { Color.blue.opacity(0.4) }
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
// cls.requestRoster()
|
cls.addContact(jidStr: "asdadad@asdfsdf.df")
|
||||||
} label: {
|
} label: {
|
||||||
Text("Request roster")
|
Text("Add contact")
|
||||||
|
.padding()
|
||||||
|
.background { Color.blue.opacity(0.4) }
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
cls.deleteContact(jidStr: "asdadad@asdfsdf.df")
|
||||||
|
} label: {
|
||||||
|
Text("Remove contact")
|
||||||
.padding()
|
.padding()
|
||||||
.background { Color.blue.opacity(0.4) }
|
.background { Color.blue.opacity(0.4) }
|
||||||
}
|
}
|
||||||
|
@ -51,9 +58,8 @@ struct TestScreen: View {
|
||||||
final class TestStorage: XMPPStorage {
|
final class TestStorage: XMPPStorage {
|
||||||
private var roster: [String: Data] = [:]
|
private var roster: [String: Data] = [:]
|
||||||
|
|
||||||
func getCredentialsByUUID(_ uuid: UUID) async -> Credentials? {
|
func getCredentialsByUUID(_: UUID) async -> Credentials? {
|
||||||
print(uuid)
|
["password": pass]
|
||||||
return ["password": pass]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteRoster(jid: JID) async {
|
func deleteRoster(jid: JID) async {
|
||||||
|
@ -66,7 +72,10 @@ final class TestStorage: XMPPStorage {
|
||||||
|
|
||||||
func setRoster(jid: JID, roster: Data) async {
|
func setRoster(jid: JID, roster: Data) async {
|
||||||
self.roster[jid.bare] = roster
|
self.roster[jid.bare] = roster
|
||||||
print("updated")
|
|
||||||
|
if let arr = try? JSONDecoder().decode([XMLElement].self, from: roster) {
|
||||||
|
print("ROSTER: \(arr)\n\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ extension XMPPClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteRosterItem(jidStr: String) {
|
func deleteContact(jidStr: String) {
|
||||||
Task {
|
Task {
|
||||||
await fire(.deleteRosterItem(jidStr: jidStr))
|
await fire(.deleteRosterItem(jidStr: jidStr))
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum RosterSubsriptionType: String {
|
||||||
|
|
||||||
// Roster is a "transparent" structure
|
// Roster is a "transparent" structure
|
||||||
// which is just wrap xml item around
|
// which is just wrap xml item around
|
||||||
|
// TODO: Add groups and annotattions!
|
||||||
struct RosterItem: Identifiable, Equatable {
|
struct RosterItem: Identifiable, Equatable {
|
||||||
let owner: String
|
let owner: String
|
||||||
let wrapped: XMLElement
|
let wrapped: XMLElement
|
||||||
|
@ -66,5 +67,3 @@ struct RosterItem: Identifiable, Equatable {
|
||||||
rhs.id == lhs.id && rhs.wrapped == lhs.wrapped
|
rhs.id == lhs.id && rhs.wrapped == lhs.wrapped
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add groups and annotattions!
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ final class RosterModule: XmppModule {
|
||||||
let id = "Roseter module"
|
let id = "Roseter module"
|
||||||
|
|
||||||
private weak var storage: (any XMPPStorage)?
|
private weak var storage: (any XMPPStorage)?
|
||||||
|
private var fullReqId = ""
|
||||||
|
|
||||||
init(_ storage: any XMPPStorage) {
|
init(_ storage: any XMPPStorage) {
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
|
@ -26,6 +27,7 @@ final class RosterModule: XmppModule {
|
||||||
payload: XMLElement(name: "query", xmlns: "jabber:iq:roster", attributes: [:], content: nil, nodes: [])
|
payload: XMLElement(name: "query", xmlns: "jabber:iq:roster", attributes: [:], content: nil, nodes: [])
|
||||||
)
|
)
|
||||||
if let req {
|
if let req {
|
||||||
|
fullReqId = req.id ?? "???"
|
||||||
return .stanzaOutbound(req)
|
return .stanzaOutbound(req)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -38,6 +40,12 @@ final class RosterModule: XmppModule {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case .addRosterItem(let jidStr):
|
||||||
|
return updRoster(state: state, target: jidStr, remove: false)
|
||||||
|
|
||||||
|
case .deleteRosterItem(let jidStr):
|
||||||
|
return updRoster(state: state, target: jidStr, remove: true)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -45,7 +53,7 @@ final class RosterModule: XmppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension RosterModule {
|
private extension RosterModule {
|
||||||
func processRoster(state: ClientState, stanza: Stanza) async -> Event? {
|
private func processRoster(state: ClientState, stanza: Stanza) async -> Event? {
|
||||||
// get inner query
|
// get inner query
|
||||||
guard let query = stanza.wrapped.nodes.first(where: { $0.name == "query" })
|
guard let query = stanza.wrapped.nodes.first(where: { $0.name == "query" })
|
||||||
else { return nil }
|
else { return nil }
|
||||||
|
@ -68,21 +76,47 @@ private extension RosterModule {
|
||||||
await storage?.setRoster(jid: state.jid, roster: data)
|
await storage?.setRoster(jid: state.jid, roster: data)
|
||||||
return .rosterUpdated
|
return .rosterUpdated
|
||||||
|
|
||||||
// process get response (.result from server)
|
// process .result from server
|
||||||
} else if stanza.type == .iq(.get) {
|
} else if stanza.type == .iq(.result) {
|
||||||
|
// process full list
|
||||||
|
if stanza.id == fullReqId {
|
||||||
let items = query.nodes.filter { $0.name == "item" }
|
let items = query.nodes.filter { $0.name == "item" }
|
||||||
guard let data = try? JSONEncoder().encode(items) else { return nil }
|
guard let data = try? JSONEncoder().encode(items) else { return nil }
|
||||||
await storage?.setRoster(jid: state.jid, roster: data)
|
await storage?.setRoster(jid: state.jid, roster: data)
|
||||||
|
|
||||||
|
// process changed item
|
||||||
|
} else {
|
||||||
|
// TODO: Fix removing item!
|
||||||
|
// guard
|
||||||
|
// let item = query.nodes.first(where: { $0.name == "item" }),
|
||||||
|
// let new = RosterItem(wrap: item, owner: state.jid)
|
||||||
|
// else { return nil }
|
||||||
|
// existItems = existItems.filter { $0.jid != new.jid }
|
||||||
|
// if new.subsription != .remove {
|
||||||
|
// existItems.append(new)
|
||||||
|
// } else {
|
||||||
|
// print("REMOVED!!!")
|
||||||
|
// }
|
||||||
|
// guard let data = try? JSONEncoder().encode(existItems.map { $0.wrapped }) else { return nil }
|
||||||
|
// await storage?.setRoster(jid: state.jid, roster: data)
|
||||||
|
}
|
||||||
return .rosterUpdated
|
return .rosterUpdated
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// <iq to='testmon3@test.anal.company/TwtWkVOZ3liz' type='result' id='7l899q9r'>
|
private func updRoster(state: ClientState, target: String, remove: Bool) -> Event? {
|
||||||
// <query ver='27' xmlns='jabber:iq:roster'>
|
var attributes = ["jid": target]
|
||||||
// <item jid='fmodf@conversations.im' subscription='both' xmlns='jabber:iq:roster'/>
|
if remove {
|
||||||
// <item subscription='to' jid='testmon4@test.anal.company' xmlns='jabber:iq:roster'/>
|
attributes["subcription"] = "remove"
|
||||||
// </query>
|
}
|
||||||
// </iq>
|
let item = XMLElement(name: "item", xmlns: "jabber:iq:roster", attributes: attributes, content: nil, nodes: [])
|
||||||
|
let query = XMLElement(name: "query", xmlns: "jabber:iq:roster", attributes: [:], content: nil, nodes: [item])
|
||||||
|
if let req = Stanza.iqSet(from: state.jid.full, payload: query) {
|
||||||
|
return .stanzaOutbound(req)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue