Page MenuHomePhorge

D351.1786919576.diff
No OneTemporary

Size
10 KB
Referenced Files
None
Subscribers
None

D351.1786919576.diff

diff --git a/matrix.org_SILQaiGkYRwqYhnOsbPOAZEE b/matrix.org_SILQaiGkYRwqYhnOsbPOAZEE
new file mode 100644
index 0000000000000000000000000000000000000000..e161d53bf7355d61860ec2167388604847bc652e
GIT binary patch
literal 6710
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
literal 0
Hc$@<O00001
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -267,6 +267,7 @@
device-mgmt/DeviceList.qml
UserPage.qml
+ KazvAction.qml
shortcuts/ActionCollection.qml
shortcuts/ActionItem.qml
diff --git a/src/contents/ui/KazvAction.qml b/src/contents/ui/KazvAction.qml
new file mode 100644
--- /dev/null
+++ b/src/contents/ui/KazvAction.qml
@@ -0,0 +1,27 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2026 nannanko <nannanko@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import QtQml
+
+import org.kde.kirigami as Kirigami
+
+Kirigami.Action {
+ id: action
+ property Kirigami.Action globalAction: actionCollection ? actionCollection.action(objectName) : null
+ icon.name: globalAction?.icon.name || ''
+ text: globalAction?.text || ''
+ shortcut: globalAction.shortcut
+
+ property var conn: Connections {
+ target: globalAction
+ function onTriggered() {
+ if (!action.enabled) {
+ return;
+ }
+ action.onTriggered();
+ }
+ }
+}
diff --git a/src/contents/ui/Main.qml b/src/contents/ui/Main.qml
--- a/src/contents/ui/Main.qml
+++ b/src/contents/ui/Main.qml
@@ -240,11 +240,37 @@
actions: Kirigami.Settings.isMobile ? (pageStack.currentItem?.actions || []) : []
}
+ property var roomPageActions: QtObject {
+ property list<Kirigami.Action> actions: [
+ Kirigami.Action {
+ objectName: 'send-message'
+ icon.name: 'document-send'
+ text: l10n.get('send-message-box-send')
+ property var defaultShortcut: 'Ctrl+Return'
+ },
+ Kirigami.Action {
+ objectName: 'send-file'
+ icon.name: 'document-open-data'
+ text: l10n.get('send-message-box-send-file')
+ },
+ Kirigami.Action {
+ objectName: 'send-stickers'
+ icon.name: 'smiley'
+ text: l10n.get('send-message-box-stickers')
+ },
+ Kirigami.Action {
+ objectName: 'remove-related-to-event'
+ icon.name: 'window-close-symbolic'
+ }
+ ]
+ }
+
property var actionCollection: KazvShortcuts.ActionCollection {
id: globalActionCollection
children: [
root.globalDrawer,
root.contextDrawer,
+ root.roomPageActions
]
shortcutsConfig: kazvConfig
}
diff --git a/src/contents/ui/SendMessageBox.qml b/src/contents/ui/SendMessageBox.qml
--- a/src/contents/ui/SendMessageBox.qml
+++ b/src/contents/ui/SendMessageBox.qml
@@ -221,7 +221,6 @@
TextArea {
id: textArea
objectName: 'draftMessage'
- property var shortcutList: ["Ctrl+Return", "Ctrl+Enter"]
property var inhibitTyping: false
placeholderText: l10n.get('send-message-box-input-placeholder')
property string filter: getFilter()
@@ -273,14 +272,6 @@
}
}
- // Shortcut keys for sending messages (TODO: Shortcut keys customized by the user)
- Shortcut {
- sequences: textArea.shortcutList
- onActivated: {
- sendAction.trigger()
- }
- }
-
DropArea {
anchors.fill: parent
onDropped: (drag) => {
@@ -411,9 +402,9 @@
textArea.forceActiveFocus();
}
- Kirigami.Action {
+ Kazv.KazvAction {
id: removeRelatedToAction
- icon.name: 'window-close-symbolic'
+ objectName: 'remove-related-to-event'
text: getCancelRelationPrompt(sendMessageBox.draftRelType)
onTriggered: {
if (textArea.text) {
@@ -424,10 +415,9 @@
}
}
- Kirigami.Action {
+ Kazv.KazvAction {
id: sendAction
- icon.name: "document-send"
- text: l10n.get("send-message-box-send")
+ objectName: 'send-message'
onTriggered: {
room.setTyping(false);
room.sendTextMessage(textArea.text, draftRelType, draftRelatedTo);
@@ -436,10 +426,9 @@
}
enabled: textArea.text !== ''
}
- Kirigami.Action {
+ Kazv.KazvAction {
id: sendMediaFileAction
- icon.name: "document-open-data"
- text: l10n.get("send-message-box-send-file")
+ objectName: 'send-file'
onTriggered: {
fileDialog.open()
}
@@ -486,10 +475,9 @@
}
}
- Kirigami.Action {
+ Kazv.KazvAction {
id: stickersAction
- icon.name: 'smiley'
- text: l10n.get('send-message-box-stickers')
+ objectName: 'send-stickers'
onTriggered: stickerPopup.open()
}
}
diff --git a/src/contents/ui/shortcuts/ActionCollection.qml b/src/contents/ui/shortcuts/ActionCollection.qml
--- a/src/contents/ui/shortcuts/ActionCollection.qml
+++ b/src/contents/ui/shortcuts/ActionCollection.qml
@@ -81,7 +81,7 @@
allActions().forEach((action) => {
const name = action.objectName;
const shortcuts = shortcutsConfig.shortcutForAction(name);
- action.shortcut = shortcuts[0] || '';
+ action.shortcut = shortcuts.length ? shortcuts[0] || '' : action.defaultShortcut || '';
});
}
}
diff --git a/src/tests/quick-tests/tst_SendMessageBox.qml b/src/tests/quick-tests/tst_SendMessageBox.qml
--- a/src/tests/quick-tests/tst_SendMessageBox.qml
+++ b/src/tests/quick-tests/tst_SendMessageBox.qml
@@ -56,6 +56,26 @@
}
}
+ // Mirror the global action the application registers for the send
+ // shortcut, so that KazvAction in SendMessageBox can resolve it.
+ property var sendMessageGlobalAction: Kirigami.Action {
+ objectName: 'send-message'
+ shortcut: 'Ctrl+Enter'
+ }
+
+ property var actionCollection: QtObject {
+ property var actions: [item.sendMessageGlobalAction]
+
+ function action(name) {
+ for (let i = 0; i < actions.length; ++i) {
+ if (actions[i].objectName === name) {
+ return actions[i];
+ }
+ }
+ return null;
+ }
+ }
+
Kazv.SendMessageBox {
id: sendMessageBox
y: 400
@@ -208,12 +228,16 @@
verify(room.sendTextMessage.calledTimes() === 0);
const textArea = findChild(sendMessageBox, 'draftMessage');
- mouseClick(textArea);
- tryVerify(() => textArea.activeFocus);
- keySequence('Ctrl+Enter');
- verify(room.sendTextMessage.calledTimes() === 0);
- keySequence('Ctrl+Return');
+
+ // The configured send shortcut must not send an empty message.
+ item.sendMessageGlobalAction.trigger();
verify(room.sendTextMessage.calledTimes() === 0);
+
+ // It should send and clear the box once the input is non-empty.
+ textArea.text = 'some test';
+ item.sendMessageGlobalAction.trigger();
+ tryVerify(() => room.sendTextMessage.calledTimes() === 1);
+ verify(textArea.text === '');
}
function test_replyWithFile() {

File Metadata

Mime Type
text/plain
Expires
Sun, Aug 16, 3:32 PM (22 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1730526
Default Alt Text
D351.1786919576.diff (10 KB)

Event Timeline