Make "Remove" option conditional in context menu

Refactor code in the backend so things can work
better
This commit is contained in:
vSLG 2020-04-01 14:33:19 -03:00 committed by miruka
parent fc878e7537
commit e60a7f6dac
6 changed files with 69 additions and 34 deletions

View File

@ -875,9 +875,10 @@ class MatrixClient(nio.AsyncClient):
return (successes, errors) return (successes, errors)
async def room_mass_redact( async def room_mass_redact(
self, room_id: str, reason: str, *event_ids: str, self, room_id: str, reason: str, *event_ids: str,
): ) -> List[nio.responses.RoomRedactResponse]:
"""Redact events from a room in parallel. """Redact events from a room in parallel.
Returns a list of sucessful redacts. Returns a list of sucessful redacts.
@ -888,6 +889,7 @@ class MatrixClient(nio.AsyncClient):
for evt_id in event_ids for evt_id in event_ids
]) ])
async def generate_thumbnail( async def generate_thumbnail(
self, data: UploadData, is_svg: bool = False, self, data: UploadData, is_svg: bool = False,
) -> Tuple[bytes, MatrixImageInfo]: ) -> Tuple[bytes, MatrixImageInfo]:
@ -1117,6 +1119,7 @@ class MatrixClient(nio.AsyncClient):
guests_allowed = room.guest_access == "can_join", guests_allowed = room.guest_access == "can_join",
can_invite = levels.can_user_invite(self.user), can_invite = levels.can_user_invite(self.user),
can_redact = levels.can_user_redact(self.user),
can_send_messages = can_send_msg(), can_send_messages = can_send_msg(),
can_set_name = can_send_state("m.room.name"), can_set_name = can_send_state("m.room.name"),
can_set_topic = can_send_state("m.room.topic"), can_set_topic = can_send_state("m.room.topic"),
@ -1186,7 +1189,10 @@ class MatrixClient(nio.AsyncClient):
async def register_nio_event( async def register_nio_event(
self, room: nio.MatrixRoom, ev: nio.Event, event_id: str = None, self,
room: nio.MatrixRoom,
ev: nio.Event,
event_id: str = "",
**fields, **fields,
) -> None: ) -> None:
"""Register a `nio.Event` as a `Event` object in our model.""" """Register a `nio.Event` as a `Event` object in our model."""

View File

@ -70,6 +70,7 @@ class Room(ModelItem):
guests_allowed: bool = True guests_allowed: bool = True
can_invite: bool = False can_invite: bool = False
can_redact: bool = False
can_send_messages: bool = False can_send_messages: bool = False
can_set_name: bool = False can_set_name: bool = False
can_set_topic: bool = False can_set_topic: bool = False

View File

@ -165,32 +165,46 @@ class NioCallbacks:
model = self.client.models[self.client.user_id, room.room_id, "events"] model = self.client.models[self.client.user_id, room.room_id, "events"]
event = None event = None
for event in model._sorted_data: for evt in model._sorted_data:
if event.event_id == ev.redacts: if evt.event_id == ev.redacts:
event = evt
break break
if ( if not (event and event.event_type is not nio.RedactedEvent):
event and return
issubclass(event.event_type, nio.events.room_events.RoomMessage)
):
event.source.source["content"] = {} event.source.source["content"] = {}
event.source.source["unsigned"] = { event.source.source["unsigned"] = {
"redacted_by": ev.event_id, "redacted_by": ev.event_id,
"redacted_because": ev.source, "redacted_because": ev.source,
} }
await self.client.register_nio_event( await self.onRedactedEvent(
room, room,
nio.events.room_events.RedactedEvent.from_dict( nio.RedactedEvent.from_dict(event.source.source),
event.source.source,
),
event_id = event.id, event_id = event.id,
) )
async def onRedactedEvent(self, room, ev) -> None: async def onRedactedEvent(self, room, ev, event_id: str = "") -> None:
# There is no way to know which kind of event was redacted in an
# encrypted room.
kind = "Message" if ev.type == "m.room.encrypted" \
else ev.type.split(".")[-1].capitalize() \
.replace("_", " ")
co = "%s event removed%s.%s" % (
kind,
f" by {ev.redacter}" if ev.redacter != ev.sender else "",
f" Reason: {ev.reason}." if ev.reason else "",
)
await self.client.register_nio_event( await self.client.register_nio_event(
room, ev, reason=ev.reason, room,
ev,
event_id = event_id,
reason = ev.reason or "",
content = co,
) )

View File

@ -220,16 +220,28 @@ HColumnLayout {
HMenuItemPopupSpawner { HMenuItemPopupSpawner {
icon.name: "remove-message" icon.name: "remove-message"
text: qsTr("Remove") text: qsTr("Remove")
enabled: ! isRedacted enabled: properties.eventIds.length
popup: "Popups/RedactEvents.qml" popup: "Popups/RedactEvents.qml"
popupParent: chat popupParent: chat
properties: ({ properties: ({
userId: chat.userId, userId: chat.userId,
roomId: chat.roomId, roomId: chat.roomId,
eventIds: eventList.selectedCount ? eventIds:
eventList.getSortedChecked().map(ev => ev.event_id) : (
[model.event_id] eventList.selectedCount ?
eventList.getSortedChecked() :
[model]
).filter(ev =>
(
ev.sender_id === chat.userId ||
chat.roomInfo.can_redact
) && ! isRedacted
).map(ev => ev.event_id),
"details.text":
(! chat.roomInfo.can_redact && eventList.selectedCount) ?
qsTr("Only your messages will be removed") :
""
}) })
} }

View File

@ -10,6 +10,8 @@ BoxPopup {
qsTr("Remove selected messages?") : qsTr("Remove selected messages?") :
qsTr("Remove selected message?") qsTr("Remove selected message?")
details.color: theme.colors.warningText
HLabeledTextField { HLabeledTextField {
id: reasonField id: reasonField
label.text: qsTr("Reason (optional):") label.text: qsTr("Reason (optional):")

View File

@ -165,11 +165,11 @@ QtObject {
function escapeHtml(text) { function escapeHtml(text) {
// Replace special HTML characters by encoded alternatives // Replace special HTML characters by encoded alternatives
return text.replace("&", "&") return text.replace(/&/g, "&")
.replace("<", "&lt;") .replace(/</g, "&lt;")
.replace(">", "&gt;") .replace(/>/g, "&gt;")
.replace('"', "&quot;") .replace(/"/g, "&quot;")
.replace("'", "&#039;") .replace(/'/g, "&#039;")
} }
@ -202,9 +202,9 @@ QtObject {
if (type === "RedactedEvent") { if (type === "RedactedEvent") {
return qsTr( return qsTr(
"<i>Removed message" + `<font color="${theme.colors.dimText}"><i>` +
`${ev.reason ? ". Reason: " + ev.reason : ""}` + escapeHtml(ev.content) +
"</i>" "</i></font>"
) )
} }