adds reactions

This commit is contained in:
gridtime
2023-12-08 09:44:52 +01:00
parent 565508b217
commit f5691fd8be
10 changed files with 268 additions and 33 deletions

View File

@@ -26,6 +26,7 @@ from urllib.parse import urlparse
from uuid import UUID, uuid4
import cairosvg
import emoji
import nio
from nio.crypto import AsyncDataT as UploadData
from nio.crypto import async_generator_from_data
@@ -225,6 +226,9 @@ class MatrixClient(nio.AsyncClient):
self.unassigned_event_last_read_by: DefaultDict[str, Dict[str, int]] =\
DefaultDict(dict)
# {reacted_event_id: {emoji: [user_id]}}
self.unassigned_reaction_events: Dict[str, Dict[str, List[str]]] = {}
self.push_rules: nio.PushRulesEvent = nio.PushRulesEvent()
self.ignored_user_ids: Set[str] = set()
@@ -359,7 +363,7 @@ class MatrixClient(nio.AsyncClient):
timeout = 10,
)
except asyncio.TimeoutError:
log.warn("%s timed out", self.user_id)
log.warning("%s timed out", self.user_id)
await self.close()
@@ -377,7 +381,7 @@ class MatrixClient(nio.AsyncClient):
account.max_upload_size = future.result() or 0
except MatrixError:
trace = traceback.format_exc().rstrip()
log.warn(
log.warning(
"On %s server config retrieval: %s", self.user_id, trace,
)
self.server_config_task = asyncio.ensure_future(
@@ -2421,6 +2425,49 @@ class MatrixClient(nio.AsyncClient):
self.backend.notification_avatar_cache[mxc] = path
return path
async def register_reaction(
self,
room: nio.MatrixRoom,
ev: nio.ReactionEvent,
event_id: str = "",
**fields,
) -> Event:
"""Register/update a reaction."""
reacts_to = ev.reacts_to
key = ev.key
sender = ev.sender
model = self.models[self.user_id, room.room_id, "events"]
reacts_to_event = model.get(reacts_to)
if not reacts_to_event: # local echo
for item in model.values():
if item.event_id == reacts_to:
reacts_to_event = item
# message is already loaded: update reactions instantly
if reacts_to_event:
reactions = reacts_to_event.reactions
if key not in reactions:
reactions[key] = {"hint": emoji.demojize(key), "users": []}
if sender not in reactions[key]["users"]:
reactions[key]["users"].append(sender)
reacts_to_event.set_fields(reactions=reactions)
reacts_to_event.notify_change("reactions")
# message is not loaded yet: register the reaction for later update
else:
registry = self.unassigned_reaction_events
if reacts_to not in registry:
registry[reacts_to] = {}
if key not in registry[reacts_to]:
registry[reacts_to][key] = []
if sender not in registry[reacts_to][key]:
registry[reacts_to][key].append(sender)
await self.register_nio_event(
room, ev, event_id, type_specifier=TypeSpecifier.Reaction,
content=key, hidden=True, **fields,
)
async def register_nio_event(
self,
@@ -2498,6 +2545,19 @@ class MatrixClient(nio.AsyncClient):
item.id = f"echo-{tx_id}"
self.event_to_echo_ids[ev.event_id] = item.id
reactions = self.unassigned_reaction_events.get(item.id, {})
for key, senders in reactions.items(): # update reactions
if key not in item.reactions:
item.reactions[key] = {
"hint": emoji.demojize(key),
"users": [],
}
item.reactions[key]["users"] += senders
if ev.source.get("type") == "m.reaction" \
and ev.source.get("unsigned", {}).get("redacted_by"):
item.type_specifier = TypeSpecifier.ReactionRedaction
item.hidden = True
model[item.id] = item
await self.set_room_last_event(room.room_id, item)