Add RedactionEvent support on backend
This commit is contained in:
parent
b3f1075507
commit
db1afc980e
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user