Add RedactionEvent support on backend

This commit is contained in:
vSLG 2020-03-28 14:24:05 -03:00 committed by miruka
parent b3f1075507
commit db1afc980e
6 changed files with 103 additions and 2 deletions

View File

@ -1208,6 +1208,11 @@ class MatrixClient(nio.AsyncClient):
content, inline=True, room_id=room.room_id, content, inline=True, room_id=room.room_id,
) )
age = 0
with suppress(Exception):
age = ev.source.get("age")
age = age or 0
# Create Event ModelItem # Create Event ModelItem
item = Event( item = Event(
@ -1215,7 +1220,12 @@ class MatrixClient(nio.AsyncClient):
event_id = ev.event_id, event_id = ev.event_id,
event_type = type(ev), event_type = type(ev),
source = ev, source = ev,
date = datetime.fromtimestamp(ev.server_timestamp / 1000), date = datetime.fromtimestamp(
(
datetime.fromtimestamp(ev.server_timestamp / 1000) -
datetime.fromtimestamp(age / 1000)
).total_seconds()
),
sender_id = ev.sender, sender_id = ev.sender,
sender_name = sender_name, sender_name = sender_name,
sender_avatar = sender_avatar, sender_avatar = sender_avatar,
@ -1242,5 +1252,61 @@ class MatrixClient(nio.AsyncClient):
AlertRequested() AlertRequested()
model[item.id] = item model[item.id] = item
await self.set_room_last_event(room.room_id, item) await self.set_room_last_event(room.room_id, item)
async def register_redact_event(
self, room: nio.MatrixRoom, ev: nio.Event, **fields
) -> None:
"""Register a `nio.events.room_events.RedactionEvent` in our model.
If .redacts attribute points to an existing model, it should get replaced.
Else register as a new Event.
"""
model = self.models[self.user_id, room.room_id, "events"]
event = model.get_event_id(ev.redacts)
if event:
sender_name, sender_avatar = \
await self.get_member_name_avatar(room.room_id, ev.sender)
target_id = getattr(ev, "state_key", "") or ""
target_name, target_avatar = \
await self.get_member_name_avatar(room.room_id, target_id) \
if target_id else ("", "")
content = fields.get("content", "").strip()
if content and "inline_content" not in fields:
fields["inline_content"] = HTML.filter(
content, inline=True, room_id=room.room_id,
)
age = ev.source["unsigned"]["age"]
item = Event(
id = ev.event_id,
event_id = ev.event_id,
event_type = type(ev),
source = ev,
date = datetime.fromtimestamp(
(
datetime.fromtimestamp(ev.server_timestamp / 1000) -
datetime.fromtimestamp(age / 1000)
).total_seconds()
),
sender_id = ev.sender,
sender_name = sender_name,
sender_avatar = sender_avatar,
target_id = target_id,
target_name = target_name,
target_avatar = target_avatar,
links = Event.parse_links(content),
**fields,
)
model[event.id] = item
else:
await self.register_nio_event(room, ev, **fields)

View File

@ -177,6 +177,7 @@ class Event(ModelItem):
content: str = "" content: str = ""
inline_content: str = "" inline_content: str = ""
redacts: str = ""
reason: str = "" reason: str = ""
links: List[str] = field(default_factory=list) links: List[str] = field(default_factory=list)
mentions: List[Tuple[str, str]] = field(default_factory=list) mentions: List[Tuple[str, str]] = field(default_factory=list)

View File

@ -129,3 +129,21 @@ class Model(MutableMapping):
new = type(self)(sync_id=sync_id) new = type(self)(sync_id=sync_id)
new.update(self) new.update(self)
return new return new
def get_event_id(self, event_id: str) -> "Model":
"""Get an event from the internal dict by event_id field.
This function exists because not every event is indexed with its
event_id field.
"""
event = self._data.get(event_id)
if event and event.event_id == event_id:
return event
for event in self._data.values():
if event.event_id == event_id:
return event
return None

View File

@ -161,6 +161,12 @@ class NioCallbacks:
await self.onRoomMessageMedia(room, ev) await self.onRoomMessageMedia(room, ev)
async def onRedactionEvent(self, room, ev) -> None:
await self.client.register_redact_event(
room, ev, redacts=ev.redacts, reason=ev.reason
)
async def onRoomCreateEvent(self, room, ev) -> None: async def onRoomCreateEvent(self, room, ev) -> None:
co = "%1 allowed users on other matrix servers to join this room" \ co = "%1 allowed users on other matrix servers to join this room" \
if ev.federate else \ if ev.federate else \

View File

@ -33,6 +33,7 @@ HColumnLayout {
readonly property bool smallAvatar: compact readonly property bool smallAvatar: compact
readonly property bool collapseAvatar: combine readonly property bool collapseAvatar: combine
readonly property bool hideAvatar: onRight readonly property bool hideAvatar: onRight
readonly property bool isRedacted: model.event_type === "RedactionEvent"
readonly property bool hideNameLine: readonly property bool hideNameLine:
model.event_type === "RoomMessageEmote" || model.event_type === "RoomMessageEmote" ||
@ -221,6 +222,7 @@ HColumnLayout {
HMenuItemPopupSpawner { HMenuItemPopupSpawner {
icon.name: "remove-message" icon.name: "remove-message"
text: qsTr("Remove") text: qsTr("Remove")
enabled: ! isRedacted
popup: "Popups/RedactEvents.qml" popup: "Popups/RedactEvents.qml"
popupParent: chat popupParent: chat

View File

@ -200,6 +200,14 @@ QtObject {
return qsTr(ev.content).arg(sender).arg(target) return qsTr(ev.content).arg(sender).arg(target)
} }
if (type === "RedactionEvent") {
return qsTr(
"<i>Removed message" +
`${ev.reason ? ". Reason: " + ev.reason : ""}` +
"</i>"
)
}
return qsTr(ev.content).arg(sender) return qsTr(ev.content).arg(sender)
} }