From 50888a286580e58d24c82b6f9b7ce9cbc5709193 Mon Sep 17 00:00:00 2001
From: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
Date: Wed, 30 Nov 2022 14:56:38 -0300
Subject: [PATCH] shortcut: add option to edit last sent message

GitLab: #892
Change-Id: Ia62ac144d187e705644742ebaa9b1679c45d2ae0
---
 src/app/currentconversation.cpp                     |  1 +
 src/app/currentconversation.h                       |  1 +
 src/app/mainview/components/ChatView.qml            | 11 ++++++++++-
 .../mainview/components/KeyboardShortcutTable.qml   |  8 ++++++++
 src/app/mainview/components/MessageBarTextArea.qml  |  6 ++++++
 src/libclient/api/conversation.h                    |  1 +
 src/libclient/conversationmodel.cpp                 |  7 +++++++
 src/libclient/messagelistmodel.cpp                  | 13 +++++++++++++
 src/libclient/messagelistmodel.h                    |  1 +
 9 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/src/app/currentconversation.cpp b/src/app/currentconversation.cpp
index 787fa2429..b6ea57043 100644
--- a/src/app/currentconversation.cpp
+++ b/src/app/currentconversation.cpp
@@ -53,6 +53,7 @@ CurrentConversation::updateData()
         const auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
         if (auto optConv = accInfo.conversationModel->getConversationForUid(convId)) {
             auto& convInfo = optConv->get();
+            set_lastSelfMessageId(convInfo.lastSelfMessageId);
             set_uris(convInfo.participantsUris());
             set_isSwarm(convInfo.isSwarm());
             set_isLegacy(convInfo.isLegacy());
diff --git a/src/app/currentconversation.h b/src/app/currentconversation.h
index 62c7944f2..99d6ae654 100644
--- a/src/app/currentconversation.h
+++ b/src/app/currentconversation.h
@@ -54,6 +54,7 @@ class CurrentConversation final : public QObject
     QML_PROPERTY(QVariantList, activeCalls)
     QML_PROPERTY(QStringList, errors)
     QML_PROPERTY(QStringList, backendErrors)
+    QML_PROPERTY(QString, lastSelfMessageId)
 
     // TODO: these belong in CurrentCall(which doesn't exist yet)
     QML_PROPERTY(bool, hideSelf)
diff --git a/src/app/mainview/components/ChatView.qml b/src/app/mainview/components/ChatView.qml
index f3990cf08..dfd7f73f1 100644
--- a/src/app/mainview/components/ChatView.qml
+++ b/src/app/mainview/components/ChatView.qml
@@ -124,7 +124,6 @@ Rectangle {
             }
         }
 
-
         Connections {
             target: CurrentConversation
             enabled: true
@@ -293,4 +292,14 @@ Rectangle {
             }
         }
     }
+
+    Shortcut {
+        sequence: "Ctrl+Escape"
+        context: Qt.WindowShortcut
+        enabled: root.visible
+        onActivated: {
+            MessagesAdapter.replyToId = ""
+            MessagesAdapter.editId = ""
+        }
+    }
 }
diff --git a/src/app/mainview/components/KeyboardShortcutTable.qml b/src/app/mainview/components/KeyboardShortcutTable.qml
index 591ee637b..3e58e8764 100644
--- a/src/app/mainview/components/KeyboardShortcutTable.qml
+++ b/src/app/mainview/components/KeyboardShortcutTable.qml
@@ -105,6 +105,14 @@ Window {
             shortcut: "Shift + Ctrl + A"
             description: qsTr("Accept contact request")
         }
+        ListElement {
+            shortcut: "↑"
+            description: qsTr("Edit last message")
+        }
+        ListElement {
+            shortcut: "Ctrl + Esc"
+            description: qsTr("Cancel message edition")
+        }
     }
 
     ListModel {
diff --git a/src/app/mainview/components/MessageBarTextArea.qml b/src/app/mainview/components/MessageBarTextArea.qml
index b636deec7..f865fdb03 100644
--- a/src/app/mainview/components/MessageBarTextArea.qml
+++ b/src/app/mainview/components/MessageBarTextArea.qml
@@ -104,6 +104,12 @@ JamiFlickable {
             if (keyEvent.matches(StandardKey.Paste)) {
                 MessagesAdapter.onPaste()
                 keyEvent.accepted = true
+            } else if (keyEvent.matches(StandardKey.MoveToPreviousLine)) {
+                if (root.text !== "")
+                    return
+                MessagesAdapter.replyToId = ""
+                MessagesAdapter.editId = CurrentConversation.lastSelfMessageId
+                keyEvent.accepted = true;
             } else if (keyEvent.key === Qt.Key_Enter ||
                        keyEvent.key === Qt.Key_Return) {
                 if (!(keyEvent.modifiers & Qt.ShiftModifier)) {
diff --git a/src/libclient/api/conversation.h b/src/libclient/api/conversation.h
index 2671b7a1c..66c0e6d45 100644
--- a/src/libclient/api/conversation.h
+++ b/src/libclient/api/conversation.h
@@ -78,6 +78,7 @@ struct Info
     QString confId;
     std::unique_ptr<MessageListModel> interactions;
     QString lastMessageUid;
+    QString lastSelfMessageId;
     QHash<QString, QString> parentsId; // pair messageid/parentid for messages without parent loaded
     unsigned int unreadMessages = 0;
     QVector<QPair<int, QString>> errors;
diff --git a/src/libclient/conversationmodel.cpp b/src/libclient/conversationmodel.cpp
index 5604a17c2..26c8ddc41 100644
--- a/src/libclient/conversationmodel.cpp
+++ b/src/libclient/conversationmodel.cpp
@@ -1307,6 +1307,7 @@ ConversationModel::sendMessage(const QString& uid, const QString& body, const QS
             }
 
             newConv.lastMessageUid = msgId;
+            newConv.lastSelfMessageId = msgId;
             // Emit this signal for chatview in the client
             Q_EMIT newInteraction(convId, msgId, msg);
             // This conversation is now at the top of the list
@@ -1486,6 +1487,9 @@ ConversationModel::clearInteractionFromConversation(const QString& convId,
                 conversation.lastMessageUid = newLastId;
                 lastInteractionUpdated = true;
             }
+            if (conversation.lastSelfMessageId == interactionId) {
+                conversation.lastSelfMessageId = conversation.interactions->lastSelfMessageId();
+            }
 
         } catch (const std::out_of_range& e) {
             qDebug() << "can't clear interaction from conversation: " << e.what();
@@ -1521,6 +1525,7 @@ ConversationModel::clearInteractionsCache(const QString& convId)
             }
             conversation.allMessagesLoaded = false;
             conversation.lastMessageUid = "";
+            conversation.lastSelfMessageId = "";
             ConfigurationManager::instance().loadConversationMessages(owner.id, convId, "", 1);
         }
     } catch (const std::out_of_range& e) {
@@ -2469,6 +2474,7 @@ ConversationModelPimpl::slotConversationLoaded(uint32_t requestId,
         }
 
         conversation.lastMessageUid = conversation.interactions->lastMessageUid();
+        conversation.lastSelfMessageId = conversation.interactions->lastSelfMessageId();
         if (conversation.lastMessageUid.isEmpty() && !conversation.allMessagesLoaded
             && messages.size() != 0) {
             if (conversation.interactions->size() > 0) {
@@ -2627,6 +2633,7 @@ ConversationModelPimpl::slotMessageReceived(const QString& accountId,
             return;
         }
         conversation.lastMessageUid = conversation.interactions->lastMessageUid();
+        conversation.lastSelfMessageId = conversation.interactions->lastSelfMessageId();
         invalidateModel();
         if (!interaction::isOutgoing(msg)) {
             Q_EMIT behaviorController.newUnreadInteraction(linked.owner.id,
diff --git a/src/libclient/messagelistmodel.cpp b/src/libclient/messagelistmodel.cpp
index e7013b998..e6913a508 100644
--- a/src/libclient/messagelistmodel.cpp
+++ b/src/libclient/messagelistmodel.cpp
@@ -648,4 +648,17 @@ MessageListModel::lastMessageUid() const
     return {};
 }
 
+QString
+MessageListModel::lastSelfMessageId() const
+{
+    for (auto it = interactions_.rbegin(); it != interactions_.rend(); ++it) {
+        auto lastType = it->second.type;
+        if (lastType == interaction::Type::TEXT
+            and !it->second.body.isEmpty() and it->second.authorUri.isEmpty()) {
+            return it->first;
+        }
+    }
+    return {};
+}
+
 } // namespace lrc
diff --git a/src/libclient/messagelistmodel.h b/src/libclient/messagelistmodel.h
index f5b662bf4..6c367bf77 100644
--- a/src/libclient/messagelistmodel.h
+++ b/src/libclient/messagelistmodel.h
@@ -138,6 +138,7 @@ public:
     void addEdition(const QString& msgId, const interaction::Info& info, bool end);
     void editMessage(const QString& msgId, interaction::Info& info);
     QString lastMessageUid() const;
+    QString lastSelfMessageId() const;
 
 protected:
     using Role = MessageList::Role;
-- 
GitLab