diff --git a/TODO.md b/TODO.md index cbfaa182..e30c4a9d 100644 --- a/TODO.md +++ b/TODO.md @@ -2,6 +2,9 @@ - redact local echo effect - being able to redact local echos +- message removed by *display name* +- do action on last msg if none selected +- unselect before unfocusing ## Refactoring diff --git a/src/backend/user_files.py b/src/backend/user_files.py index 50d24213..c387c05d 100644 --- a/src/backend/user_files.py +++ b/src/backend/user_files.py @@ -282,13 +282,14 @@ class UISettings(JSONDataFile): "10": f"{alt_or_cmd()}+0", }, - "unfocusOrDeselectAllMessages": ["Escape"], - "focusPreviousMessage": ["Ctrl+Up", "Ctrl+K"], - "focusNextMessage": ["Ctrl+Down", "Ctrl+J"], - "toggleSelectMessage": ["Ctrl+Space"], - "selectMessagesUntilHere": ["Ctrl+Shift+Space"], - "debugFocusedMessage": ["Ctrl+D"], - "clearRoomMessages": ["Ctrl+L"], + "unfocusOrDeselectAllMessages": ["Escape"], + "focusPreviousMessage": ["Ctrl+Up", "Ctrl+K"], + "focusNextMessage": ["Ctrl+Down", "Ctrl+J"], + "toggleSelectMessage": ["Ctrl+Space"], + "selectMessagesUntilHere": ["Ctrl+Shift+Space"], + "removeFocusedOrSelectedMessages": ["Ctrl+R", "Ctrl+Del"], + "debugFocusedMessage": ["Ctrl+D"], + "clearRoomMessages": ["Ctrl+L"], "sendFile": ["Alt+S"], "sendFileFromPathInClipboard": ["Alt+Shift+S"], diff --git a/src/gui/Pages/Chat/Timeline/EventDelegate.qml b/src/gui/Pages/Chat/Timeline/EventDelegate.qml index 764648b8..30f6ac29 100644 --- a/src/gui/Pages/Chat/Timeline/EventDelegate.qml +++ b/src/gui/Pages/Chat/Timeline/EventDelegate.qml @@ -229,26 +229,22 @@ HColumnLayout { properties: ({ userId: chat.userId, roomId: chat.roomId, - - eventIds: - redactableEvents - .filter(ev => ev.event_type !== "RedactedEvent") - .map(ev => ev.event_id), + eventIds: events.map(ev => ev.event_id), onlyOwnMessageWarning: ! chat.roomInfo.can_redact_all && - redactableEvents.length < eventList.selectedCount + events.length < eventList.selectedCount }) - readonly property var redactableEvents: - ( - eventList.selectedCount ? - eventList.getSortedChecked() : - [model] - ).filter(ev => - ev.sender_id === chat.userId || - chat.roomInfo.can_redact_all - ) + readonly property var events: { + eventList.selectedCount ? + eventList.redactableCheckedEvents : + + eventList.canRedact(currentModel) ? + [model] : + + [] + } } HMenuItem { diff --git a/src/gui/Pages/Chat/Timeline/EventList.qml b/src/gui/Pages/Chat/Timeline/EventList.qml index bed5a312..f1a0d3bf 100644 --- a/src/gui/Pages/Chat/Timeline/EventList.qml +++ b/src/gui/Pages/Chat/Timeline/EventList.qml @@ -50,6 +50,45 @@ Rectangle { eventList.checkFromLastToHere(eventList.currentIndex) } + HShortcut { + sequences: window.settings.keys.removeFocusedOrSelectedMessages + onActivated: utils.makePopup( + "Popups/RedactPopup.qml", + chat, + { + userId: chat.userId, + roomId: chat.roomId, + eventIds: + (events || findLastRemovableDelegate()).map( + ev => ev.event_id, + ), + isLast: ! events, + onlyOwnMessageWarning: + ! chat.roomInfo.can_redact_all && + events && + events.length < eventList.selectedCount + } + ) + + readonly property var events: + eventList.selectedCount ? + eventList.redactableCheckedEvents : + + eventList.currentItem && + eventList.canRedact(eventList.currentItem.currentModel) ? + [eventList.currentItem.currentModel] : + + null + + function findLastRemovableDelegate() { + for (let i = 0; i < eventList.model.count && i <= 1000; i++) { + const event = eventList.model.get(i) + if (eventList.canRedact(event)) return [event] + } + return [] + } + } + HShortcut { active: eventList.currentItem sequences: window.settings.keys.debugFocusedMessage @@ -140,6 +179,9 @@ Rectangle { property string delegateWithSelectedText: "" property string selectedText: "" + readonly property var redactableCheckedEvents: + getSortedChecked().filter(ev => eventList.canRedact(ev)) + function copySelectedDelegates() { if (eventList.selectedText) { @@ -174,6 +216,13 @@ Rectangle { Clipboard.text = contents.join("\n\n") } + function canRedact(eventModel) { + print(eventModel) + return eventModel.event_type !== "RedactedEvent" && + (chat.roomInfo.can_redact_all || + eventModel.sender_id === chat.userId) + } + function canCombine(item, itemAfter) { if (! item || ! itemAfter) return false diff --git a/src/gui/Popups/RedactPopup.qml b/src/gui/Popups/RedactPopup.qml index becfb131..219633f8 100644 --- a/src/gui/Popups/RedactPopup.qml +++ b/src/gui/Popups/RedactPopup.qml @@ -6,22 +6,20 @@ import "../Base" BoxPopup { summary.text: + isLast ? + qsTr("Remove your last message?") : + eventIds.length > 1 ? - qsTr("Remove selected messages?") : - qsTr("Remove selected message?") + qsTr("Remove %1 messages?").arg(eventIds.length) : + + qsTr("Remove this message?") details.color: theme.colors.warningText details.text: onlyOwnMessageWarning ? - qsTr("Only your messages will be removed") : + qsTr("Only your messages can be removed") : "" - HLabeledTextField { - id: reasonField - label.text: qsTr("Reason (optional):") - Layout.fillWidth: true - } - okText: qsTr("Remove") box.focusButton: "ok" @@ -31,9 +29,18 @@ BoxPopup { [roomId, reasonField.field.text, ...eventIds] ) + property string roomId: "" property string userId: "" property var eventIds: [] property bool onlyOwnMessageWarning: false + property bool isLast: false + + + HLabeledTextField { + id: reasonField + label.text: qsTr("Optional reason:") + Layout.fillWidth: true + } }