| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-06-24 03:00:54 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-06-24 03:04:26 UTC |
| parent | 352ac7ce64f43e3295abd75cb809d767cad0efdf |
| 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++;