Add user menu that is opened via right-clicking/long-tapped on avatar
We can un-clutter our message context menu, which we had to share with user actions. (Even though we only had one so far.) I added one new user-specific action which allows you to quickly mention the user in chat. Otherwise you would've had to copy their username or use the completion menu. It's convergent on mobile, it still has the hover indicator and it also is available through the AuthorComponent. BUG: 486252
This commit is contained in:
@@ -101,6 +101,7 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
||||
qml/AvatarNotification.qml
|
||||
qml/ReasonDialog.qml
|
||||
qml/NewPollDialog.qml
|
||||
qml/UserMenu.qml
|
||||
DEPENDENCIES
|
||||
QtCore
|
||||
QtQuick
|
||||
|
||||
35
src/app/qml/UserMenu.qml
Normal file
35
src/app/qml/UserMenu.qml
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
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.neochat
|
||||
import org.kde.neochat.settings
|
||||
import org.kde.neochat.devtools
|
||||
|
||||
KirigamiComponents.ConvergentContextMenu {
|
||||
id: root
|
||||
|
||||
required property NeoChatConnection connection
|
||||
required property Kirigami.ApplicationWindow window
|
||||
required property var author
|
||||
|
||||
QQC2.Action {
|
||||
text: i18nc("@action:button", "Open Profile")
|
||||
icon.name: "im-user-symbolic"
|
||||
onTriggered: RoomManager.resolveResource(root.author.uri)
|
||||
}
|
||||
|
||||
QQC2.Action {
|
||||
text: i18nc("@action:button", "Mention")
|
||||
icon.name: "username-copy-symbolic"
|
||||
onTriggered: {
|
||||
RoomManager.currentRoom.mainCache.mentionAdded(root.author.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,19 @@ QQC2.Control {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: currentRoom.mainCache
|
||||
|
||||
function onMentionAdded(mention: string): void {
|
||||
// add mention text
|
||||
textField.append(mention + " ");
|
||||
// move cursor to the end
|
||||
textField.cursorPosition = textField.text.length;
|
||||
// move the focus back to the chat bar
|
||||
textField.forceActiveFocus(Qt.OtherFocusReason);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The list of actions in the ChatBar.
|
||||
*
|
||||
|
||||
@@ -195,6 +195,7 @@ Q_SIGNALS:
|
||||
void relationIdChanged(const QString &oldEventId, const QString &newEventId);
|
||||
void threadIdChanged(const QString &oldThreadId, const QString &newThreadId);
|
||||
void attachmentPathChanged();
|
||||
void mentionAdded(const QString &mention);
|
||||
|
||||
private:
|
||||
QString m_text = QString();
|
||||
|
||||
@@ -41,21 +41,43 @@ RowLayout {
|
||||
|
||||
implicitHeight: Math.max(nameButton.implicitHeight, timeLabel.implicitHeight)
|
||||
|
||||
QQC2.AbstractButton {
|
||||
QQC2.Label {
|
||||
id: nameButton
|
||||
contentItem: QQC2.Label {
|
||||
text: root.author.disambiguatedName
|
||||
color: root.author.color
|
||||
textFormat: Text.PlainText
|
||||
font.weight: Font.Bold
|
||||
elide: Text.ElideRight
|
||||
|
||||
text: root.author.disambiguatedName
|
||||
color: root.author.color
|
||||
textFormat: Text.PlainText
|
||||
font.weight: Font.Bold
|
||||
elide: Text.ElideRight
|
||||
|
||||
function openUserMenu(): void {
|
||||
const menu = Qt.createComponent("org.kde.neochat", "UserMenu").createObject(root, {
|
||||
connection: root.connection,
|
||||
window: QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow,
|
||||
author: root.author,
|
||||
});
|
||||
menu.popup(root);
|
||||
}
|
||||
Accessible.name: contentItem.text
|
||||
onClicked: RoomManager.resolveResource(root.author.uri)
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
// tapping to open profile
|
||||
TapHandler {
|
||||
onTapped: RoomManager.resolveResource(root.author.uri)
|
||||
}
|
||||
|
||||
// right-clicking/long-press for context menu
|
||||
TapHandler {
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: nameButton.openUserMenu()
|
||||
}
|
||||
TapHandler {
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
onTapped: nameButton.openUserMenu()
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
@@ -73,16 +95,4 @@ RowLayout {
|
||||
id: timeHoverHandler
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
onLongPressed: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink);
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
onTapped: RoomManager.viewEventMenu(root.eventId, root.Message.room, root.author, root.Message.selectedText, root.Message.hoveredLink);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,14 +142,6 @@ KirigamiComponents.ConvergentContextMenu {
|
||||
}
|
||||
}
|
||||
|
||||
component ShowUserAction: Kirigami.Action {
|
||||
text: i18nc("@action:inmenu", "Show User")
|
||||
icon.name: "username-copy"
|
||||
onTriggered: {
|
||||
RoomManager.resolveResource(author.id)
|
||||
}
|
||||
}
|
||||
|
||||
component PinMessageAction: Kirigami.Action {
|
||||
readonly property bool pinned: currentRoom.isEventPinned(root.eventId)
|
||||
|
||||
|
||||
@@ -94,8 +94,6 @@ DelegateContextMenu {
|
||||
|
||||
DelegateContextMenu.ReportMessageAction {}
|
||||
|
||||
DelegateContextMenu.ShowUserAction {}
|
||||
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
visible: viewSourceAction.visible
|
||||
|
||||
@@ -149,6 +149,7 @@ MessageDelegateBase {
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: _private.showMessageMenu()
|
||||
}
|
||||
|
||||
@@ -159,7 +160,7 @@ MessageDelegateBase {
|
||||
}
|
||||
}
|
||||
|
||||
avatarComponent: KirigamiComponents.AvatarButton {
|
||||
avatarComponent: KirigamiComponents.Avatar {
|
||||
id: avatar
|
||||
implicitWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||
implicitHeight: width
|
||||
@@ -170,7 +171,34 @@ MessageDelegateBase {
|
||||
asynchronous: true
|
||||
QQC2.ToolTip.text: root.author.htmlSafeDisambiguatedName
|
||||
|
||||
onClicked: RoomManager.resolveResource(root.author.uri)
|
||||
function openUserMenu(): void {
|
||||
const menu = Qt.createComponent("org.kde.neochat", "UserMenu").createObject(root, {
|
||||
connection: root.connection,
|
||||
window: QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow,
|
||||
author: root.author,
|
||||
});
|
||||
menu.popup(root);
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
// tapping to open profile
|
||||
TapHandler {
|
||||
onTapped: RoomManager.resolveResource(root.author.uri)
|
||||
}
|
||||
|
||||
// right-clicking/long-press for context menu
|
||||
TapHandler {
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: avatar.openUserMenu()
|
||||
}
|
||||
TapHandler {
|
||||
acceptedDevices: PointerDevice.TouchScreen
|
||||
onTapped: avatar.openUserMenu()
|
||||
}
|
||||
}
|
||||
|
||||
sectionComponent: SectionDelegate {
|
||||
|
||||
@@ -102,7 +102,6 @@ DelegateContextMenu {
|
||||
}
|
||||
DelegateContextMenu.PinMessageAction {}
|
||||
DelegateContextMenu.ReportMessageAction {}
|
||||
DelegateContextMenu.ShowUserAction {}
|
||||
Kirigami.Action {
|
||||
separator: true
|
||||
visible: viewSourceAction.visible
|
||||
|
||||
Reference in New Issue
Block a user