| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-06-30 19:50:11 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-06-30 19:50:11 UTC |
| parent | 01b0656464135a84e83fd6b12f4456263bc1a139 |
| borogove/Chat.hx | +6 | -3 |
| borogove/Client.hx | +3 | -0 |
| borogove/Import.hx | +19 | -1 |
| borogove/RosterItem.hx | +27 | -0 |
| borogove/queries/RosterGet.hx | +2 | -8 |
diff --git a/borogove/Chat.hx b/borogove/Chat.hx index 9e88d01..025f755 100644 --- a/borogove/Chat.hx +++ b/borogove/Chat.hx @@ -589,10 +589,10 @@ abstract class Chat extends EventEmitter { } @:allow(borogove) - private function updateFromRoster(item: { fn: Null<String>, subscription: String, groups: Array<String> }) { + private function updateFromRoster(item: RosterItem) { isBookmarked = true; setTrusted(item.subscription == "both" || item.subscription == "from"); - if (item.fn != null && item.fn != "") displayName = item.fn; + if (item.name != null && item.name != "") displayName = item.name; if (uiState == Invited) uiState = Open; extensions.removeChildren("group", "jabber:iq:roster"); for (group in item.groups) { @@ -2479,6 +2479,8 @@ class AvailableChat { public final note: String; @:allow(borogove) private final caps: Caps; + @:allow(borogove) + private final rosterItem: Null<RosterItem>; /** Is this search result a channel? @@ -2508,11 +2510,12 @@ class AvailableChat { } @:allow(borogove) - private function new(chatId: String, displayName: Null<String>, note: String, caps: Caps) { + private function new(chatId: String, displayName: Null<String>, note: String, caps: Caps, rosterItem: Null<RosterItem> = null) { this.chatId = chatId; this.displayName = displayName; this.note = note; this.caps = caps; + this.rosterItem = rosterItem; } } diff --git a/borogove/Client.hx b/borogove/Client.hx index d4f9b3a..e070cfe 100644 --- a/borogove/Client.hx +++ b/borogove/Client.hx @@ -1227,6 +1227,9 @@ class Client extends EventEmitter { } else { getDirectChat(availableChat.chatId, false); } + if (availableChat.rosterItem != null) { + chat.updateFromRoster(availableChat.rosterItem); + } persistence.storeChats(accountId(), [chat]); this.trigger("chats/update", [chat]); return chat; diff --git a/borogove/Import.hx b/borogove/Import.hx index 93a336e..e05ed30 100644 --- a/borogove/Import.hx +++ b/borogove/Import.hx @@ -3,6 +3,8 @@ package borogove; import ltx.Sax; using StringTools; +import borogove.Chat; + @:expose @:access(Xml) class Import { @@ -17,6 +19,7 @@ class Import { public var onAccount: String->Void; public var onChannel: String->Void; + public var onChat: (String, AvailableChat)->Void; public var onMessage: (String, Message)->Void; public function new(targetAccount: Null<String>, sortA: String = "Wt@|q", sortB: String = "a ") { @@ -30,6 +33,7 @@ class Import { var item = null; var mucComponent = false; var inArchive = false; + var inRoster = false; var resultStanza: Null<Stanza> = null; p.onStartElement = (tag: Xml) -> { ns = NsContext.from(ns, tag); @@ -53,7 +57,15 @@ class Import { sortA = sortAinit; item = tag.get("name"); if (mucComponent && onChannel != null) onChannel(item + "@" + host); + case "{jabber:iq:roster}query": + if (inArchive) throw "Roster inside an archive?"; + inRoster = true; + case "{jabber:iq:roster}item": + if (inRoster && onChat != null && !ignoredSources[item + "@" + host]) { + resultStanza = new Stanza("item", tag.attributeMap); + } case "{urn:xmpp:pie:0#mam}archive": + if (inRoster) throw "Archive inside a roster?"; if (item != null && host != null) inArchive = true; case "{urn:xmpp:mam:2}result": if (inArchive && onMessage != null && !ignoredSources[item + "@" + host]) { @@ -65,7 +77,11 @@ class Import { if (resultStanza != null) { resultStanza.up(); if (resultStanza.atTop()) { - if (onMessage != null) processResultStanza(resultStanza, item, host); + if (inRoster) { + if (onChat != null) onChat(item + "@" + host, new AvailableChat(resultStanza.attr.get("jid"), resultStanza.attr.get("name"), "Import", CapsRepo.empty, resultStanza)); + } else if (inArchive) { + if (onMessage != null) processResultStanza(resultStanza, item, host); + } resultStanza = null; } return; @@ -79,6 +95,8 @@ class Import { mucComponent = false; case "{urn:xmpp:pie:0#component}item", "{urn:xmpp:pie:0}user": item = null; + case "{jabber:iq:roster}query": + inRoster = false; case "{urn:xmpp:pie:0#mam}archive": inArchive = false; case "{urn:xmpp:mam:2}result": diff --git a/borogove/RosterItem.hx b/borogove/RosterItem.hx new file mode 100644 index 0000000..5b4802a --- /dev/null +++ b/borogove/RosterItem.hx @@ -0,0 +1,27 @@ +package borogove; + +@:nullSafety(StrictThreaded) +@:forward(toString) +abstract RosterItem(Stanza) from Stanza to Stanza { + public var jid(get, never): Null<String>; + public var name(get, never): Null<String>; + public var subscription(get, never): Null<String>; + public var groups(get, never): Array<String>; + + private inline function get_jid() { + return this.attr.get("jid"); + } + + private inline function get_name() { + return this.attr.get("name"); + } + + private inline function get_subscription() { + return this.attr.get("subscription"); + } + + private inline function get_groups() { + // TODO: cannot specify namespace here due to bugs in namespace handling in allTags + return this.allTags("group").map(g -> g.getText()); + } +} diff --git a/borogove/queries/RosterGet.hx b/borogove/queries/RosterGet.hx index ee0a554..2e7f66f 100644 --- a/borogove/queries/RosterGet.hx +++ b/borogove/queries/RosterGet.hx @@ -14,7 +14,7 @@ class RosterGet extends GenericQuery { public var queryId:String = null; public var ver:String = null; private var responseStanza:Stanza; - private var result: Array<{ jid: String, fn: String, subscription: String, groups: Array<String> }>; + private var result: Array<RosterItem>; public function new(?ver: String) { var attr: DynamicAccess<String> = { xmlns: xmlns }; @@ -41,13 +41,7 @@ class RosterGet extends GenericQuery { return []; } ver = q.attr.get("ver"); - // TODO: cannot specify namespace here due to bugs in namespace handling in allTags - result = q.allTags("item").map((item) -> { - jid: item.attr.get("jid"), - fn: item.attr.get("name"), - subscription: item.attr.get("subscription"), - groups: item.allTags("group").map(g -> g.getText()) - }); + result = q.allTags("item"); } return result; }