diff --git a/resources/icons/share_black_24dp.svg b/resources/icons/share_black_24dp.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d41fc300a18e735180688926070b5de0754891aa
--- /dev/null
+++ b/resources/icons/share_black_24dp.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<path d="M17.1,15.7c-0.8,0-1.5,0.3-2.1,0.8l-5.3-3.3C9.9,12.8,10,12.4,10,12c0-0.4-0.1-0.8-0.3-1.2l5.3-3.3c0.6,0.5,1.3,0.8,2.1,0.8
+	c1.7,0,3.1-1.4,3.1-3.1S18.9,2,17.1,2C15.4,2,14,3.4,14,5.1c0,0.4,0.1,0.8,0.3,1.2L8.9,9.6C8.3,9.1,7.6,8.9,6.9,8.9
+	c-1.7,0-3.1,1.4-3.1,3.1s1.4,3.1,3.1,3.1c0.8,0,1.5-0.3,2.1-0.8l5.3,3.3C14.1,18,14,18.4,14,18.9c0,1.7,1.4,3.1,3.1,3.1
+	c1.7,0,3.1-1.4,3.1-3.1S18.9,15.7,17.1,15.7z M17.1,20.6c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8c1,0,1.8,0.8,1.8,1.8
+	S18.1,20.6,17.1,20.6z M17.1,3.4c1,0,1.8,0.8,1.8,1.8s-0.8,1.8-1.8,1.8c-1,0-1.8-0.8-1.8-1.8S16.2,3.4,17.1,3.4z M6.9,13.8
+	c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8S8.6,11,8.6,12S7.8,13.8,6.9,13.8z"/>
+</svg>
diff --git a/src/app/commoncomponents/SBSMessageBase.qml b/src/app/commoncomponents/SBSMessageBase.qml
index a57b1ddb51253ec9a29ef74005987b460aef1f52..15d7eeeba83d11651a9e2fdbdb58b11b9053310e 100644
--- a/src/app/commoncomponents/SBSMessageBase.qml
+++ b/src/app/commoncomponents/SBSMessageBase.qml
@@ -278,7 +278,7 @@ Control {
 
                     anchors.right: isOutgoing ? bubble.left : undefined
                     anchors.left: !isOutgoing ? bubble.right : undefined
-                    width: JamiTheme.emojiPushButtonSize * 2
+                    width: JamiTheme.emojiPushButtonSize * 4
                     height: JamiTheme.emojiPushButtonSize
                     anchors.verticalCenter: bubble.verticalCenter
 
@@ -299,24 +299,24 @@ Control {
                         anchors.verticalCenter: parent.verticalCenter
                         anchors.right: isOutgoing ? optionButtonItem.right : undefined
                         anchors.left: !isOutgoing ? optionButtonItem.left : undefined
-                        visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || bgHandler.hovered)
+                        visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || share.hovered || bgHandler.hovered)
                         source: JamiResources.more_vert_24dp_svg
-                        width: optionButtonItem.width / 2
+                        width: optionButtonItem.width / 4
                         height: optionButtonItem.height
                         circled: false
                         property bool isOpen: false
                         property var obj: undefined
 
-                        function bind() {
+                        function setBindings() {
                             more.isOpen = false;
-                            visible = Qt.binding(() => CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || bgHandler.hovered));
+                            visible = Qt.binding(() => CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || share.hovered || bgHandler.hovered));
                             imageColor = Qt.binding(() => hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor);
                             normalColor = Qt.binding(() => JamiTheme.primaryBackgroundColor);
                         }
 
                         onClicked: {
                             if (more.isOpen) {
-                                more.bind();
+                                more.setBindings();
                                 obj.close();
                             } else {
                                 var component = Qt.createComponent("qrc:/commoncomponents/ShowMoreMenu.qml");
@@ -332,7 +332,7 @@ Control {
                                     });
                                 obj.open();
                                 more.isOpen = true;
-                                visible = true;
+                                visible = true; // the button stay visible as long the popup is open even if it's not hovered
                                 imageColor = JamiTheme.chatViewFooterImgHoverColor;
                                 normalColor = JamiTheme.hoveredButtonColor;
                             }
@@ -348,19 +348,75 @@ Control {
                         normalColor: JamiTheme.primaryBackgroundColor
                         toolTipText: JamiStrings.reply
                         source: JamiResources.reply_black_24dp_svg
-                        width: optionButtonItem.width / 2
+                        width: optionButtonItem.width / 4
                         height: optionButtonItem.height
                         anchors.verticalCenter: parent.verticalCenter
                         anchors.rightMargin: 5
                         anchors.right: isOutgoing ? more.left : undefined
                         anchors.left: !isOutgoing ? more.right : undefined
-                        visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || bgHandler.hovered)
+                        visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || share.hovered || bgHandler.hovered)
 
                         onClicked: {
                             MessagesAdapter.editId = "";
                             MessagesAdapter.replyToId = Id;
                         }
                     }
+
+                    PushButton {
+                        id: share
+                        objectName: "share"
+
+                        circled: false
+                        imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
+                        normalColor: JamiTheme.primaryBackgroundColor
+                        toolTipText: JamiStrings.share
+                        source: JamiResources.share_black_24dp_svg
+
+                        width: optionButtonItem.width / 4
+                        height: optionButtonItem.height
+                        anchors.verticalCenter: parent.verticalCenter
+                        anchors.rightMargin: 5
+                        anchors.right: isOutgoing ? reply.left : undefined
+                        anchors.left: !isOutgoing ? reply.right : undefined
+                        visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || more.hovered || bgHandler.hovered)
+                        property bool isOpen: false
+                        property var obj: undefined
+
+                        function setBindings() { // when the popup is closed, setBindings is called to reset the icon's visual settings
+                            share.isOpen = false;
+                            visible = Qt.binding(() => CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || more.hovered || bgHandler.hovered));
+                            imageColor = Qt.binding(() => hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor);
+                            normalColor = Qt.binding(() => JamiTheme.primaryBackgroundColor);
+                        }
+
+                        onClicked: {
+                            if (share.isOpen) {
+                                share.setBindings();
+                                obj.close();
+                            } else {
+                                if (root.type === 2 || root.type === 5) {
+                                    // 2=TEXT and 5=DATA_TRANSFER (any kind of file) defined in interaction.h
+                                    var component = Qt.createComponent("qrc:/commoncomponents/ShareMessageMenu.qml");
+                                    obj = component.createObject(share, {
+                                            "isOutgoing": isOutgoing,
+                                            "msgId": Id,
+                                            "msgBody": Body,
+                                            "type": root.type,
+                                            "transferName": TransferName,
+                                            "msgBubble": bubble,
+                                            "listView": listView,
+                                            "author": UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author),
+                                            "formattedTime": formattedTime
+                                        });
+                                    obj.open();
+                                    share.isOpen = true;
+                                    visible = true; // the PushButton stay visible as long the popup is open even if it's not hovered
+                                    imageColor = JamiTheme.chatViewFooterImgHoverColor;
+                                    normalColor = JamiTheme.hoveredButtonColor;
+                                }
+                            }
+                        }
+                    }
                 }
 
                 MessageBubble {
@@ -382,11 +438,7 @@ Control {
                     property bool bubbleHovered
                     property string imgSource
 
-                    width: (root.type === Interaction.Type.TEXT || isDeleted ?
-                            root.textContentWidth + (IsEmojiOnly || root.bigMsg ?
-                                                        0
-                                                        : root.timeWidth + root.editedWidth)
-                            : innerContent.childrenRect.width)
+                    width: (root.type === Interaction.Type.TEXT || isDeleted ? root.textContentWidth + (IsEmojiOnly || root.bigMsg ? 0 : root.timeWidth + root.editedWidth) : innerContent.childrenRect.width)
                     height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0) + (root.bigMsg ? 15 : 0)
 
                     HoverHandler {
@@ -470,6 +522,11 @@ Control {
                                 MessagesAdapter.openUrl(root.hoveredLink);
                             }
                         }
+
+                        onDoubleClicked: {
+                            MessagesAdapter.editId = "";
+                            MessagesAdapter.replyToId = Id;
+                        }
                         property bool bubbleHovered: containsMouse || textHovered
                         cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
                     }
diff --git a/src/app/commoncomponents/ShareMessageMenu.qml b/src/app/commoncomponents/ShareMessageMenu.qml
new file mode 100644
index 0000000000000000000000000000000000000000..72ee5d9f2797de945b55d3891b1f3fa69ea98a75
--- /dev/null
+++ b/src/app/commoncomponents/ShareMessageMenu.qml
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2024 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 Qt5Compat.GraphicalEffects
+import net.jami.Constants 1.1
+import net.jami.Models 1.1
+import net.jami.Adapters 1.1
+import SortFilterProxyModel 0.2
+import "contextmenu"
+import "../commoncomponents"
+import "../mainview/components"
+
+BaseContextMenu {
+    id: mainMenu
+
+    height: 330 + Math.min(messageInput.height, textareaMaxHeight)
+    width: 400
+
+    required property string msgId
+    required property string msgBody
+    required property bool isOutgoing
+    required property int type
+    required property string transferName
+    required property Item msgBubble
+    required property ListView listView
+    required property string author
+    required property string formattedTime
+
+    property var selectedUids: []
+    property string shareToId: msgId
+    property string fileLink: msgBody
+    property int textareaMaxHeight: 350
+    function xPosition(width) {
+        // Use the width at function scope to retrigger property evaluation.
+        const listViewWidth = listView.width;
+        const parentX = parent.x;
+        if (isOutgoing) {
+            return parentX - width - 20;
+        } else {
+            return parentX + 20;
+        }
+    }
+
+    x: xPosition(width)
+    y: parent.y
+
+    function xPositionProvider(width) {
+        // Use the width at function scope to retrigger property evaluation.
+        const listViewWidth = listView.width;
+        if (isOutgoing) {
+            return -5 - width;
+        } else {
+            const rightMargin = listViewWidth - (msgBubble.x + width);
+            return width > rightMargin + 35 ? -5 - width : 35;
+        }
+    }
+    function yPositionProvider(height) {
+        const topOffset = msgBubble.mapToItem(listView, 0, 0).y;
+        const listViewHeight = listView.height;
+        const bottomMargin = listViewHeight - height - topOffset;
+        if (bottomMargin < 0 || (topOffset < 0 && topOffset + height > 0)) {
+            return 30 - height;
+        } else {
+            return 0;
+        }
+    }
+
+    SortFilterProxyModel {
+        id: shareConvProxyModel
+
+        sourceModel: ConversationsAdapter.convListProxyModel
+        filterCaseSensitivity: Qt.CaseInsensitive
+    }
+
+    Rectangle {
+        id: header
+
+        width: parent.width
+        height: 0
+    }
+
+    Rectangle {
+        id: sendButton
+
+        height: JamiTheme.chatViewFooterButtonSize
+        anchors.right: parent.right
+        anchors.rightMargin: 10
+        anchors.topMargin: 10
+        anchors.top: header.bottom
+        color: JamiTheme.transparentColor
+
+        PushButton {
+            id: shareMessageButton
+
+            height: JamiTheme.chatViewFooterButtonSize
+            width: scale * JamiTheme.chatViewFooterButtonSize
+            anchors.right: parent.right
+
+            visible: true
+
+            radius: JamiTheme.chatViewFooterButtonRadius
+            preferredSize: JamiTheme.chatViewFooterButtonIconSize - 6
+            imageContainerWidth: 25
+            imageContainerHeight: 25
+
+            toolTipText: JamiStrings.share
+
+            mirror: UtilsAdapter.isRTL
+
+            source: JamiResources.send_black_24dp_svg
+
+            hoverEnabled: enabled
+            normalColor: enabled ? JamiTheme.chatViewFooterSendButtonColor : JamiTheme.chatViewFooterSendButtonDisableColor
+            imageColor: enabled ? JamiTheme.chatViewFooterSendButtonImgColor : JamiTheme.chatViewFooterSendButtonImgColorDisable
+            hoveredColor: JamiTheme.buttonTintedBlueHovered
+            pressedColor: hoveredColor
+
+            opacity: 1
+            scale: opacity
+
+            MouseArea {
+                anchors.fill: parent
+
+                onClicked: {
+                    var selectedContacts = mainMenu.selectedUids;
+                    var hasText = messageInput.text && selectedContacts.length > 0;
+                    function sendMessageOrFile(uid) {
+                        if (Type === 2) {
+                            // 2=TEXT and 5=DATA_TRANSFER (any kind of file) defined in interaction.h
+                            MessagesAdapter.sendMessageToUid(msgBody, uid);
+                        } else {
+                            MessagesAdapter.sendFileToUid(fileLink, uid);
+                        }
+                    }
+                    for (var i = 0; i < selectedContacts.length; i++) {
+                        var uid = selectedContacts[i];
+                        sendMessageOrFile(uid);
+                        if (hasText) {
+                            MessagesAdapter.sendMessageToUid(messageInput.text, uid);
+                        }
+                    }
+                    messageInput.text = "";
+                    mainMenu.destroy();
+                }
+            }
+        }
+    }
+
+    Rectangle {
+        id: searchConv
+
+        height: 300
+        width: parent.width
+        anchors.top: header.bottom
+        anchors.topMargin: 10
+
+        property int type: ContactList.CONVERSATION
+
+        color: JamiTheme.transparentColor
+        ColumnLayout {
+            id: contactPickerPopupRectColumnLayout
+
+            anchors.fill: parent
+            Searchbar {
+                id: contactPickerContactSearchBar
+
+                width: parent.width - 20 - JamiTheme.chatViewFooterButtonSize
+                anchors.leftMargin: 10
+                Layout.preferredHeight: 35
+                placeHolderText: "Share to..."
+                onSearchBarTextChanged: function (text) {
+                    shareConvProxyModel.filterRole = shareConvProxyModel.roleForName("Title");
+                    shareConvProxyModel.filterPattern = text;
+                }
+            }
+            JamiListView {
+                id: contactPickerListView
+
+                Layout.alignment: Qt.AlignCenter
+                Layout.fillWidth: true
+                Layout.preferredHeight: 255
+                Layout.bottomMargin: JamiTheme.preferredMarginSize
+                Layout.topMargin: 5
+
+                model: shareConvProxyModel
+
+                delegate: ConversationPickerItemDelegate {
+                    id: conversationDelegate
+                }
+            }
+        }
+    }
+
+    Flickable {
+        id: messageInputContainer
+
+        height: Math.min(contentHeight, mainMenu.textareaMaxHeight)
+        width: parent.width - 20
+        contentHeight: messageInput.height
+        anchors.left: parent.left
+        anchors.leftMargin: 10
+        anchors.rightMargin: 10
+        anchors.topMargin: 10
+        anchors.top: searchConv.bottom
+
+        flickableDirection: Flickable.VerticalFlick
+        clip: true
+
+        ScrollBar.vertical: JamiScrollBar {
+            policy: ScrollBar.AsNeeded
+        }
+
+        onContentHeightChanged: {
+            if (contentHeight > height) {
+                contentY = contentHeight - height;
+            }
+        }
+
+        TextArea {
+            id: messageInput
+
+            height: contentHeight + 12
+            width: parent.width
+            placeholderText: "Add a comment"
+            placeholderTextColor: JamiTheme.messageBarPlaceholderTextColor
+            font.pointSize: JamiTheme.textFontSize + 2
+            color: JamiTheme.textColor
+            wrapMode: Text.WordWrap
+
+            background: Rectangle {
+                color: JamiTheme.transparentColor
+                radius: 5
+                border.color: JamiTheme.chatViewFooterRectangleBorderColor
+                border.width: 2
+            }
+        }
+    }
+
+    // destroy() and setBindings() are needed to unselect the share icon from SBSMessageBase
+
+    onAboutToHide: {
+        mainMenu.destroy();
+    }
+
+    Component.onDestruction: {
+        parent.setBindings();
+    }
+}
diff --git a/src/app/commoncomponents/ShowMoreMenu.qml b/src/app/commoncomponents/ShowMoreMenu.qml
index 26c4cdb8cea930d85c7030d5289b211dd18db441..0a8f3f9c83caa127ae014abbade181b04102d6ef 100644
--- a/src/app/commoncomponents/ShowMoreMenu.qml
+++ b/src/app/commoncomponents/ShowMoreMenu.qml
@@ -198,11 +198,13 @@ BaseContextMenu {
         root.loadMenuItems(menuItems);
     }
 
+    // destroy() and setBindings() are needed to unselect the share icon from SBSMessageBase
+
     onAboutToHide: {
         root.destroy();
     }
 
     Component.onDestruction: {
-        parent.bind();
+        parent.setBindings();
     }
 }
diff --git a/src/app/mainview/components/ConversationPickerItemDelegate.qml b/src/app/mainview/components/ConversationPickerItemDelegate.qml
new file mode 100644
index 0000000000000000000000000000000000000000..300a99a3332368afb9b84ab4c0291e5797e3ac33
--- /dev/null
+++ b/src/app/mainview/components/ConversationPickerItemDelegate.qml
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 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 Qt5Compat.GraphicalEffects
+import net.jami.Adapters 1.1
+import net.jami.Constants 1.1
+import net.jami.Enums 1.1
+import net.jami.Models 1.1
+import "../../commoncomponents"
+
+ItemDelegate {
+    id: root
+
+    width: ListView.view.width
+    height: JamiTheme.smartListItemHeight
+
+    RowLayout {
+        anchors.fill: parent
+        anchors.leftMargin: 15
+        anchors.rightMargin: 15
+        spacing: 10
+
+        ConversationAvatar {
+            id: avatar
+            objectName: "smartlistItemDelegateAvatar"
+
+            imageId: UID
+            presenceStatus: Presence
+            showPresenceIndicator: Presence !== undefined ? Presence : false
+
+            Layout.preferredWidth: JamiTheme.smartListAvatarSize
+            Layout.preferredHeight: JamiTheme.smartListAvatarSize
+
+            Rectangle {
+                id: overlayHighlighted
+                visible: highlighted
+
+                anchors.fill: parent
+                color: Qt.rgba(0, 0, 0, 0.5)
+                radius: JamiTheme.smartListAvatarSize / 2
+
+                Image {
+                    id: highlightedImage
+
+                    width: JamiTheme.smartListAvatarSize / 2
+                    height: JamiTheme.smartListAvatarSize / 2
+                    anchors.centerIn: parent
+
+                    layer {
+                        enabled: true
+                        effect: ColorOverlay {
+                            color: "white"
+                        }
+                    }
+                    source: JamiResources.check_black_24dp_svg
+                }
+            }
+        }
+
+        ColumnLayout {
+            Layout.fillWidth: true
+            Layout.fillHeight: true
+            spacing: 0
+
+            // best name
+            Text {
+                Layout.fillWidth: true
+                Layout.minimumHeight: 20
+                Layout.alignment: Qt.AlignVCenter
+                horizontalAlignment: Text.AlignLeft
+                verticalAlignment: Text.AlignVCenter
+                elide: Text.ElideMiddle
+                text: Title === undefined ? "" : Title
+                textFormat: TextEdit.PlainText
+                font.pointSize: JamiTheme.mediumFontSize
+                font.weight: UnreadMessagesCount ? Font.Bold : Font.Normal
+                color: JamiTheme.textColor
+            }
+
+            Text {
+                Layout.fillWidth: true
+                Layout.minimumHeight: 20
+                Layout.alignment: Qt.AlignVCenter
+                text: JamiStrings.blocked
+                textFormat: TextEdit.PlainText
+                visible: IsBanned
+                font.pointSize: JamiTheme.mediumFontSize
+                font.weight: Font.Bold
+                color: JamiTheme.textColor
+            }
+        }
+
+        Accessible.role: Accessible.Button
+        Accessible.name: Title === undefined ? "" : Title
+    }
+
+    background: Rectangle {
+        color: {
+            if (root.pressed || root.highlighted)
+                return JamiTheme.smartListSelectedColor;
+            else if (root.hovered)
+                return JamiTheme.smartListHoveredColor;
+            else
+                return "transparent";
+        }
+    }
+
+    highlighted: {
+        return mainMenu.selectedUids.includes(UID);
+    }
+
+    onClicked: {
+        const currentSelectedUids = mainMenu.selectedUids;
+        if (currentSelectedUids.includes(UID)) {
+            mainMenu.selectedUids = currentSelectedUids.filter(uid => uid !== UID);
+        } else {
+            mainMenu.selectedUids = currentSelectedUids.concat(UID);
+        }
+        return;
+    }
+}
diff --git a/src/app/messagesadapter.cpp b/src/app/messagesadapter.cpp
index 037dcd7d1f095e77b979be7f5a2b3bc7ec447422..43afc61a76460ea1dc95f67b5f375c5547724264 100644
--- a/src/app/messagesadapter.cpp
+++ b/src/app/messagesadapter.cpp
@@ -165,6 +165,16 @@ MessagesAdapter::sendMessage(const QString& message)
     }
 }
 
+void
+MessagesAdapter::sendMessageToUid(const QString& message, const QString& convUid)
+{
+    try {
+        lrcInstance_->getCurrentConversationModel()->sendMessage(convUid, message, replyToId_);
+    } catch (...) {
+        qDebug() << "Exception during sendMessage:" << message;
+    }
+}
+
 void
 MessagesAdapter::editMessage(const QString& convId, const QString& newBody, const QString& messageId)
 {
@@ -221,6 +231,21 @@ MessagesAdapter::sendFile(const QString& message)
     }
 }
 
+void
+MessagesAdapter::sendFileToUid(const QString& message, const QString& convUid)
+{
+    QFileInfo fi(message);
+    QString fileName = fi.fileName();
+    try {
+        lrcInstance_->getCurrentConversationModel()->sendFile(convUid,
+                                                              message,
+                                                              fileName,
+                                                              replyToId_);
+    } catch (...) {
+        qDebug() << "Exception during sendFile";
+    }
+}
+
 void
 MessagesAdapter::joinCall(const QString& uri,
                           const QString& deviceId,
@@ -312,8 +337,7 @@ MessagesAdapter::onPaste()
         QString path = QDir::temp().filePath(fileName);
 
         if (!pixmap.save(path, "PNG")) {
-            qDebug().noquote() << "Errors during QPixmap save"
-                               << "\n";
+            qDebug().noquote() << "Errors during QPixmap save" << "\n";
             return;
         }
 
diff --git a/src/app/messagesadapter.h b/src/app/messagesadapter.h
index c35f3f31d14772b32e934497c9c5be7d55c18af8..806bffb5fbf5a38cd55a485bf5f8a0eea757a8ed 100644
--- a/src/app/messagesadapter.h
+++ b/src/app/messagesadapter.h
@@ -126,6 +126,7 @@ public:
     Q_INVOKABLE void unbanContact(int index);
     Q_INVOKABLE void unbanConversation(const QString& convUid);
     Q_INVOKABLE void sendMessage(const QString& message);
+    Q_INVOKABLE void sendMessageToUid(const QString& message, const QString& convUid);
     Q_INVOKABLE void editMessage(const QString& convId,
                                  const QString& newBody,
                                  const QString& messageId = "");
@@ -136,6 +137,7 @@ public:
                                          const QString& emoji,
                                          const QString& messageId);
     Q_INVOKABLE void sendFile(const QString& message);
+    Q_INVOKABLE void sendFileToUid(const QString& message, const QString& convUid);
     Q_INVOKABLE void acceptFile(const QString& arg);
     Q_INVOKABLE void cancelFile(const QString& arg);
     Q_INVOKABLE void openUrl(const QString& url);