git » sdk » commit 00bfc80

Update chat on bookmark change

author Eric Roberts
2026-08-17 16:03:44 UTC
committer Stephen Paul Weber
2026-08-17 16:18:37 UTC
parent fb3172a95b16870fb347b6f22b9d2e6e7b28886d

Update chat on bookmark change

borogove/Client.hx +32 -0
test/TestClient.hx +54 -0

diff --git a/borogove/Client.hx b/borogove/Client.hx
index 9262813..089cb40 100644
--- a/borogove/Client.hx
+++ b/borogove/Client.hx
@@ -755,6 +755,38 @@ class Client extends EventEmitter {
 			}
 			trace("pubsubNode == "+pubsubNode);
 
+			if (isOwnAccount && pubsubNode == "urn:xmpp:bookmarks:1" && pubsubEvent.getItems().length > 0) {
+				final chatsToUpdate = [];
+				for (item in pubsubEvent.getItems()) {
+					if (item.attr.get("id") != null) {
+						final chat = getChat(item.attr.get("id"));
+						if (chat == null) {
+							startChatWith(
+								item.attr.get("id"),
+								(caps) -> {
+									if (caps == null) return Open;
+
+									final identity = caps.identities[0];
+									final conf = item.getChild("conference", "urn:xmpp:bookmarks:1");
+									if (conf.attr.get("name") == null) {
+										conf.attr.set("name", identity?.name);
+									}
+									return (conf.attr.get("autojoin") == "1" || conf.attr.get("autojoin") == "true" || !caps.isChannel(item.attr.get("id"))) ? Open : Closed;
+								},
+								(chat) -> {
+									chat.updateFromBookmark(item);
+								}
+							);
+						} else {
+							chat.updateFromBookmark(item);
+							chatsToUpdate.push(chat);
+						}
+					}
+				}
+				persistence.storeChats(accountId(), chatsToUpdate);
+				this.trigger("chats/update", chatsToUpdate);
+			}
+
 #if !NO_OMEMO
 			if(pubsubNode == "eu.siacs.conversations.axolotl.devicelist" && omemo != null) {
 				if(isOwnAccount) {
diff --git a/test/TestClient.hx b/test/TestClient.hx
index e6ddc71..3065ac2 100644
--- a/test/TestClient.hx
+++ b/test/TestClient.hx
@@ -215,6 +215,60 @@ class TestClient extends utest.Test {
 		Assert.equals("Test Name", client.displayName());
 	}
 
+	public function testUpdateExistingFromBookmark() {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = new borogove.Chat.Channel(
+			client,
+			client.stream,
+			persistence,
+			"room@example.com"
+		);
+		client.chats.push(chat);
+
+		final stanza = new Stanza("message", { xmlns: "jabber:client", from: "test@example.com" })
+				.tag("event", { xmlns: "http://jabber.org/protocol/pubsub#event" })
+				.tag("items", { node: "urn:xmpp:bookmarks:1" })
+				.tag("item", { id: "room@example.com" })
+				.tag("conference", { xmlns: "urn:xmpp:bookmarks:1" })
+				.tag("extensions")
+				.textTag("group", "mboa", { xmlns: "jabber:iq:roster" });
+
+		client.stream.onStanza(stanza);
+
+		Assert.equals(1, client.getChat("room@example.com").getTags().length);
+		Assert.equals("mboa", client.getChat("room@example.com").getTags()[0]);
+	}
+
+	public function testCreateNewFromBookmark(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+
+		final stanza = new Stanza("message", { xmlns: "jabber:client", from: "test@example.com" })
+				.tag("event", { xmlns: "http://jabber.org/protocol/pubsub#event" })
+				.tag("items", { node: "urn:xmpp:bookmarks:1" })
+				.tag("item", { id: "room@example.com" })
+				.tag("conference", { xmlns: "urn:xmpp:bookmarks:1" })
+				.tag("extensions")
+				.textTag("group", "mboa", { xmlns: "jabber:iq:roster" });
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			if (stanza.name == "iq" && stanza.findChild("{http://jabber.org/protocol/disco#info}query") != null) {
+				client.stream.onStanza(
+					new Stanza("iq", { type: "result", to: "room@example.com", id: stanza.attr.get("id"), from: "stranger@example.com", xmlns: "jabber:client" })
+						.tag("query", { xmlns: "http://jabber.org/protocol/disco#info" })
+						.tag("identity", { category: "conference", type: "text" })
+				);
+			}
+			Assert.equals(1, client.getChat("room@example.com").getTags().length);
+			Assert.equals("mboa", client.getChat("room@example.com").getTags()[0]);
+			async.done();
+			return EventHandled;
+		});
+
+		client.stream.onStanza(stanza);
+	}
+
 	public function testSortAfterDirectChat() {
 		final persistence = new Dummy();
 		final client = new Client("test@example.com", persistence);