git » sdk » commit 61d49fe

Send both types of voice grant and update the chat

author Stephen Paul Weber
2026-06-24 03:00:54 UTC
committer Stephen Paul Weber
2026-06-24 03:04:26 UTC
parent 352ac7ce64f43e3295abd75cb809d767cad0efdf

Send both types of voice grant and update the chat

borogove/Chat.hx +26 -10
test/TestChat.hx +6 -4

diff --git a/borogove/Chat.hx b/borogove/Chat.hx
index 193701b..dc86495 100644
--- a/borogove/Chat.hx
+++ b/borogove/Chat.hx
@@ -1771,7 +1771,9 @@ class Channel extends Chat {
 			}
 			if (mucUser.role != "visitor" && mucUser.jid != null) {
 				// If they're not a visitor they can't be requesting voice
-				persistence.storeVoiceRequest(client.accountId(), this, mucUser.jid.asString(), false);
+				persistence.storeVoiceRequest(client.accountId(), this, mucUser.jid.asBare().asString(), false).then(_ -> {
+					client.trigger("chats/update", [this]);
+				});
 			}
 		}
 		if (member.isSelf) {
@@ -2051,16 +2053,30 @@ class Channel extends Chat {
 	public function voiceRequestRespond(member: Member, canSend: Bool) {
 		if (member.chat == null) return;
 
-		// For canSend=true we could use normal set role to participant as well
 		final outboxItem = outbox.newItem();
-		outboxItem.handle(() -> client.sendStanza(
-			new Stanza("message", { to: chatId })
-			.tag("x", { xmlns: "jabber:x:data", type: "submit" })
-			.tag("field", { "var": "FORM_TYPE" }).textTag("value", "http://jabber.org/protocol/muc#request").up()
-			.tag("field", { "var": "muc#role" }).textTag("value", "participant").up()
-			.tag("field", { "var": "muc#jid" }).textTag("value", member.chat.chatId).up()
-			.tag("field", { "var": "muc#request_allow" }).textTag("value", canSend ? "1" : "0").up()
-		));
+		outboxItem.handle(() -> {
+			client.sendStanza(
+				new Stanza("message", { to: chatId })
+				.tag("x", { xmlns: "jabber:x:data", type: "submit" })
+				.tag("field", { "var": "FORM_TYPE" }).textTag("value", "http://jabber.org/protocol/muc#request").up()
+				.tag("field", { "var": "muc#role" }).textTag("value", "participant").up()
+				.tag("field", { "var": "muc#jid" }).textTag("value", member.chat.chatId).up()
+				.tag("field", { "var": "muc#roomnick" }).textTag("value", member.displayName).up()
+				.tag("field", { "var": "muc#request_allow" }).textTag("value", canSend ? "1" : "0").up()
+			);
+			if (canSend) {
+				stream.sendIq(
+					new Stanza("iq", { type: "set", to: chatId })
+					.tag("query", { xmlns: "http://jabber.org/protocol/muc#admin" })
+					.tag("item", { nick: member.displayName, role: "participant" })
+					.textTag("reason", "Approve voice request"),
+					(response) -> {}
+				);
+			}
+			persistence.storeVoiceRequest(client.accountId(), this, member.chat.chatId, false).then(_ -> {
+				client.trigger("chats/update", [this]);
+			});
+		});
 	}
 
 	private function buildMember(resource: String, presence: Presence): Member {
diff --git a/test/TestChat.hx b/test/TestChat.hx
index acbeede..f816fdf 100644
--- a/test/TestChat.hx
+++ b/test/TestChat.hx
@@ -707,19 +707,21 @@ class TestChat extends utest.Test {
 				final x = stanza.getChild("x", "jabber:x:data");
 				if (x != null && x.attr.get("type") == "submit") {
 					final fields = x.allTags("field");
-					Assert.equals(4, fields.length);
+					Assert.equals(5, fields.length);
 					Assert.equals("FORM_TYPE", fields[0].attr.get("var"));
 					Assert.equals("http://jabber.org/protocol/muc#request", fields[0].getChild("value").getText());
 					Assert.equals("muc#role", fields[1].attr.get("var"));
 					Assert.equals("participant", fields[1].getChild("value").getText());
 					Assert.equals("muc#jid", fields[2].attr.get("var"));
 					Assert.equals("someone_chat@example.com", fields[2].getChild("value").getText());
-					Assert.equals("muc#request_allow", fields[3].attr.get("var"));
+					Assert.equals("muc#roomnick", fields[3].attr.get("var"));
+					Assert.equals("some_name", fields[3].getChild("value").getText());
+					Assert.equals("muc#request_allow", fields[4].attr.get("var"));
 
 					if (count == 0) {
-						Assert.equals("1", fields[3].getChild("value").getText());
+						Assert.equals("1", fields[4].getChild("value").getText());
 					} else {
-						Assert.equals("0", fields[3].getChild("value").getText());
+						Assert.equals("0", fields[4].getChild("value").getText());
 						async.done();
 					}
 					count++;