Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85639065
D351.1786919576.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D351.1786919576.diff
View Options
diff --git a/matrix.org_SILQaiGkYRwqYhnOsbPOAZEE b/matrix.org_SILQaiGkYRwqYhnOsbPOAZEE
new file mode 100644
index 0000000000000000000000000000000000000000..e161d53bf7355d61860ec2167388604847bc652e
GIT binary patch
literal 6710
zc%1E7c~nzZ6Ax6hA60>hMi3zlDxgS6$PO5gB!EhkML@tn5&{W?1hWwkaA_-`0#(EX
zMUW^^l}g<Z0dYYTB2|n~Q4kfQAWan^jRL{%#;Tv^JFVxm`bT??FDIGz=FQBVJ2Stz
z_q}8-qj^s<wls!7Ad`H3$N><@XW!_*pBn;>)RDsj#6nC76$c7p#7PVx8{!!)V6tJp
z35-~F0Gkn=ysC-q1~g7_gF?ljeoKffL4p%QFXJRjNQCGQH<B!o!HQ>#VN7-`m+uaL
zQd19yaiiVgAs9brzeF!KhwGCfWCy0uf><f>EJ8G#v;gKNBLV{nY%v2SOW^TEM43DM
zm0cn@*Rv6D*eelnygU4Nr$YUf!Mp@QHVos0ozFs|F)$p#35j(<69|qllrs{KaK<B$
zF7uICBHEdVLcv}ia4?!MI))fProJ8vT)D$JVsRo7fk;Y9a!PV>5(r}vNCJU?a7H0e
zsQEx*z9^Y5X2|CAMYeA&kl7-Zkeevx3ivSnHG?UTh~44vH&aMR4B*Cc#G<#x`J&gs
z0%1eQ7>Nj^lQTm2N(S+cmY?7IH4+luN{hq+?3njUi-M99*@ytPNFWiiKo(<c-x=!t
zs(QiKb0GRLgz;>UMJj_QV!yiK=SN%$oagcxJhFf#NnrEEzGQc}M8b_GQoQiaE*LKt
z3eMS!f<_|oSgIEpha%u`NEalAihpC^T}8lgiq`A8ppXPI&J%_6^g<#j1OnNax^N-Z
zi-K85B`?H#z0vjMi^L2*i~UBI`#)X6dv%FkLN-Gz5C#bZyf@Xfj3W>WL>xgP%*#t(
zJs6n1AA`l^>zNMvgunKeE#yks(Nv)z0ro2PMD8DWfyR1LC}=zmhgpaNUSRN^R5BGs
z#p3Zu3fhYRX8*fx^dHRrwJ!cobrHZB#Q&Aw8y2W({pnjUfs40rWb;AxgaB-ZwYPI2
zkZI<=WX~YktzWtZ{4KjI&)!S4dzldg3kDzXTl~F8g-1Cg(6iXk*XZz6^1N$7rhx|9
znbHkSoHLo1&l41bqxWQk$&$3M9zN=DU(CYpPJ=+!COj`PgFs+Z1Bj{o@6$|w$OqE~
z`@c__<{wUx#($fxoo@8O)MK;Z-=_LBd?@{p^nZ*p_>lDf<ucf28Na`*`^oBvwJS|Y
zzkWIT)i0|&|3ZA0{n*IEx)=o~KX%lj8VYH##6nA`N9pM<zQ4I5b$>||CiveLk&g?A
zj{%Gi0mR1uhN+wi`9~tNd|xgV@<6rfS8(+8^*y>;G?4z{k*dgT<ZgTCeO+B$ovcjR
zhu+;Htx4EP@o%`s6c3E4)d?>$Hj$F&%$X(%AH6D<%VpuT>u&4vF)_z>IaD?WmbHdH
zyl_8K*C&pPsP+EFAFb5sbX}d6B+;&eX3N#pl#}f>3!oPw#G|LT`C7t<6-i^8Lr`sM
zX%FGp74Nym4ff1!r;U2mYIQWK<0dqFdUh=DIJdSUaA%`4Ycul7>^!F0)*X+}tlCby
zXrJldU~dtvl)2>y!$wNF!YPEAHa6Ony3{Fi3mMxBT4JuagpuxqA*ae=R5SUk2Yr29
zv}KxZ7_)^p9C)aWNFwE?H?u3y8!QYgFGM_<Jt<zGQ!164OXpHA+PD3<+xoh0Lh+WZ
z>GhEpt1Qk9sT4b|7Lg+9^f{p=HV;P*+`svoR=bo&!zQ<!jkB;c3ABpaj8=U)-$r{e
zs7GtMrW<qvUYNhRS!YH@M)h%@ZJcd^LrRTCqevLZitdea_EF!Y7skD~?PIlu?maov
z9~J_(p<UH2Ps)<(FD~Q~2exrHEZEeCAM?5Xxe^V%Y=AVr;feOX(RlA3BgbMGwHIzs
zRdaX->x#QqQC9Mtsl%XP9`_6nr}S%rDd9;qT`iHt7Lmgb9?Uu;p8vC%;##iV=6Vds
zetWSSVoh@L3We&268p&}Cb$)}yrx-U^9Q<uo*Yrj&NoC&>CQ3&4oUpE7(C+TLHn}2
zyu5?)HA{|9O5G<;&(5-2N=Xs|kS`ONEm5uS%}K4#YubN3@Hds=;N-ov))U7|>R<+@
za*yTBb(j;8rn-1UaI0M2%9#f(D;*Ty`c@+Wh1kC;Ep4Xi`0g1c3e8<jaL<nFncY$J
z$?Y?rfymX;X*Hs_Gmovam*%(j8}c4@Oub^zV82#)u-03lc0HL#nzGc{-I!@!ymj<o
zw@2_DX&^m4?&ln9BcyRLImAX0SH+lHH7|K8TrYH2(po$+GO}o>e#2n<JdWZ@K#5{v
z^C9%Q=|<A7=1pq~`fO&$aTag9mXwXk^p7fAd_$70m_Bj5Vu^3o5AE_`74WDgyo4Cl
zw4yF-S6&l2>j$^+_(2$TU7<)QEFtd*F~3NnwO^W*-`mVg`TE>hD*!y#S<OxHE@zgH
zQ$|9cHrL=+++LmgxvnXiIa#mgT;P&XwXrj`dhH{}!P60Rx}|NVfAQF!W$C&7{r$17
zyCT$;PRLNZelRp9gdc{=&^~wBIjlQ#XlDEE;bv<P{8+xjaJsy;Ji;n_;)$(QQbAgl
z0T{QVa&wiFidJgBS{_=%{K*PtYm*HLZIro5MI#aisCNZ2<mcf++9fL(G?=>XfPJgx
zXi7*QFB=M)HZOaVeib|0Zcbr@yMq<rX2FrjdP_t7Sxze_dee0MSxoM0&VY>fIVh+o
zSI|Z}w@%a>Xo*H4$NB6Di82gm<za8DrH9&X-M+p0w<5kk(4$r=^F}m>v2C(Py}iAv
zH9Fl$65+ZmT%lgjGw}TW{qsstRA;*>b`oM??|zimju-WA3l`jINqafAa`)JY1yI|x
z{zJ^|RgY@x>x-7m(QuTgqpUf5r+;_&&0>nSRHTNEhT{uq+3`kQ{HjI-_h!E)CpWi8
z?K<x(qU}+xoAv4!mlCDYV47s51@!BRbCb57NgJ7#H!yVb>{U4BTwH{UF^{(YQCnLZ
zm^z=&FEP1OPoG-!)q<s?=LerYtvq(_$DMIOKc8MSbRo4h1#i_D)uVK(<`kAbvorzW
zM-9zwF7192vg#*voI^q1rCb}8W=oCjm$j$AcM_7u&oGHBwLKa)nQ4AgvV4Ma;WkdR
zGKUwMHMW;lw&m`OQ!vySvRmq|lVd$S@*PY=r13B1nLD$Ml;;!ioliqLYw1Uz+~@5&
z-zNf{3@xg)I#0!!%FjA&3`&v7ZYDbCH-F*Ve@hO9LUA};_={ifZ+dvj=JKu-AoEjJ
z)Ghwx?FyM@2JiS?U~U-spiQpTYR49>2RQICJ{R;G$I7>5{B9qkhi!7Yxp{+qW%%p@
zTIrsaHdZAt>6?Za@OX5zs0jmF>bjMyB$E8F(McH>4h!;DJl3Q*IATf1Di()mKx<xG
zpE*&j9r=Fd@*4r`Ewpn~D}$77m4kzWjxoKz(tvisyvRzs7FNF|CA{NCy^}-t_jA*A
zmznoEHUM8eT4txmUyYddlumSYU0l0=Fm2Tw5L%2GVe51HcKVSWJ^At#5iHZ{J!8DC
zuKxfmgqy+tL!Uc*9W;6AF?SN_Dl=o*@G(gXaHaU9uzE+VR4dy!vF_9<=Wt+XwCtyd
zX&JZTP6(?JF%CP}t-_OabcD)Q9B&5(cUPTARy}`?m&;q&E6|%dh<+wa^YVS0w^N`K
z_9*u4Ei6<Wbu8%O=^HXxsvT;w-}x-8LFY^gjQl#}v|)q&ciGaK!X9Smv`d{l?3DU(
zF5319fLpgjU|V$2y3}eh+RDmmf2u4uH+Sq7i2Y+*WfTC(;+L>vuHHqI-cA0%i;6|)
zBWg_bxIhQxU{`V%;S0cP%*n|?xj!4ib&#*KEr)kmV?iWGAJi<Lt()GGGUL08{$O(X
z@z~u3a$=U?vlLDBJ+pBjIu)Hy?&duos0p_NXdRo~f55dO!eQ}4uwabyZWNMQbbU%Y
z6F9IHN62*?0(};?Gw$+u7%*0TprT2a5>a0cwqwg?9J#E`(WQp~0m#&5-N_YzS-$-M
z0)Vy>!$%#|fEym}9guOax1bLizkutvaY$ppxO3S^4hD>h=N*{v={fBmwHy2+`ZO4<
z8rN^|s{m|+59N>Wdcu3fMC+lA`w6$N@vyq6b>rUI_B|^)px^XCc0HEXQ2ZSSw`^SB
zhW9i1*Ua|QONl=zc8uXa_#tqS)5a1GZ&7_WE-?z)kXw_j<7C_PjL-QCMFyLc-NB0i
y1M$Ai|Ma~3uYUnl{^>>JU#YjXj-!!l4IrZ)h1k!M4^P(rljBRFk$+eiwf?`vZ2yJ;
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
Details
Attached
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)
Attached To
Mode
D351: Make shortcuts of SendMessageBox.qml configurable
Attached
Detach File
Event Timeline
Log In to Comment