changeset 5656:c20b77e5e032

mod_http_muc_log: Correctly handle changed or retracted reactions Since per XEP-0444 each reaction should overwrite all previous reactions on a particular message from a particular occupant. Previously repeated reactions would be counted again and retractions were not handled.
author Kim Alvefur <zash@zash.se>
date Tue, 19 Sep 2023 13:22:00 +0200
parents 1cae6133e315
children 80abda15a1e9
files mod_http_muc_log/mod_http_muc_log.lua
diffstat 1 files changed, 18 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mod_http_muc_log/mod_http_muc_log.lua	Mon Sep 18 18:34:55 2023 +0200
+++ b/mod_http_muc_log/mod_http_muc_log.lua	Tue Sep 19 13:22:00 2023 +0200
@@ -407,17 +407,17 @@
 			local target_id = reactions.attr.id or reactions.attr.to;
 			for n = i - 1, 1, -1 do
 				if logs[n].archive_id == target_id then
-					local react_map = logs[n].reactions; -- { string : integer }
+					local react_map = logs[n].reactions; -- [occupant_id][emoji]boolean
 					if not react_map then
 						react_map = {};
 						logs[n].reactions = react_map;
 					end
+					local reacts = {};
 					for reaction_tag in reactions:childtags("reaction") do
-						-- FIXME This doesn't replace previous reactions by the same user
-						-- on the same message.
 						local reaction_text = reaction_tag:get_text() or "�";
-						react_map[reaction_text] = (react_map[reaction_text] or 0) + 1;
+						reacts[reaction_text] = true;
 					end
+					react_map[occupant_id] = reacts;
 					break
 				end
 			end
@@ -458,6 +458,20 @@
 	end
 	if i == 1 and not lazy then return end -- No items
 
+	-- collapse reactions[occupant-id][reaction]boolean into reactions[reaction]integer
+	for n = 1, #logs do
+		local reactions = logs[n].reactions;
+		if reactions then
+			local collated = {};
+			for _, reacts in pairs(reactions) do
+				for reaction_text in pairs(reacts) do
+					collated[reaction_text] = (collated[reaction_text] or 0) + 1;
+				end
+			end
+			logs[n].reactions = collated;
+		end
+	end
+
 	local next_when, prev_when = "", "";
 	local date_list = archive.dates and archive:dates(room);
 	if date_list then