From c5b0176e950053369dc178668001c8cf994cbd83 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Mon, 1 Jul 2024 12:36:32 +0200 Subject: [PATCH] Poll WIP (#231): * backend: custom xml --- .../mod_muc_poll/constants.lib.lua | 8 +++++ prosody-modules/mod_muc_poll/message.lib.lua | 33 ++++++++++++++++++- prosody-modules/mod_muc_poll/poll.lib.lua | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/prosody-modules/mod_muc_poll/constants.lib.lua b/prosody-modules/mod_muc_poll/constants.lib.lua index 759e274c..eca16ce0 100644 --- a/prosody-modules/mod_muc_poll/constants.lib.lua +++ b/prosody-modules/mod_muc_poll/constants.lib.lua @@ -3,7 +3,15 @@ -- FIXME: create a XEP to standardize this, and remove the "x-". local xmlns_poll = "http://jabber.org/protocol/muc#x-poll"; +local xmlns_poll_message = "http://jabber.org/protocol/muc#x-poll-message"; +local poll_message_tag = "x-poll"; +local poll_question_tag = "x-poll-question"; +local poll_choice_tag = "x-poll-choice"; return { xmlns_poll = xmlns_poll; + xmlns_poll_message = xmlns_poll_message; + poll_message_tag = poll_message_tag; + poll_question_tag = poll_question_tag; + poll_choice_tag = poll_choice_tag; }; diff --git a/prosody-modules/mod_muc_poll/message.lib.lua b/prosody-modules/mod_muc_poll/message.lib.lua index 73c07bee..30135a00 100644 --- a/prosody-modules/mod_muc_poll/message.lib.lua +++ b/prosody-modules/mod_muc_poll/message.lib.lua @@ -6,6 +6,10 @@ local st = require "util.stanza"; local timer = require "util.timer"; local xmlns_occupant_id = "urn:xmpp:occupant-id:0"; local xmlns_replace = "urn:xmpp:message-correct:0"; +local xmlns_poll_message = module:require("constants").xmlns_poll_message; +local poll_message_tag = module:require("constants").poll_message_tag; +local poll_question_tag = module:require("constants").poll_question_tag; +local poll_choice_tag = module:require("constants").poll_choice_tag; local mod_muc = module:depends"muc"; local get_room_from_jid = mod_muc.get_room_from_jid; @@ -35,7 +39,7 @@ local function build_poll_message(room, message_id, is_end_message) local choice, label = choice_desc.number, choice_desc.label; content = content .. choice .. ': ' .. label; if total > 0 then - local nb = current_poll.votes_by_choices["" .. choice] or 0; + local nb = current_poll.votes_by_choices[choice] or 0; local percent = string.format("%.2f", nb * 100 / total); content = content .. " (" .. nb .. "/" .. total .. " = " .. percent .. "%)"; end @@ -57,6 +61,33 @@ local function build_poll_message(room, message_id, is_end_message) id = current_poll.occupant_id }):up(); + -- now we must add some custom XML data, so that compatible clients can display the poll as they want: + -- + -- Poll question + -- Choice 1 label + -- Choice 2 label + -- Choice 3 label + -- Choice 4 label + -- + local message_attrs = { + xmlns = xmlns_poll_message, + id = current_poll.poll_id, + votes = "" .. total + }; + if current_poll.already_ended then + message_attrs["over"] = ""; + end + msg:tag(poll_message_tag, message_attrs):text_tag(poll_question_tag, current_poll["muc#roompoll_question"], {}); + for _, choice_desc in ipairs(current_poll.choices_ordered) do + local choice, label = choice_desc.number, choice_desc.label; + local nb = current_poll.votes_by_choices[choice] or 0; + msg:text_tag(poll_choice_tag, label, { + votes = "" .. nb, + choice = choice + }); + end + msg:up(); + return msg; end diff --git a/prosody-modules/mod_muc_poll/poll.lib.lua b/prosody-modules/mod_muc_poll/poll.lib.lua index ff3f09ac..f6e110e7 100644 --- a/prosody-modules/mod_muc_poll/poll.lib.lua +++ b/prosody-modules/mod_muc_poll/poll.lib.lua @@ -1,6 +1,7 @@ -- SPDX-FileCopyrightText: 2024 John Livingston -- SPDX-License-Identifier: AGPL-3.0-only +local id = require "util.id"; local st = require "util.stanza"; local get_time = require "util.time".now; local timer = require "util.timer"; @@ -95,6 +96,7 @@ end local function create_poll(room, fields, occupant) module:log("debug", "Creating a new poll for room %s, by %s", room.jid, occupant.bare_jid); room._data.current_poll = fields; + room._data.current_poll.poll_id = id.short(); room._data.current_poll.end_timestamp = get_time() + (60 * fields["muc#roompoll_duration"]); room._data.current_poll.votes_by_occupant = {}; room._data.current_poll.votes_by_choices = {};