From 2a0a3765fc128bc9e2861e8da2314d0b778fa352 Mon Sep 17 00:00:00 2001 From: miruka Date: Sun, 19 Apr 2020 11:12:35 -0400 Subject: [PATCH] Add kick to room member context menu --- src/backend/matrix_client.py | 1 + src/backend/models/items.py | 1 + src/backend/nio_callbacks.py | 4 +- src/gui/Pages/Chat/Banners/LeftBanner.qml | 2 +- .../Pages/Chat/RoomPane/MemberDelegate.qml | 17 ++++++++ src/gui/Popups/KickPopup.qml | 40 +++++++++++++++++++ src/gui/Utils.qml | 6 +-- src/icons/thin/remove-message.svg | 4 +- src/icons/thin/room-kick.svg | 4 ++ 9 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 src/gui/Popups/KickPopup.qml create mode 100644 src/icons/thin/room-kick.svg diff --git a/src/backend/matrix_client.py b/src/backend/matrix_client.py index 7a43ff69..9e401948 100644 --- a/src/backend/matrix_client.py +++ b/src/backend/matrix_client.py @@ -1182,6 +1182,7 @@ class MatrixClient(nio.AsyncClient): guests_allowed = room.guest_access == "can_join", can_invite = levels.can_user_invite(self.user), + can_kick = levels.can_user_kick(self.user), can_redact_all = levels.can_user_redact(self.user), can_send_messages = can_send_msg(), can_set_name = can_send_state("m.room.name"), diff --git a/src/backend/models/items.py b/src/backend/models/items.py index dada6631..6db07a28 100644 --- a/src/backend/models/items.py +++ b/src/backend/models/items.py @@ -70,6 +70,7 @@ class Room(ModelItem): guests_allowed: bool = True can_invite: bool = False + can_kick: bool = False can_redact_all: bool = False can_send_messages: bool = False can_set_name: bool = False diff --git a/src/backend/nio_callbacks.py b/src/backend/nio_callbacks.py index e99891fb..4f86ef32 100644 --- a/src/backend/nio_callbacks.py +++ b/src/backend/nio_callbacks.py @@ -272,7 +272,7 @@ class NioCallbacks: self.client.skipped_events[room.room_id] += 1 return None - reason = f". Reason: {now['reason']}" if now.get("reason") else "" + reason = f", reason: {now['reason']}" if now.get("reason") else "" if membership == "join": return ( @@ -303,7 +303,7 @@ class NioCallbacks: f"%1 unbanned %2 from the room{reason}" if prev and prev_membership == "ban" else - f"%1 kicked out %2 from the room{reason}", + f"%1 kicked %2 out from the room{reason}", ) if membership == "ban": diff --git a/src/gui/Pages/Chat/Banners/LeftBanner.qml b/src/gui/Pages/Chat/Banners/LeftBanner.qml index 54cf4dc6..1427e3bb 100644 --- a/src/gui/Pages/Chat/Banners/LeftBanner.qml +++ b/src/gui/Pages/Chat/Banners/LeftBanner.qml @@ -10,7 +10,7 @@ Banner { avatar.userId: chat.userId avatar.displayName: chat.userInfo.display_name avatar.mxc: chat.userInfo.avatar_url - labelText: qsTr("You are not part of this room anymore") + labelText: qsTr("You are no longer part of this room") buttonModel: [ { diff --git a/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml b/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml index f8d43bee..b573e3ae 100644 --- a/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml +++ b/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml @@ -52,6 +52,23 @@ HTileDelegate { text: qsTr("Copy user ID") onTriggered: Clipboard.text = model.id } + + HMenuItemPopupSpawner { + icon.name: "room-kick" + icon.color: theme.colors.negativeBackground + text: model.invited ? qsTr("Disinvite") : qsTr("Kick") + enabled: chat.roomInfo.can_kick + + popup: "Popups/KickPopup.qml" + popupParent: chat + properties: ({ + userId: chat.userId, + roomId: chat.roomId, + targetUserId: model.id, + targetDisplayName: model.display_name, + targetIsInvited: model.invited, + }) + } } diff --git a/src/gui/Popups/KickPopup.qml b/src/gui/Popups/KickPopup.qml new file mode 100644 index 00000000..26b7c720 --- /dev/null +++ b/src/gui/Popups/KickPopup.qml @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later + +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import "../Base" + +BoxPopup { + summary.textFormat: Text.StyledText + summary.text: + targetIsInvited ? + qsTr("Withdraw %1's invitation?").arg(coloredTarget) : + qsTr("Kick %1 out of the room?").arg(coloredTarget) + + okText: qsTr("Kick") + + onOpened: reasonField.field.forceActiveFocus() + onOk: py.callClientCoro( + userId, + "room_kick", + [roomId, targetUserId, reasonField.field.text || null], + ) + + + property string userId + property string roomId + property string targetUserId + property string targetDisplayName + property bool targetIsInvited: false + + readonly property string coloredTarget: + utils.coloredNameHtml(targetDisplayName, targetUserId) + + + HLabeledTextField { + id: reasonField + label.text: qsTr("Optional reason:") + + Layout.fillWidth: true + } +} diff --git a/src/gui/Utils.qml b/src/gui/Utils.qml index 1d5027b4..1e7c6253 100644 --- a/src/gui/Utils.qml +++ b/src/gui/Utils.qml @@ -160,9 +160,7 @@ QtObject { } - function coloredNameHtml( - name, userId, displayText=null, disambiguate=false, dim=false, - ) { + function coloredNameHtml(name, userId, displayText=null, dim=false) { // substring: remove leading @ return ``+ escapeHtml(displayText || name || userId) + @@ -210,7 +208,7 @@ QtObject { if (ev.content.includes("%2")) content = content.arg(coloredNameHtml( - ev.redacter_name, ev.redacter_id, "", false, true, + ev.redacter_name, ev.redacter_id, "", true, )) return qsTr( diff --git a/src/icons/thin/remove-message.svg b/src/icons/thin/remove-message.svg index e6e3bfcf..d8b94628 100644 --- a/src/icons/thin/remove-message.svg +++ b/src/icons/thin/remove-message.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/icons/thin/room-kick.svg b/src/icons/thin/room-kick.svg new file mode 100644 index 00000000..67b9a968 --- /dev/null +++ b/src/icons/thin/room-kick.svg @@ -0,0 +1,4 @@ + + + +