Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F62410088
D245.1775892632.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D245.1775892632.diff
View Options
diff --git a/src/contents/ui/Bubble.qml b/src/contents/ui/Bubble.qml
--- a/src/contents/ui/Bubble.qml
+++ b/src/contents/ui/Bubble.qml
@@ -75,8 +75,7 @@
objectName: 'editMenuItem'
text: l10n.get('event-edit-action')
onTriggered: {
- setDraftRelation('m.replace', currentEvent.eventId);
- replaceDraftRequested(Helpers.getEventBodyForEditing(event));
+ setDraftRelation('m.replace', currentEvent.eventId, Helpers.getEventBodyForEditing(event));
}
enabled: event && !event.redacted && !event.isLocalEcho && getIsEditable(event)
},
diff --git a/src/contents/ui/ConfirmationOverlay.qml b/src/contents/ui/ConfirmationOverlay.qml
--- a/src/contents/ui/ConfirmationOverlay.qml
+++ b/src/contents/ui/ConfirmationOverlay.qml
@@ -20,6 +20,7 @@
default property alias contentData: itemsLayout.data
signal accepted()
+ signal canceled()
ColumnLayout {
Label {
@@ -47,7 +48,10 @@
Button {
objectName: 'cancelButton'
text: cancelActionText
- onClicked: confirmationOverlay.close();
+ onClicked: {
+ canceled();
+ confirmationOverlay.close();
+ }
}
}
}
diff --git a/src/contents/ui/RoomPage.qml b/src/contents/ui/RoomPage.qml
--- a/src/contents/ui/RoomPage.qml
+++ b/src/contents/ui/RoomPage.qml
@@ -180,9 +180,8 @@
}
}
- function setDraftRelation(relType, eventId) {
- sendMessageBox.draftRelType = relType;
- sendMessageBox.draftRelatedTo = eventId;
+ function setDraftRelation(relType, eventId, newDraft) {
+ sendMessageBox.setDraftRelation(relType, eventId, newDraft);
}
property var joinRoomHandler: Kazv.AsyncHandler {
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
@@ -16,11 +16,41 @@
ColumnLayout {
id: sendMessageBox
+ objectName: 'sendMessageBox'
property var room
- property var draftRelType: ''
- property var draftRelatedTo: ''
+ property var draftRelType: room.draftRelType
+ property var draftRelatedTo: room.draftRelTo
property var timeline: room.timeline()
property var members: room.members()
+ property var changeDraftRelTypes: ['m.replace']
+ property bool isDraftSaved: false
+
+ property var confirmSaveDraftOverlay: Kazv.ConfirmationOverlay {
+ objectName: 'confirmSaveDraftOverlay'
+ parent: Overlay.overlay
+ title: l10n.get('save-draft-confirmation-title')
+ message: l10n.get('save-draft-confirmation')
+ confirmActionText: l10n.get('save-draft-confirm-action')
+ cancelActionText: l10n.get('save-draft-cancel-action')
+
+ property var relType
+ property var relTo
+ property var newDraft
+
+ onAccepted: {
+ room.pushLocalDraft(newDraft, relType, relTo)
+ .succeeded.connect(() => {
+ textArea.changeText(room.localDraft);
+ });
+ }
+
+ onCanceled: {
+ room.setLocalDraft(newDraft, relType, relTo)
+ .succeeded.connect(() => {
+ textArea.changeText(room.localDraft);
+ });;
+ }
+ }
function getRelationPrompt(draftRelType) {
if (draftRelType === 'm.in_reply_to') {
@@ -42,6 +72,27 @@
textArea.changeText(newDraft, /* inhibitTyping = */ true);
}
+ function setDraftRelation(relType, eventId, newDraft) {
+ if (!changeDraftRelTypes.includes(relType)) {
+ room.setLocalDraftRel(relType, eventId);
+ return;
+ }
+ if (textArea.text === '') {
+ room.setLocalDraft(newDraft, relType, eventId);
+ }
+
+ confirmSaveDraftOverlay.relType = relType;
+ confirmSaveDraftOverlay.relTo = eventId;
+ confirmSaveDraftOverlay.newDraft = newDraft;
+ confirmSaveDraftOverlay.open();
+ }
+
+ function resetDraftRelation() {
+ room.popLocalDraft().succeeded.connect(() => {
+ textArea.changeText(room.localDraft, true);
+ });
+ }
+
onRoomChanged: {
textArea.changeText(room.localDraft, true);
}
@@ -129,7 +180,7 @@
wrapMode: TextEdit.Wrap
persistentSelection: true
onTextChanged: {
- room.setLocalDraft(text);
+ room.setLocalDraftText(text);
if (!inhibitTyping) {
room.setTyping(true);
}
@@ -316,8 +367,7 @@
icon.name: 'window-close-symbolic'
text: getCancelRelationPrompt(sendMessageBox.draftRelType)
onTriggered: {
- sendMessageBox.draftRelType = '';
- sendMessageBox.draftRelatedTo = '';
+ sendMessageBox.resetDraftRelation();
}
}
@@ -329,8 +379,7 @@
room.setTyping(false);
room.sendTextMessage(textArea.text, draftRelType, draftRelatedTo);
textArea.changeText("", true);
- sendMessageBox.draftRelType = '';
- sendMessageBox.draftRelatedTo = '';
+ sendMessageBox.resetDraftRelation();
}
enabled: textArea.text !== ''
}
@@ -364,8 +413,7 @@
room.roomId, sdkVars.roomList, room.encrypted,
draftRelType, draftRelatedTo
);
- sendMessageBox.draftRelType = '';
- sendMessageBox.draftRelatedTo = '';
+ sendMessageBox.resetDraftRelation();
}
property var stickerPopup: Kirigami.OverlaySheet {
@@ -379,8 +427,7 @@
onSendMessageRequested: eventJson => {
console.log(JSON.stringify(eventJson));
room.sendMessage(eventJson, draftRelType, draftRelatedTo);
- draftRelType = '';
- draftRelatedTo = '';
+ sendMessageBox.resetDraftRelation();
stickerPopup.close();
}
}
diff --git a/src/l10n/cmn-Hans/100-ui.ftl b/src/l10n/cmn-Hans/100-ui.ftl
--- a/src/l10n/cmn-Hans/100-ui.ftl
+++ b/src/l10n/cmn-Hans/100-ui.ftl
@@ -163,6 +163,11 @@
send-message-box-stickers = 发送贴纸...
send-message-box-stickers-popup-title = 发送贴纸
+save-draft-confirmation-title = 保存草稿
+save-draft-confirmation = 需要保存草稿吗?
+save-draft-confirm-action = 保存
+save-draft-cancel-action = 不保存
+
sticker-picker-user-stickers = 我的贴纸
sticker-picker-room-sticker-pack-name = {$room} 中的 {$stateKey}
sticker-picker-room-default-sticker-pack-name = {$room} 中的默认包
diff --git a/src/l10n/en/100-ui.ftl b/src/l10n/en/100-ui.ftl
--- a/src/l10n/en/100-ui.ftl
+++ b/src/l10n/en/100-ui.ftl
@@ -167,6 +167,11 @@
send-message-box-stickers = Send a sticker...
send-message-box-stickers-popup-title = Send a sticker
+save-draft-confirmation-title = Save draft
+save-draft-confirmation = Do you want save your draft?
+save-draft-confirm-action = Yes
+save-draft-cancel-action = No
+
sticker-picker-user-stickers = My stickers
sticker-picker-room-sticker-pack-name = {$stateKey} in {$room}
sticker-picker-room-default-sticker-pack-name = Default pack in {$room}
diff --git a/src/matrix-room.hpp b/src/matrix-room.hpp
--- a/src/matrix-room.hpp
+++ b/src/matrix-room.hpp
@@ -62,6 +62,8 @@
LAGER_QT_READER(QString, avatarMxcUri);
LAGER_QT_READER(QString, roomOrHeroAvatarMxcUri);
LAGER_QT_READER(QString, localDraft);
+ LAGER_QT_READER(QString, draftRelType);
+ LAGER_QT_READER(QString, draftRelTo);
LAGER_QT_READER(bool, encrypted);
LAGER_QT_READER(bool, tombstoned);
@@ -120,9 +122,20 @@
Q_INVOKABLE void setTyping(bool typing);
- Q_INVOKABLE void setLocalDraft(QString localDraft);
+ Q_INVOKABLE void setLocalDraftText(QString localDraft);
- Q_INVOKABLE void updateLocalDraftNow();
+ Q_INVOKABLE void updateLocalDraftTextNow();
+
+ Q_INVOKABLE MatrixPromise *pushLocalDraft(const QString &localDraft,
+ const QString &draftRelType, const QString &draftRelTo);
+
+ Q_INVOKABLE MatrixPromise *popLocalDraft();
+
+ Q_INVOKABLE MatrixPromise *setLocalDraft(const QString &localDraft,
+ const QString &draftRelType, const QString &draftRelTo);
+
+ Q_INVOKABLE MatrixPromise *setLocalDraftRel(
+ const QString draftRelType, const QString draftRelTo);
Q_INVOKABLE MatrixPromise *addOrSetTag(QString tagId) const;
diff --git a/src/matrix-room.cpp b/src/matrix-room.cpp
--- a/src/matrix-room.cpp
+++ b/src/matrix-room.cpp
@@ -6,6 +6,7 @@
#include <kazv-defs.hpp>
+#include <qobject.h>
#include <string>
#include <lager/setter.hpp>
@@ -73,7 +74,27 @@
return std::string();
})
.xform(strToQt))
- , LAGER_QT(localDraft)(m_room.localDraft().xform(strToQt))
+ , LAGER_QT(localDraft)(m_room.localDrafts().map(
+ [](immer::flex_vector<Kazv::LocalDraft> drafts) {
+ if (drafts.empty()) {
+ return std::string{""};
+ }
+ return drafts.front().text;
+ }).xform(strToQt))
+ , LAGER_QT(draftRelType)(m_room.localDrafts().map(
+ [](immer::flex_vector<Kazv::LocalDraft> drafts) {
+ if (drafts.empty()) {
+ return std::string{""};
+ }
+ return drafts.front().relType;
+ }).xform(strToQt))
+ , LAGER_QT(draftRelTo)(m_room.localDrafts().map(
+ [](immer::flex_vector<Kazv::LocalDraft> drafts) {
+ if (drafts.empty()) {
+ return std::string{""};
+ }
+ return drafts.front().relatedEventId;
+ }).xform(strToQt))
, LAGER_QT(encrypted)(m_room.encrypted())
, LAGER_QT(tombstoned)(m_room.stateOpt({"m.room.tombstone"s, ""s}).map(
[](auto c) { return c.has_value(); }))
@@ -96,7 +117,7 @@
}, typingDebounceMs))
, m_updateLocalDraftDebounced(QFunctionUtils::Debounce([self=QPointer<MatrixRoom>(this)]() {
if (self) {
- self->updateLocalDraftNow();
+ self->updateLocalDraftTextNow();
}
}, saveDraftDebounceMs))
, m_internalLocalDraft(std::nullopt)
@@ -107,7 +128,7 @@
}
MatrixRoom::~MatrixRoom() {
- updateLocalDraftNow();
+ updateLocalDraftTextNow();
}
MatrixRoomTimeline *MatrixRoom::timeline() const
@@ -468,7 +489,9 @@
m_room.setTyping(true, typingTimeoutMs);
}
-void MatrixRoom::setLocalDraft(QString localDraft)
+
+
+void MatrixRoom::setLocalDraftText(QString localDraft)
{
// To avoid heavy computations when updating the local draft again
// and again, we only set our internal state. **Assume only
@@ -479,14 +502,41 @@
m_updateLocalDraftDebounced();
}
-void MatrixRoom::updateLocalDraftNow()
+void MatrixRoom::updateLocalDraftTextNow()
{
if (m_internalLocalDraft.has_value()) {
- m_room.setLocalDraft(m_internalLocalDraft.value().toStdString());
+ m_room.setLocalDraftText(m_internalLocalDraft.value().toStdString());
m_internalLocalDraft = std::nullopt;
}
}
+MatrixPromise *MatrixRoom::pushLocalDraft(const QString &localDraft,
+ const QString &draftRelType, const QString &draftRelTo)
+{
+ updateLocalDraftTextNow();
+ return new MatrixPromise(m_room.pushLocalDraft(localDraft.toStdString(),
+ draftRelType.toStdString(), draftRelTo.toStdString()));
+}
+
+MatrixPromise *MatrixRoom::popLocalDraft()
+{
+ return new MatrixPromise(m_room.popLocalDraft());
+}
+
+MatrixPromise *MatrixRoom::setLocalDraft(const QString &localDraft,
+ const QString &draftRelType, const QString &draftRelTo)
+{
+ return new MatrixPromise(m_room.setLocalDraft(localDraft.toStdString(),
+ draftRelType.toStdString(), draftRelTo.toStdString()));
+}
+
+MatrixPromise *MatrixRoom::setLocalDraftRel(
+ const QString draftRelType, const QString draftRelTo)
+{
+ return new MatrixPromise(m_room.setLocalDraftRel(draftRelType.toStdString(),
+ draftRelTo.toStdString()));
+}
+
MatrixRoomMemberListModel *MatrixRoom::members() const
{
return new MatrixRoomMemberListModel(
diff --git a/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml b/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml
--- a/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml
+++ b/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml
@@ -39,6 +39,7 @@
property var room: makeRoom()
property var room2: makeRoom()
+ property var room3: makeRoom()
property var sendMessageBoxComp: Component {
id: comp
@@ -74,6 +75,23 @@
}
}
+ property var sendMessageBoxComp3: Component {
+ id: comp3
+ Kirigami.Page {
+ id: page
+ Label {
+ text: 'room 3'
+ }
+ footer: Item {
+ height: childrenRect.height
+ width: parent.width
+ Kazv.SendMessageBox {
+ room: item.room3
+ }
+ }
+ }
+ }
+
property var mockMainPageComp: Component {
id: mockMainPageComp
Kirigami.Page {}
@@ -88,6 +106,11 @@
name: 'SendMessageBoxDraftsTest'
when: windowShown
+ function init() {
+ window.pageStack.clear();
+ mockHelper.clearAll();
+ }
+
function test_saveDraftsOnSwitching() {
// simulates the MainPage when starting up kazv
window.pageStack.push(mockMainPageComp);
@@ -114,5 +137,23 @@
tryVerify(() => item.room.localDraft === 'foo', 1000);
verify(item.room.updateLocalDraftNow.calledTimes() === 1);
}
+
+ function test_restoreDraftOnExitEditing() {
+ window.pageStack.push(comp3);
+ const sendMessageBox = findChild(window.pageStack, 'sendMessageBox');
+ const textArea = findChild(window.pageStack, 'draftMessage');
+ textArea.text = 'some draft';
+ sendMessageBox.setDraftRelation('m.replace', '$someevent');
+ // m.replace will change textArea
+ textArea.text = 'foo';
+ // Old draft has been saved.
+ compare(sendMessageBox.oldDraft, 'some draft');
+ // Exit editing
+ sendMessageBox.resetDraftRelation();
+ // Old draft has been restored.
+ compare(textArea.text, 'some draft');
+
+ window.pageStack.clear();
+ }
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 11, 12:30 AM (20 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1307324
Default Alt Text
D245.1775892632.diff (13 KB)
Attached To
Mode
D245: Restore draft after editing
Attached
Detach File
Event Timeline
Log In to Comment