From 8de099e38d52a27c86723b16e5fcc64029600629 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Thu, 3 Aug 2023 16:32:32 -0400
Subject: [PATCH] MessageOptionsPopup: add option to locally delete file

This button offers an option to remove sent/downloaded files
from the device.

Change-Id: Ida1b135681243fd6055034d8a2d699d11bf040e5
GitLab: #1287
---
 .../commoncomponents/MessageOptionsPopup.qml  | 12 ++++++++++
 src/app/constant/JamiStrings.qml              |  1 +
 src/app/messagesadapter.cpp                   |  7 ++++++
 src/app/messagesadapter.h                     |  1 +
 src/libclient/api/conversationmodel.h         |  3 +++
 src/libclient/conversationmodel.cpp           | 23 +++++++++++++++++--
 6 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/src/app/commoncomponents/MessageOptionsPopup.qml b/src/app/commoncomponents/MessageOptionsPopup.qml
index e359bc196..c562a7914 100644
--- a/src/app/commoncomponents/MessageOptionsPopup.qml
+++ b/src/app/commoncomponents/MessageOptionsPopup.qml
@@ -228,6 +228,18 @@ Popup {
                 }
             }
 
+            MessageOptionButton {
+                visible: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
+                textButton: JamiStrings.removeLocally
+                iconSource: JamiResources.trash_black_24dp_svg
+                Layout.fillWidth: true
+                Layout.margins: 5
+                onClicked: {
+                    MessagesAdapter.removeFile(msgId, root.location)
+                    close()
+                }
+            }
+
             MessageOptionButton {
                 id: buttonEdit
 
diff --git a/src/app/constant/JamiStrings.qml b/src/app/constant/JamiStrings.qml
index 4d6cbfb25..1fe84a663 100644
--- a/src/app/constant/JamiStrings.qml
+++ b/src/app/constant/JamiStrings.qml
@@ -496,6 +496,7 @@ Item {
     // Context Menu
     property string saveFile: qsTr("Save file")
     property string openLocation: qsTr("Open location")
+    property string removeLocally: qsTr("Delete file from device")
 
     // Updates
     property string betaInstall: qsTr("Install beta version")
diff --git a/src/app/messagesadapter.cpp b/src/app/messagesadapter.cpp
index 0b77e51b6..0a6ccae43 100644
--- a/src/app/messagesadapter.cpp
+++ b/src/app/messagesadapter.cpp
@@ -299,6 +299,13 @@ MessagesAdapter::openDirectory(const QString& path)
     }
 }
 
+void
+MessagesAdapter::removeFile(const QString& interactionId, const QString& path)
+{
+    auto convUid = lrcInstance_->get_selectedConvUid();
+    lrcInstance_->getCurrentConversationModel()->removeFile(convUid, interactionId, path);
+}
+
 void
 MessagesAdapter::acceptFile(const QString& interactionId)
 {
diff --git a/src/app/messagesadapter.h b/src/app/messagesadapter.h
index a70c66d67..db3916ed1 100644
--- a/src/app/messagesadapter.h
+++ b/src/app/messagesadapter.h
@@ -111,6 +111,7 @@ protected:
     Q_INVOKABLE void cancelFile(const QString& arg);
     Q_INVOKABLE void openUrl(const QString& url);
     Q_INVOKABLE void openDirectory(const QString& arg);
+    Q_INVOKABLE void removeFile(const QString& interactionId, const QString& path);
     Q_INVOKABLE void deleteInteraction(const QString& interactionId);
     Q_INVOKABLE void joinCall(const QString& uri,
                               const QString& deviceId,
diff --git a/src/libclient/api/conversationmodel.h b/src/libclient/api/conversationmodel.h
index 07536a6fe..dcfeb31dd 100644
--- a/src/libclient/api/conversationmodel.h
+++ b/src/libclient/api/conversationmodel.h
@@ -306,6 +306,9 @@ public:
     void getTransferInfo(const QString& conversationId,
                          const QString& interactionId,
                          api::datatransfer::Info& info) const;
+    void removeFile(const QString& conversationId,
+                    const QString& interactionId,
+                    const QString& path);
 
     /**
      * Starts a search of all medias in a conversation
diff --git a/src/libclient/conversationmodel.cpp b/src/libclient/conversationmodel.cpp
index 5d853fb79..4031eb97f 100644
--- a/src/libclient/conversationmodel.cpp
+++ b/src/libclient/conversationmodel.cpp
@@ -3384,8 +3384,7 @@ ConversationModelPimpl::slotNewCall(const QString& fromId, const QString& callId
         // in case if we receive call after removing contact add conversation request;
         try {
             auto contact = linked.owner.contactModel->getContact(fromId);
-            if (!isOutgoing && !contact.isBanned
-                && fromId != linked.owner.profileInfo.uri) {
+            if (!isOutgoing && !contact.isBanned && fromId != linked.owner.profileInfo.uri) {
                 addContactRequest(fromId);
             }
             if (isOutgoing && contact.profileInfo.type == profile::Type::TEMPORARY) {
@@ -4049,6 +4048,26 @@ ConversationModel::getTransferInfo(const QString& conversationId,
     }
 }
 
+void
+ConversationModel::removeFile(const QString& conversationId,
+                              const QString& interactionId,
+                              const QString& path)
+{
+    auto convOpt = getConversationForUid(conversationId);
+    if (!convOpt)
+        return;
+
+    QFile::remove(path);
+
+    std::lock_guard<std::mutex> lk(pimpl_->interactionsLocks[convOpt->get().uid]);
+    auto& interactions = convOpt->get().interactions;
+    auto it = interactions->find(interactionId);
+    if (it != interactions->end()) {
+        it->second.status = interaction::Status::TRANSFER_AWAITING_HOST;
+        interactions->emitDataChanged(it, {MessageList::Role::Status});
+    }
+}
+
 int
 ConversationModel::getNumberOfUnreadMessagesFor(const QString& convUid)
 {
-- 
GitLab