diff --git a/qml.qrc b/qml.qrc
index 5abf8aece942161856e68c2ebd2157f3e1fe509c..04b8a564ed361850178335e3da3f1a90a3d9fa32 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -165,6 +165,7 @@
         <file>src/mainview/components/MessageListView.qml</file>
         <file>src/commoncomponents/MessageBubble.qml</file>
         <file>src/constant/MsgSeq.qml</file>
+        <file>src/commoncomponents/SBSContextMenu.qml</file>
         <file>src/commoncomponents/SBSMessageBase.qml</file>
         <file>src/commoncomponents/GeneratedMessageDelegate.qml</file>
         <file>src/commoncomponents/DataTransferMessageDelegate.qml</file>
diff --git a/src/commoncomponents/DataTransferMessageDelegate.qml b/src/commoncomponents/DataTransferMessageDelegate.qml
index 93595f9ad0946d3a1dee50a9d7d9d0e68a55447c..8296579f5bafbc97a2139afdb403eb0f8c0dc567 100644
--- a/src/commoncomponents/DataTransferMessageDelegate.qml
+++ b/src/commoncomponents/DataTransferMessageDelegate.qml
@@ -66,6 +66,9 @@ Loader {
             showTime: root.showTime
             seq: root.seq
             author: Author
+            location: Body
+            transferName: TransferName
+            transferId: Id
             formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
             extraHeight: progressBar.visible ? 18 : 0
             innerContent.children: [
@@ -232,6 +235,9 @@ Loader {
             showTime: root.showTime
             seq: root.seq
             author: Author
+            location: Body
+            transferName: TransferName
+            transferId: Id
             formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
             bubble.visible: false
             innerContent.children: [
diff --git a/src/commoncomponents/SBSContextMenu.qml b/src/commoncomponents/SBSContextMenu.qml
new file mode 100644
index 0000000000000000000000000000000000000000..5c49755b9f653cff038d8734788e06db98dd37ea
--- /dev/null
+++ b/src/commoncomponents/SBSContextMenu.qml
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 by Savoir-faire Linux
+ * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.15
+
+import net.jami.Models 1.1
+import net.jami.Adapters 1.1
+import net.jami.Constants 1.1
+
+import "../commoncomponents"
+import "../commoncomponents/contextmenu"
+
+ContextMenuAutoLoader {
+    id: root
+
+    property string location
+    property string transferName
+    property string transferId
+
+    property list<GeneralMenuItem> menuItems: [
+        GeneralMenuItem {
+            id: saveFile
+
+            itemName: JamiStrings.saveFile
+            onClicked: {
+                MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
+            }
+        },
+        GeneralMenuItem {
+            id: openLocation
+
+            itemName: JamiStrings.openLocation
+            onClicked: {
+                MessagesAdapter.openDirectory(root.location)
+            }
+        }
+    ]
+
+    Component.onCompleted: menuItemsToLoad = menuItems
+}
+
diff --git a/src/commoncomponents/SBSMessageBase.qml b/src/commoncomponents/SBSMessageBase.qml
index c186add2ba4b186f2f5e03de5d775c9e2279a5db..669b5ba310b93d52a3c273dafff9515ccf7ff8d6 100644
--- a/src/commoncomponents/SBSMessageBase.qml
+++ b/src/commoncomponents/SBSMessageBase.qml
@@ -38,7 +38,10 @@ Control {
     property bool showTime
     property int seq
     property string author
+    property string transferId
+    property string transferName
     property string formattedTime
+    property string location
     property string hoveredLink
 
     readonly property real senderMargin: 64
@@ -124,13 +127,27 @@ Control {
         }
     }
 
+    SBSContextMenu {
+        id: ctxMenu
+
+        location: root.location
+        transferId: root.transferId
+        transferName: root.transferName
+    }
+
     MouseArea {
         id: itemMouseArea
         anchors.fill: parent
         z: -1
-        acceptedButtons: Qt.LeftButton
-        onClicked: {
-            if (root.hoveredLink)
+        acceptedButtons: Qt.LeftButton | Qt.RightButton
+        onClicked: function (mouse) {
+
+            if (mouse.button === Qt.RightButton && transferId !== "") {
+                // Context Menu for Transfers
+                ctxMenu.x = mouse.x
+                ctxMenu.y = mouse.y
+                ctxMenu.openMenu()
+            } else if (root.hoveredLink)
                 MessagesAdapter.openUrl(root.hoveredLink)
         }
     }
diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml
index 5725172a9d94c0a5f8fc29a16a3a66e658d0eb29..5e6cb5bd4631b97fab9c63fffbd8951571df36f3 100644
--- a/src/constant/JamiStrings.qml
+++ b/src/constant/JamiStrings.qml
@@ -368,6 +368,10 @@ Item {
     property string networkError: qsTr("Network error")
     property string somethingWentWrong: qsTr("Something went wrong")
 
+    // Context Menu
+    property string saveFile: qsTr("Save file")
+    property string openLocation: qsTr("Open location")
+
     // Updates
     property string betaInstall: qsTr("Install beta version")
     property string checkForUpdates: qsTr("Check for updates now")
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index efe43d1821a821785634d621c5854c2511736151..84dd0b184b609ff1186ee55bcb6a9a574e117161 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -195,6 +195,23 @@ MessagesAdapter::openUrl(const QString& url)
     }
 }
 
+void
+MessagesAdapter::openDirectory(const QString& path)
+{
+    QString p = path;
+    QFileInfo f(p);
+    if (f.exists()) {
+        if (!f.isDir())
+            p = f.dir().absolutePath();
+        QString url;
+        if (!p.startsWith("file://"))
+            url = "file://" + p;
+        else
+            url = p;
+        openUrl(url);
+    }
+}
+
 void
 MessagesAdapter::acceptFile(const QString& interactionId)
 {
diff --git a/src/messagesadapter.h b/src/messagesadapter.h
index 7e7138ac393f43bb5d445dee2142f3262ecfea27..7049e0b5a4c4463f2c27d7cf81932bc556734d5d 100644
--- a/src/messagesadapter.h
+++ b/src/messagesadapter.h
@@ -97,6 +97,7 @@ protected:
     Q_INVOKABLE void cancelFile(const QString& arg);
     Q_INVOKABLE void openUrl(const QString& url);
     Q_INVOKABLE void openFile(const QString& arg);
+    Q_INVOKABLE void openDirectory(const QString& arg);
     Q_INVOKABLE void retryInteraction(const QString& interactionId);
     Q_INVOKABLE void deleteInteraction(const QString& interactionId);
     Q_INVOKABLE void copyToDownloads(const QString& interactionId, const QString& displayName);