diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0a09b3d8..9c33d96f9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -213,7 +213,7 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE qml/AccountMenu.qml qml/ExploreComponent.qml qml/ExploreComponentMobile.qml - qml/ContextMenu.qml + qml/RoomContextMenu.qml qml/CollapsedRoomDelegate.qml qml/RoomDelegate.qml qml/RoomListPage.qml diff --git a/src/qml/ContextMenu.qml b/src/qml/ContextMenu.qml deleted file mode 100644 index 752594f8f..000000000 --- a/src/qml/ContextMenu.qml +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-FileCopyrightText: 2019 Black Hat -// SPDX-FileCopyrightText: 2020 Carl Schwan -// SPDX-License-Identifier: GPL-3.0-only - -import QtQuick -import QtQuick.Controls as QQC2 -import QtQuick.Layouts - -import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.components as KirigamiComponents -import org.kde.kirigamiaddons.delegates as Delegates - -import org.kde.neochat -import org.kde.neochat.settings - -/** - * Context menu when clicking on a room in the room list - */ -Loader { - id: root - - property NeoChatRoom room - required property NeoChatConnection connection - - signal closed - - Component { - id: regularMenu - QQC2.Menu { - QQC2.MenuItem { - text: i18n("Mark as Read") - icon.name: "checkmark" - enabled: room.notificationCount > 0 - onTriggered: room.markAllMessagesAsRead() - } - - QQC2.MenuSeparator {} - - QQC2.Menu { - title: i18nc("@action:inmenu", "Notifications") - icon.name: "notifications" - - QQC2.MenuItem { - text: i18n("Follow Global Setting") - icon.name: "globe" - checkable: true - autoExclusive: true - checked: room.pushNotificationState === PushNotificationState.Default - enabled: room.pushNotificationState != PushNotificationState.Unknown - onTriggered: { - room.pushNotificationState = PushNotificationState.Default; - } - } - QQC2.MenuItem { - text: i18nc("As in 'notify for all messages'", "All") - icon.name: "notifications" - checkable: true - autoExclusive: true - checked: room.pushNotificationState === PushNotificationState.All - enabled: room.pushNotificationState != PushNotificationState.Unknown - onTriggered: { - room.pushNotificationState = PushNotificationState.All; - } - } - QQC2.MenuItem { - text: i18nc("As in 'notify when the user is mentioned or the message contains a set keyword'", "@Mentions and Keywords") - icon.name: "im-user" - checkable: true - autoExclusive: true - checked: room.pushNotificationState === PushNotificationState.MentionKeyword - enabled: room.pushNotificationState != PushNotificationState.Unknown - onTriggered: { - room.pushNotificationState = PushNotificationState.MentionKeyword; - } - } - QQC2.MenuItem { - text: i18nc("As in 'do not notify for any messages'", "Off") - icon.name: "notifications-disabled" - checkable: true - autoExclusive: true - checked: room.pushNotificationState === PushNotificationState.Mute - enabled: room.pushNotificationState != PushNotificationState.Unknown - onTriggered: { - room.pushNotificationState = PushNotificationState.Mute; - } - } - } - - QQC2.MenuItem { - text: room.isFavourite ? i18n("Remove from Favorites") : i18n("Add to Favorites") - icon.name: room.isFavourite ? "rating" : "rating-unrated" - onTriggered: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0) - } - - QQC2.MenuItem { - text: room.isLowPriority ? i18n("Reprioritize") : i18n("Deprioritize") - icon.name: room.isLowPriority ? "arrow-up-symbolic" : "arrow-down-symbolic" - onTriggered: room.isLowPriority ? room.removeTag("m.lowpriority") : room.addTag("m.lowpriority", 1.0) - } - - QQC2.MenuSeparator {} - - QQC2.MenuItem { - text: room.isDirectChat() ? i18nc("@action:inmenu", "Copy user's Matrix ID to Clipboard") : i18nc("@action:inmenu", "Copy Address to Clipboard") - icon.name: "edit-copy" - onTriggered: if (room.isDirectChat()) { - Clipboard.saveText(room.directChatRemoteMember.id); - } else if (room.canonicalAlias.length === 0) { - Clipboard.saveText(room.id); - } else { - Clipboard.saveText(room.canonicalAlias); - } - } - - QQC2.MenuItem { - text: i18nc("@action:inmenu", "Room Settings") - icon.name: 'settings-configure-symbolic' - onTriggered: { - RoomSettingsView.openRoomSettings(root.room, RoomSettingsView.Room); - } - } - - QQC2.MenuSeparator {} - - QQC2.MenuItem { - text: i18n("Leave Room") - icon.name: "go-previous" - onTriggered: { - Qt.createComponent('org.kde.neochat', 'ConfirmLeaveDialog').createObject(root.QQC2.ApplicationWindow.window, { - room: root.room - }).open(); - } - - } - - onClosed: { - root.closed(); - } - } - } - - Component { - id: mobileMenu - - Kirigami.OverlayDrawer { - id: drawer - - parent: applicationWindow().overlay - edge: Qt.BottomEdge - - height: popupContent.implicitHeight - - leftPadding: 0 - rightPadding: 0 - bottomPadding: 0 - topPadding: 0 - - ColumnLayout { - id: popupContent - - width: parent.width - spacing: 0 - - RowLayout { - id: headerLayout - Layout.fillWidth: true - Layout.margins: Kirigami.Units.largeSpacing - spacing: Kirigami.Units.largeSpacing - KirigamiComponents.Avatar { - id: avatar - source: room.avatarMediaUrl - name: room.displayName - Layout.preferredWidth: Kirigami.Units.gridUnit * 3 - Layout.preferredHeight: Kirigami.Units.gridUnit * 3 - Layout.alignment: Qt.AlignTop - } - Kirigami.Heading { - level: 5 - Layout.fillWidth: true - text: room.displayName - elide: Text.ElideRight - } - QQC2.ToolButton { - checked: room.isFavourite - checkable: true - icon.name: 'favorite' - Accessible.name: room.isFavourite ? i18n("Remove from Favourites") : i18n("Add to Favourites") - onClicked: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0) - } - - QQC2.ToolButton { - text: i18nc("@action:button", "Room Settings") - icon.name: 'settings-configure-symbolic' - onClicked: { - RoomSettingsView.openRoomSettings(root.room, RoomSettingsView.Room); - drawer.close(); - } - } - } - - Delegates.RoundedItemDelegate { - text: room.isLowPriority ? i18n("Reprioritize") : i18n("Deprioritize") - icon.name: room.isLowPriority ? "arrow-up-symbolic" : "arrow-down-symbolic" - onClicked: room.isLowPriority ? room.removeTag("m.lowpriority") : room.addTag("m.lowpriority", 1.0) - Layout.fillWidth: true - } - - Delegates.RoundedItemDelegate { - text: i18n("Mark as Read") - icon.name: "checkmark" - onClicked: room.markAllMessagesAsRead() - Layout.fillWidth: true - } - - Delegates.RoundedItemDelegate { - text: i18n("Leave Room") - icon.name: "go-previous" - onClicked: { - Qt.createComponent('org.kde.neochat', 'ConfirmLeaveDialog').createObject(root.QQC2.ApplicationWindow.window, { - room: root.room - }).open(); - drawer.close(); - } - Layout.fillWidth: true - } - } - - onClosed: root.closed() - } - } - - asynchronous: true - sourceComponent: Kirigami.Settings.isMobile ? mobileMenu : regularMenu - - function open() { - active = true; - } - - onStatusChanged: if (status == Loader.Ready) { - if (Kirigami.Settings.isMobile) { - item.open(); - } else { - item.popup(); - } - } -} diff --git a/src/qml/RoomContextMenu.qml b/src/qml/RoomContextMenu.qml new file mode 100644 index 000000000..e387f3597 --- /dev/null +++ b/src/qml/RoomContextMenu.qml @@ -0,0 +1,158 @@ +// SPDX-FileCopyrightText: 2019 Black Hat +// SPDX-FileCopyrightText: 2020 Carl Schwan +// SPDX-License-Identifier: GPL-3.0-only + +import QtQuick +import QtQuick.Controls as QQC2 +import QtQuick.Layouts + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.components as KirigamiComponents +import org.kde.kirigamiaddons.delegates as Delegates + +import org.kde.neochat +import org.kde.neochat.settings + +/** + * Context menu when clicking on a room in the room list + */ +KirigamiComponents.ConvergentContextMenu { + id: root + + property NeoChatRoom room + required property NeoChatConnection connection + + headerContentItem: RowLayout { + id: headerLayout + Layout.fillWidth: true + spacing: Kirigami.Units.largeSpacing + KirigamiComponents.Avatar { + id: avatar + source: room.avatarMediaUrl + name: room.displayName + Layout.preferredWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2 + Layout.alignment: Qt.AlignTop + } + Kirigami.Heading { + level: 5 + Layout.fillWidth: true + text: room.displayName + elide: Text.ElideRight + } + } + + QQC2.Action { + text: i18n("Mark as Read") + icon.name: "checkmark" + enabled: room.notificationCount > 0 + onTriggered: room.markAllMessagesAsRead() + } + + Kirigami.Action { + separator: true + } + + Kirigami.Action { + text: i18nc("@action:inmenu", "Notifications") + icon.name: "notifications" + + Kirigami.Action { + text: i18n("Follow Global Setting") + icon.name: "globe" + checkable: true + autoExclusive: true + checked: room.pushNotificationState === PushNotificationState.Default + enabled: room.pushNotificationState != PushNotificationState.Unknown + onTriggered: { + room.pushNotificationState = PushNotificationState.Default; + } + } + + Kirigami.Action { + text: i18nc("As in 'notify for all messages'", "All") + icon.name: "notifications" + checkable: true + autoExclusive: true + checked: room.pushNotificationState === PushNotificationState.All + enabled: room.pushNotificationState != PushNotificationState.Unknown + onTriggered: { + room.pushNotificationState = PushNotificationState.All; + } + } + + Kirigami.Action { + text: i18nc("As in 'notify when the user is mentioned or the message contains a set keyword'", "@Mentions and Keywords") + icon.name: "im-user" + checkable: true + autoExclusive: true + checked: room.pushNotificationState === PushNotificationState.MentionKeyword + enabled: room.pushNotificationState != PushNotificationState.Unknown + onTriggered: { + room.pushNotificationState = PushNotificationState.MentionKeyword; + } + } + + Kirigami.Action { + text: i18nc("As in 'do not notify for any messages'", "Off") + icon.name: "notifications-disabled" + checkable: true + autoExclusive: true + checked: room.pushNotificationState === PushNotificationState.Mute + enabled: room.pushNotificationState != PushNotificationState.Unknown + onTriggered: { + room.pushNotificationState = PushNotificationState.Mute; + } + } + } + + QQC2.Action { + text: room.isFavourite ? i18n("Remove from Favorites") : i18n("Add to Favorites") + icon.name: room.isFavourite ? "rating" : "rating-unrated" + onTriggered: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0) + } + + QQC2.Action { + text: room.isLowPriority ? i18n("Reprioritize") : i18n("Deprioritize") + icon.name: room.isLowPriority ? "arrow-up-symbolic" : "arrow-down-symbolic" + onTriggered: room.isLowPriority ? room.removeTag("m.lowpriority") : room.addTag("m.lowpriority", 1.0) + } + + Kirigami.Action { + separator: true + } + + QQC2.Action { + text: room.isDirectChat() ? i18nc("@action:inmenu", "Copy user's Matrix ID to Clipboard") : i18nc("@action:inmenu", "Copy Address to Clipboard") + icon.name: "edit-copy" + onTriggered: if (room.isDirectChat()) { + Clipboard.saveText(room.directChatRemoteMember.id); + } else if (room.canonicalAlias.length === 0) { + Clipboard.saveText(room.id); + } else { + Clipboard.saveText(room.canonicalAlias); + } + } + + QQC2.Action { + text: i18nc("@action:inmenu", "Room Settings") + icon.name: 'settings-configure-symbolic' + onTriggered: { + RoomSettingsView.openRoomSettings(root.room, RoomSettingsView.Room); + } + } + + Kirigami.Action { + separator: true + } + + QQC2.Action { + text: i18n("Leave Room") + icon.name: "go-previous" + onTriggered: { + Qt.createComponent('org.kde.neochat', 'ConfirmLeaveDialog').createObject(root.QQC2.ApplicationWindow.window, { + room: root.room + }).open(); + } + } +} diff --git a/src/qml/RoomDelegate.qml b/src/qml/RoomDelegate.qml index a0d50c309..1dbefeb83 100644 --- a/src/qml/RoomDelegate.qml +++ b/src/qml/RoomDelegate.qml @@ -153,12 +153,12 @@ Delegates.RoundedItemDelegate { } } - function createRoomListContextMenu() { - const component = Qt.createComponent('org.kde.neochat', 'ContextMenu'); + function createRoomListContextMenu(): void { + const component = Qt.createComponent('org.kde.neochat', 'RoomContextMenu'); if (component.status === Component.Error) { console.error(component.errorString()); } - const menu = component.createObject(root, { + const menu = component.createObject(root.ListView.view ?? root.treeView, { room: root.currentRoom, connection: root.connection }); @@ -172,6 +172,6 @@ Delegates.RoundedItemDelegate { return root.hovered && !Kirigami.Settings.isMobile && !NeoChatConfig.compactRoomList; }); }); - menu.open(); + menu.popup(); } }