Software /
code /
prosody-modules
Comparison
mod_muc_markers/mod_muc_markers.lua @ 4065:92152437ecfe
mod_muc_markers: replace configurable multi-marker tracking with better system
Now tracks a single marker, but automatically applies rules from the XEP about
"higher" markers implying "lower" markers - i.e. "displayed" implies "received".
Still, just a single marker is tracked and synthesized at all times (the one
configured with muc_marker_name).
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Tue, 07 Jul 2020 17:08:08 +0100 |
parent | 4056:554f64c8d0c0 |
child | 4071:8e28d0918abc |
comparison
equal
deleted
inserted
replaced
4064:b7c9e479e857 | 4065:92152437ecfe |
---|---|
6 -- in marker reports. However it implies the 'id' attribute through examples, and this | 6 -- in marker reports. However it implies the 'id' attribute through examples, and this |
7 -- is what some clients implement. | 7 -- is what some clients implement. |
8 -- Notably Conversations will ack the origin-id instead. We need to update the XEP to | 8 -- Notably Conversations will ack the origin-id instead. We need to update the XEP to |
9 -- clarify the correct behaviour. | 9 -- clarify the correct behaviour. |
10 | 10 |
11 local set = require "util.set"; | |
11 local st = require "util.stanza"; | 12 local st = require "util.stanza"; |
12 | 13 |
13 local xmlns_markers = "urn:xmpp:chat-markers:0"; | 14 local xmlns_markers = "urn:xmpp:chat-markers:0"; |
14 | 15 |
16 local marker_order = { "received", "displayed", "acknowledged" }; | |
17 | |
18 -- Add reverse mapping | |
19 for priority, name in ipairs(marker_order) do | |
20 marker_order[name] = priority; | |
21 end | |
22 | |
15 local marker_element_name = module:get_option_string("muc_marker_type", "displayed"); | 23 local marker_element_name = module:get_option_string("muc_marker_type", "displayed"); |
16 local marker_element_names = module:get_option_set("muc_marker_types", { marker_element_name }); | 24 |
25 assert(marker_order[marker_element_name], "invalid marker name: "..marker_element_name); | |
26 | |
27 local marker_element_names = set.new(); | |
28 | |
29 -- "displayed" implies "received", etc. so we'll add the | |
30 -- chosen marker and any "higher" ones to the set | |
31 for i = marker_order[marker_element_name], #marker_order do | |
32 marker_element_names:add(marker_order[i]); | |
33 end | |
17 | 34 |
18 local muc_marker_map_store = module:open_store("muc_markers", "map"); | 35 local muc_marker_map_store = module:open_store("muc_markers", "map"); |
19 | 36 |
20 local function get_stanza_id(stanza, by_jid) | 37 local function get_stanza_id(stanza, by_jid) |
21 for tag in stanza:childtags("stanza-id", "urn:xmpp:sid:0") do | 38 for tag in stanza:childtags("stanza-id", "urn:xmpp:sid:0") do |
50 muc_marker_map_store:set(event.occupant.bare_jid, event.room.jid, marker.attr.id); | 67 muc_marker_map_store:set(event.occupant.bare_jid, event.room.jid, marker.attr.id); |
51 | 68 |
52 end); | 69 end); |
53 | 70 |
54 module:hook("muc-message-is-historic", function (event) | 71 module:hook("muc-message-is-historic", function (event) |
55 local marker = event.stanza:get_child("received", xmlns_markers); | 72 local marker = event.stanza:get_child(nil, xmlns_markers) |
56 | 73 |
57 -- Prevent stanza from reaching the archive (it's just noise) | 74 -- Prevent stanza from reaching the archive (it's just noise) |
58 if marker then | 75 if marker and marker_element_names:contains(marker.name) then |
59 return false | 76 return false |
60 end | 77 end |
61 end); | 78 end); |
62 | 79 |
63 local function find_nickname(room, user_jid) | 80 local function find_nickname(room, user_jid) |
80 if not markers then return end | 97 if not markers then return end |
81 for user_jid, id in pairs(markers) do | 98 for user_jid, id in pairs(markers) do |
82 local room_nick = find_nickname(room, user_jid); | 99 local room_nick = find_nickname(room, user_jid); |
83 if room_nick then | 100 if room_nick then |
84 local recv_marker = st.message({ type = "groupchat", from = room_nick, to = to }) | 101 local recv_marker = st.message({ type = "groupchat", from = room_nick, to = to }) |
85 :tag("received", { xmlns = xmlns_markers, id = id }); | 102 :tag(marker_element_name, { xmlns = xmlns_markers, id = id }); |
86 room:route_stanza(recv_marker); | 103 room:route_stanza(recv_marker); |
87 end | 104 end |
88 end | 105 end |
89 end); | 106 end); |
90 end | 107 end |