diff --git a/src/app/commoncomponents/SBSContextMenu.qml b/src/app/commoncomponents/SBSContextMenu.qml
index 64f2893ca98b585dda67b39570266e05f45178da..47546bf3b19147cd3bc4ba144c12a09dd83d144f 100644
--- a/src/app/commoncomponents/SBSContextMenu.qml
+++ b/src/app/commoncomponents/SBSContextMenu.qml
@@ -37,9 +37,7 @@ ContextMenuAutoLoader {
 
             canTrigger: root.transferId !== ""
             itemName: JamiStrings.saveFile
-            onClicked: {
-                MessagesAdapter.copyToDownloads(root.transferId, root.transferName);
-            }
+            onClicked: MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
         },
         GeneralMenuItem {
             id: openLocation
diff --git a/src/app/constant/JamiStrings.qml b/src/app/constant/JamiStrings.qml
index 6278cb033cddbbabf0ca7d3809e70b06ba0991c1..2379c2b64eb14ccb0a91e8de4b69fe988a15f11c 100644
--- a/src/app/constant/JamiStrings.qml
+++ b/src/app/constant/JamiStrings.qml
@@ -295,6 +295,7 @@ Item {
     property string layoutSettings: qsTr("Layout settings")
     property string tileScreenshot: qsTr("Take tile screenshot")
     property string screenshotTaken: qsTr("Screenshot saved to %1")
+    property string fileSaved: qsTr("File saved to %1")
 
     //advanced information
     property string renderersInformation: qsTr("Renderers information")
diff --git a/src/app/mainview/components/FilePreview.qml b/src/app/mainview/components/FilePreview.qml
deleted file mode 100644
index f87490e3ca601eb97769c424df7787349b4f190a..0000000000000000000000000000000000000000
--- a/src/app/mainview/components/FilePreview.qml
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2022-2023 Savoir-faire Linux Inc.
- *
- * 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
-import QtQuick.Controls
-import QtQuick.Layouts
-import Qt.labs.platform
-import Qt5Compat.GraphicalEffects
-import net.jami.Models 1.1
-import net.jami.Adapters 1.1
-import net.jami.Constants 1.1
-import "../../commoncomponents"
-import "../../settingsview/components"
-
-Component {
-    id: root
-
-    Rectangle {
-        id: dataTransferRect
-
-        clip: true
-        width: (contentWidth - spacingLength) / numberElementsPerRow
-        height: width
-        color: "transparent"
-
-        ColumnLayout {
-            anchors.fill: parent
-            anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
-
-            Text {
-                id: myText
-
-                text: TransferName
-                color: JamiTheme.textColor
-                elide: Text.ElideRight
-                Layout.fillWidth: true
-                horizontalAlignment: Text.AlignHCenter
-            }
-            Rectangle {
-                Layout.preferredHeight: parent.height - myText.height - JamiTheme.swarmDetailsPageDocumentsMargins
-                Layout.preferredWidth: parent.width
-                Layout.rightMargin: JamiTheme.swarmDetailsPageDocumentsMargins
-                Layout.bottomMargin: JamiTheme.swarmDetailsPageDocumentsMargins
-                color: "transparent"
-
-                Rectangle {
-                    id: rectContent
-
-                    anchors.fill: parent
-                    anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
-                    color: "transparent"
-                    border.color: themeColor
-                    border.width: 2
-                    radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
-                    layer.enabled: true
-
-                    ResponsiveImage {
-                        id: paperClipImage
-
-                        source: JamiResources.link_black_24dp_svg
-                        width: parent.width / 2
-                        height: parent.height / 2
-                        anchors.centerIn: parent
-                        color: JamiTheme.textColor
-
-                        MouseArea {
-                            anchors.fill: parent
-                            hoverEnabled: true
-                            acceptedButtons: Qt.LeftButton | Qt.RightButton
-                            onEntered: {
-                                cursorShape = Qt.PointingHandCursor;
-                            }
-
-                            onClicked: function (mouse) {
-                                if (mouse.button === Qt.RightButton) {
-                                    ctxMenu.x = mouse.x;
-                                    ctxMenu.y = mouse.y;
-                                    ctxMenu.openMenu();
-                                } else {
-                                    Qt.openUrlExternally(new Url("file://" + Body));
-                                }
-                            }
-                        }
-                        SBSContextMenu {
-                            id: ctxMenu
-
-                            msgId: Id
-                            location: Body
-                            transferId: Id
-                            transferName: TransferName
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/src/app/mainview/components/MediaPreview.qml b/src/app/mainview/components/MediaPreview.qml
deleted file mode 100644
index 2b25e3fb136a0a452ee8b7c0ec508cb8bad46954..0000000000000000000000000000000000000000
--- a/src/app/mainview/components/MediaPreview.qml
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2022-2023 Savoir-faire Linux Inc.
- *
- * 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
-import QtQuick.Controls
-import QtQuick.Layouts
-import Qt.labs.platform
-import Qt5Compat.GraphicalEffects
-import net.jami.Models 1.1
-import net.jami.Adapters 1.1
-import net.jami.Constants 1.1
-import "../../commoncomponents"
-import "../../settingsview/components"
-
-Component {
-    id: root
-
-    Rectangle {
-        id: localMediaRect
-
-        width: (flickableWidth - spacingLength) / numberElementsPerRow
-        height: width
-        color: "transparent"
-
-        ColumnLayout {
-            anchors.fill: parent
-            anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
-
-            Text {
-                id: mediaName
-
-                text: TransferName
-                color: JamiTheme.textColor
-                elide: Text.ElideRight
-                Layout.fillWidth: true
-                horizontalAlignment: Text.AlignHCenter
-            }
-            Rectangle {
-                Layout.preferredHeight: parent.height - mediaName.height - JamiTheme.swarmDetailsPageDocumentsMargins
-                Layout.preferredWidth: parent.width
-                Layout.rightMargin: JamiTheme.swarmDetailsPageDocumentsMargins
-                Layout.bottomMargin: JamiTheme.swarmDetailsPageDocumentsMargins
-                color: "transparent"
-
-                Rectangle {
-                    id: rectContent
-
-                    anchors.fill: parent
-                    anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
-                    color: themeColor
-                    layer.enabled: true
-                    layer.effect: OpacityMask {
-                        maskSource: Item {
-                            width: localMediaCompLoader.width
-                            height: localMediaCompLoader.height
-                            Rectangle {
-                                anchors.centerIn: parent
-                                width: localMediaCompLoader.width
-                                height: localMediaCompLoader.height
-                                radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
-                            }
-                        }
-                    }
-
-                    Loader {
-                        id: localMediaCompLoader
-
-                        property var mediaInfo: MessagesAdapter.getMediaInfo(Body)
-                        anchors.fill: parent
-                        anchors.margins: 2
-                        sourceComponent: {
-                            if (mediaInfo.isImage || mediaInfo.isAnimatedImage)
-                                return imageMediaComp;
-                            else if (WITH_WEBENGINE)
-                                return avMediaComp;
-                        }
-                        Component {
-                            id: avMediaComp
-                            Loader {
-                                Component.onCompleted: {
-                                    var qml = WITH_WEBENGINE ? "qrc:/webengine/VideoPreview.qml" : "qrc:/nowebengine/VideoPreview.qml";
-                                    setSource(qml, {
-                                            "isVideo": mediaInfo.isVideo,
-                                            "html": mediaInfo.html
-                                        });
-                                }
-
-                                property real msgRadius: 20
-                            }
-                        }
-                        Component {
-                            id: imageMediaComp
-
-                            Image {
-                                id: fileImage
-
-                                anchors.fill: parent
-                                fillMode: Image.PreserveAspectCrop
-                                source: "file://" + Body
-                                layer.enabled: true
-                                layer.effect: OpacityMask {
-                                    maskSource: Item {
-                                        width: fileImage.width
-                                        height: fileImage.height
-                                        Rectangle {
-                                            anchors.centerIn: parent
-                                            width: fileImage.width
-                                            height: fileImage.height
-                                            radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
-                                        }
-                                    }
-                                }
-                                MouseArea {
-                                    anchors.fill: parent
-                                    hoverEnabled: true
-                                    acceptedButtons: Qt.LeftButton | Qt.RightButton
-
-                                    onEntered: {
-                                        cursorShape = Qt.PointingHandCursor;
-                                    }
-
-                                    onClicked: function (mouse) {
-                                        if (mouse.button === Qt.RightButton) {
-                                            ctxMenu.x = mouse.x;
-                                            ctxMenu.y = mouse.y;
-                                            ctxMenu.openMenu();
-                                        } else {
-                                            MessagesAdapter.openUrl(fileImage.source);
-                                        }
-                                    }
-                                }
-
-                                SBSContextMenu {
-                                    id: ctxMenu
-
-                                    msgId: Id
-                                    location: Body
-                                    transferId: Id
-                                    transferName: TransferName
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/src/app/mainview/components/MessageListView.qml b/src/app/mainview/components/MessageListView.qml
index 98a691979418d188e3bd271b056693e4d1633670..8da113236cf146f812d9ba21d8d8ee35177fc17f 100644
--- a/src/app/mainview/components/MessageListView.qml
+++ b/src/app/mainview/components/MessageListView.qml
@@ -156,6 +156,16 @@ JamiListView {
         }
     }
 
+    ToastManager {
+        id: toastManager
+
+        anchors.fill: parent
+
+        function instantiateToast(dest) {
+            instantiate(JamiStrings.fileSaved.arg(dest), 1000, 400)
+        }
+    }
+
     Connections {
         target: CurrentConversation
         function onScrollTo(id) {
@@ -253,6 +263,10 @@ JamiListView {
                 root.loadMoreMsgsIfNeeded()
             }
         }
+
+        function onFileCopied(dest) {
+            toastManager.instantiateToast(dest)
+        }
     }
 
     ScrollToBottomButton {
diff --git a/src/app/messagesadapter.cpp b/src/app/messagesadapter.cpp
index 985e7259e3c18f09d501106c1f0d8f1f38123aa9..dfbf0f7feedb5716f2e1a3bf3e90d322710ad226 100644
--- a/src/app/messagesadapter.cpp
+++ b/src/app/messagesadapter.cpp
@@ -254,12 +254,16 @@ void
 MessagesAdapter::copyToDownloads(const QString& interactionId, const QString& displayName)
 {
     auto downloadDir = lrcInstance_->accountModel().downloadDirectory;
-    if (auto accInfo = &lrcInstance_->getCurrentAccountInfo())
-        accInfo->dataTransferModel->copyTo(lrcInstance_->get_currentAccountId(),
-                                           lrcInstance_->get_selectedConvUid(),
-                                           interactionId,
-                                           downloadDir,
-                                           displayName);
+    if (auto accInfo = &lrcInstance_->getCurrentAccountInfo()) {
+        auto dest = accInfo->dataTransferModel->copyTo(lrcInstance_->get_currentAccountId(),
+                                                       lrcInstance_->get_selectedConvUid(),
+                                                       interactionId,
+                                                       downloadDir,
+                                                       displayName);
+        if (!dest.isEmpty()) {
+            Q_EMIT fileCopied(dest);
+        }
+    }
 }
 
 void
diff --git a/src/app/messagesadapter.h b/src/app/messagesadapter.h
index 25d1177a8847ddc738dc4180f26639983b580c71..9d63b9e817ac565e7b512aa22c9ee1969654bdad 100644
--- a/src/app/messagesadapter.h
+++ b/src/app/messagesadapter.h
@@ -77,6 +77,7 @@ Q_SIGNALS:
     void previewInformationToQML(QString messageId, QStringList previewInformation);
     void moreMessagesLoaded(qint32 loadingRequestId);
     void timestampUpdated();
+    void fileCopied(const QString& dest);
 
 protected:
     Q_INVOKABLE bool isDocument(const interaction::Type& type);
diff --git a/src/libclient/api/datatransfermodel.h b/src/libclient/api/datatransfermodel.h
index b6769ab6e947113b8e6cfd40d79425b949809988..5ec2f0c4f138ed031bea3ec07fa39d84464b8387 100644
--- a/src/libclient/api/datatransfermodel.h
+++ b/src/libclient/api/datatransfermodel.h
@@ -72,11 +72,11 @@ public:
                   const QString& fileId,
                   const QString& filePath = {});
 
-    void copyTo(const QString& accountId,
-                const QString& convId,
-                const QString& interactionId,
-                const QString& destPath,
-                const QString& displayName);
+    QString copyTo(const QString& accountId,
+                   const QString& convId,
+                   const QString& interactionId,
+                   const QString& destPath,
+                   const QString& displayName);
 
     void cancel(const QString& accountId, const QString& conversationId, const QString& fileId);
 
diff --git a/src/libclient/datatransfermodel.cpp b/src/libclient/datatransfermodel.cpp
index 460b64578c209329633969ea21354b0fd093ca78..3afd771584e8730363cc12b8276f5b3fe6c5f0cd 100644
--- a/src/libclient/datatransfermodel.cpp
+++ b/src/libclient/datatransfermodel.cpp
@@ -166,7 +166,7 @@ DataTransferModel::download(const QString& accountId,
     ConfigurationManager::instance().downloadFile(accountId, convId, interactionId, fileId, path);
 }
 
-void
+QString
 DataTransferModel::copyTo(const QString& accountId,
                           const QString& convId,
                           const QString& interactionId,
@@ -176,7 +176,7 @@ DataTransferModel::copyTo(const QString& accountId,
     auto fileId = getFileIdFromInteractionId(interactionId);
     if (fileId.isEmpty()) {
         qWarning() << "Cannot find any file for " << interactionId;
-        return;
+        return {};
     }
     QString path;
     qlonglong total, progress;
@@ -186,7 +186,7 @@ DataTransferModel::copyTo(const QString& accountId,
     auto src = QFile(path);
     auto srcfi = QFileInfo(path);
     if (!src.exists())
-        return;
+        return {};
 
     auto filename = displayName;
     if (displayName.isEmpty())
@@ -198,6 +198,7 @@ DataTransferModel::copyTo(const QString& accountId,
     if (!dir.exists())
         dir.mkpath(".");
     src.copy(dest);
+    return dest;
 }
 
 void