wip
This commit is contained in:
parent
8b6273b573
commit
ced4175906
|
@ -118,7 +118,7 @@ final class RosterModule: XmppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
// process stanza
|
// process stanza
|
||||||
return await processInbound(stanza: stanza)
|
return await processInbound(state: state, stanza: stanza)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -130,47 +130,93 @@ final class RosterModule: XmppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension RosterModule {
|
private extension RosterModule {
|
||||||
func processInbound(stanza: Stanza) async -> Event? {
|
func processInbound(state: ClientState, stanza: Stanza) async -> Event? {
|
||||||
switch stanza.type {
|
switch stanza.type {
|
||||||
|
// "set" type stanza from server is just "push", so change roster accordingly
|
||||||
case .iq(.set):
|
case .iq(.set):
|
||||||
return nil
|
// sanity check
|
||||||
|
if stanza.wrapped.attributes["to"] != state.jid.bare {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
case .iq(.error):
|
// get exists roster items
|
||||||
return nil
|
var existItems: [RosterItem] = []
|
||||||
|
if let data = await storage?.getRoster(jid: state.jid), let decoded = try? JSONDecoder().decode([XMLElement].self, from: data) {
|
||||||
|
existItems = decoded.compactMap { RosterItem(wrap: $0, owner: state.jid) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// get item from stanza
|
||||||
|
let xmlItem = stanza.wrapped
|
||||||
|
.nodes
|
||||||
|
.first(where: { $0.name == "query" })?
|
||||||
|
.nodes
|
||||||
|
.first(where: { $0.name == "item" })
|
||||||
|
guard let xmlItem, let item = RosterItem(wrap: xmlItem, owner: state.jid) else { return nil }
|
||||||
|
|
||||||
|
// filter out exists items
|
||||||
|
existItems = existItems.filter { $0.id != item.id }
|
||||||
|
|
||||||
|
// append updated/new item (if it not "removed")
|
||||||
|
if item.subsription != .remove {
|
||||||
|
existItems.append(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// save roster
|
||||||
|
guard let data = try? JSONEncoder().encode(existItems.map { $0.wrapped }) else { return nil }
|
||||||
|
await storage?.setRoster(jid: state.jid, roster: data)
|
||||||
|
return .rosterUpdated
|
||||||
|
|
||||||
|
// the "result" is an answer from one of our "set", or initial roster request
|
||||||
case .iq(.result):
|
case .iq(.result):
|
||||||
|
// get request stanza from registry
|
||||||
|
guard let respId = stanza.id, let req = await registry.deuque(for: respId) else { return nil }
|
||||||
|
|
||||||
|
// get exists roster items
|
||||||
|
var existItems: [RosterItem] = []
|
||||||
|
if let data = await storage?.getRoster(jid: state.jid), let decoded = try? JSONDecoder().decode([XMLElement].self, from: data) {
|
||||||
|
existItems = decoded.compactMap { RosterItem(wrap: $0, owner: state.jid) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform changes based on stanza request type
|
||||||
|
switch req.type {
|
||||||
|
// for simple roster request
|
||||||
|
case .iq(.get):
|
||||||
|
// get items from response
|
||||||
|
let stanzaItems = stanza.wrapped
|
||||||
|
.nodes
|
||||||
|
.first(where: { $0.name == "query" })?
|
||||||
|
.nodes
|
||||||
|
.filter { $0.name == "item" }
|
||||||
|
.compactMap { RosterItem(wrap: $0, owner: state.jid) } ?? []
|
||||||
|
let stanzaItemsIds = stanzaItems.map { $0.id }
|
||||||
|
|
||||||
|
// filter out exists items and append updated
|
||||||
|
existItems = existItems.filter { !stanzaItemsIds.contains($0.id) }
|
||||||
|
existItems.append(contentsOf: stanzaItems)
|
||||||
|
|
||||||
|
// save roster
|
||||||
|
guard let data = try? JSONEncoder().encode(existItems.map { $0.wrapped }) else { return nil }
|
||||||
|
await storage?.setRoster(jid: state.jid, roster: data)
|
||||||
|
return .rosterUpdated
|
||||||
|
|
||||||
|
// for result of one of our request
|
||||||
|
case .iq(.set):
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// append items from requested roster
|
||||||
|
return nil
|
||||||
|
|
||||||
|
// TODO: add error handling here
|
||||||
|
case .iq(.error):
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// get items from stanza
|
|
||||||
// var items: [XMLElement] = []
|
|
||||||
// switch stanza.type {
|
|
||||||
// case .iq(.set):
|
|
||||||
// break
|
|
||||||
// // return await processSet(state: state, stanza: stanza)
|
|
||||||
//
|
|
||||||
// case .iq(.result):
|
|
||||||
// let stanzaItems = stanza.wrapped
|
|
||||||
// .nodes
|
|
||||||
// .first(where: { $0.name == "query" })?
|
|
||||||
// .nodes
|
|
||||||
// .filter { $0.name == "item" } ?? []
|
|
||||||
// items.append(contentsOf: stanzaItems)
|
|
||||||
//
|
|
||||||
// case .iq(.error):
|
|
||||||
// // handle errors here
|
|
||||||
// break
|
|
||||||
//
|
|
||||||
// default:
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
|
|
||||||
// process items
|
|
||||||
|
|
||||||
// result
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue