diff --git a/src/app/commoncomponents/JamiListView.qml b/src/app/commoncomponents/JamiListView.qml
index e7a2b8ad5a386dc5b2f31b054e7c0e947802a701..e92c8cda33a293446fb0043fff35f47cfb9c3e9b 100644
--- a/src/app/commoncomponents/JamiListView.qml
+++ b/src/app/commoncomponents/JamiListView.qml
@@ -26,6 +26,8 @@ import net.jami.Models 1.1
 ListView {
     id: root
 
+    property alias verticalScrollBar: verticalScrollBar
+
     layer.mipmap: false
     clip: true
     maximumFlickVelocity: 1024
@@ -36,11 +38,6 @@ ListView {
         attachedFlickableMoving: root.moving
     }
 
-    property bool isScrolling: verticalScrollBar.active
-    onIsScrollingChanged: {
-        JamiQmlUtils.isChatviewScrolling = isScrolling
-    }
-
     Keys.onUpPressed: verticalScrollBar.decrease()
     Keys.onDownPressed: verticalScrollBar.increase()
 }
diff --git a/src/app/commoncomponents/ChatviewMessageOptions.qml b/src/app/commoncomponents/MessageOptionsPopup.qml
similarity index 71%
rename from src/app/commoncomponents/ChatviewMessageOptions.qml
rename to src/app/commoncomponents/MessageOptionsPopup.qml
index 5e149f9d1920da34804024e900f66a5f85fa96ff..acc1657eb4f9adbdcf6b20c42c427efbd624e029 100644
--- a/src/app/commoncomponents/ChatviewMessageOptions.qml
+++ b/src/app/commoncomponents/MessageOptionsPopup.qml
@@ -15,6 +15,7 @@
  * 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 Qt5Compat.GraphicalEffects
@@ -32,22 +33,79 @@ Popup {
     padding: 0
     background.visible: false
 
-    property string msgId
-    property string msg
-    property var emojiReplied
-    property bool out
-    property int type
+    required property string msgId
+    required property string msgBody
+    required property var emojiReplied
+    required property bool isOutgoing
+    required property int type
+    required property string transferName
+    required property Item msgBubble
+    required property ListView listView
+
     property string transferId: msgId
-    property string location: Body
-    property string transferName
+    property string location: msgBody
     property bool closeWithoutAnimation: false
+    property var emojiPicker
+
+    function xPositionProvider(width) {
+        // Use the width at function scope to retrigger property evaluation.
+        const listViewWidth = listView.width
+        if (isOutgoing) {
+            const leftMargin = msgBubble.mapToItem(listView, 0, 0).x
+            return width > leftMargin ? -leftMargin : -width
+        } else {
+            const rightMargin = listViewWidth - (msgBubble.x + msgBubble.width)
+            return width > rightMargin ? msgBubble.width - width : msgBubble.width
+        }
+    }
+    function yPositionProvider(height) {
+        const topOffset = msgBubble.mapToItem(listView, 0, 0).y
+        if (topOffset < 0) return -topOffset
+        const bottomOffset = topOffset + height - listView.height
+        if (bottomOffset > 0) return -bottomOffset
+        return 0
+    }
+    x: xPositionProvider(width)
+    y: yPositionProvider(height)
 
     signal addMoreEmoji
+    onAddMoreEmoji: {
+        JamiQmlUtils.updateMessageBarButtonsPoints()
+        openEmojiPicker()
+    }
 
-    onOpened: {
-        root.closeWithoutAnimation = false
+    function openEmojiPicker() {
+        var component =  WITH_WEBENGINE ?
+                    Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") :
+                    Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
+        emojiPicker = component.createObject(root.parent, { listView: listView })
+        emojiPicker.emojiIsPicked.connect(function(content) {
+            if (emojiReplied.includes(content)) {
+                MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId)
+            } else {
+                MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId)
+            }
+        })
+        if (emojiPicker !== null) {
+            root.opacity = 0
+            emojiPicker.closed.connect(() => close())
+            emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth)
+            emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight)
+            emojiPicker.open()
+        } else {
+            console.log("Error creating emojiPicker from message options popup");
+        }
     }
 
+    // Close the picker when listView vertical properties change.
+    property real listViewHeight: listView.height
+    onListViewHeightChanged: close()
+    property bool isScrolling: listView.verticalScrollBar.active
+    onIsScrollingChanged: close()
+
+    onOpened: root.closeWithoutAnimation = false
+    onClosed: if (emojiPicker) emojiPicker.closeEmojiPicker()
+
     function getModel() {
         var model = ["👍", "👎", "😂"]
         var cur = []
@@ -132,7 +190,7 @@ Popup {
                     onClicked: {
                         root.closeWithoutAnimation = true
                         root.addMoreEmoji()
-                        close()
+                        //close()
                     }
                 }
             }
@@ -152,7 +210,7 @@ Popup {
                 Layout.fillWidth: true
                 Layout.margins: 5
                 onClicked: {
-                    UtilsAdapter.setClipboardText(msg)
+                    UtilsAdapter.setClipboardText(msgBody)
                     close()
                 }
             }
@@ -184,7 +242,7 @@ Popup {
             MessageOptionButton {
                 id: buttonEdit
 
-                visible: root.out && type === Interaction.Type.TEXT
+                visible: root.isOutgoing && type === Interaction.Type.TEXT
                 textButton: JamiStrings.editMessage
                 iconSource: JamiResources.edit_svg
                 Layout.fillWidth: true
@@ -198,7 +256,7 @@ Popup {
             }
 
             MessageOptionButton {
-                visible: root.out && type === Interaction.Type.TEXT
+                visible: root.isOutgoing && type === Interaction.Type.TEXT
                 textButton: JamiStrings.deleteMessage
                 iconSource: JamiResources.delete_svg
                 Layout.fillWidth: true
diff --git a/src/app/commoncomponents/SBSMessageBase.qml b/src/app/commoncomponents/SBSMessageBase.qml
index 1914ef0667eba65e92f71393462902c896110932..36f24cf641e78609077b5aa59c1cdef46fb6432f 100644
--- a/src/app/commoncomponents/SBSMessageBase.qml
+++ b/src/app/commoncomponents/SBSMessageBase.qml
@@ -55,9 +55,15 @@ Control {
     readonly property real hPadding: JamiTheme.sbsMessageBasePreferredPadding
     property bool textHovered: false
     property alias replyAnimation: selectAnimation
-    width: ListView.view ? ListView.view.width : 0
+    width: listView.width
     height: mainColumnLayout.implicitHeight
 
+    // If the ListView attached properties are not available,
+    // then the root delegate is likely a Loader.
+    readonly property ListView listView: ListView.view ?
+                                             ListView.view :
+                                             parent.ListView.view
+
     rightPadding: hPadding
     leftPadding: hPadding
 
@@ -184,9 +190,18 @@ Control {
                         height: optionButtonItem.height
 
                         onClicked: {
-                            messageOptionPopup.open()
-                            messageOptionPopup.x = messageOptionPopup.setXposition(messageOptionPopup.width)
-                            messageOptionPopup.y = messageOptionPopup.setYposition(messageOptionPopup.height)
+                            var component = Qt.createComponent("qrc:/commoncomponents/MessageOptionsPopup.qml")
+                            var obj = component.createObject(bubble, {
+                                                                 "emojiReplied": Qt.binding(() => emojiReaction.emojiTexts),
+                                                                 "isOutgoing": isOutgoing,
+                                                                 "msgId": Id,
+                                                                 "msgBody": Body,
+                                                                 "type": Type,
+                                                                 "transferName": TransferName,
+                                                                 "msgBubble": bubble,
+                                                                 "listView": listView
+                                                             })
+                            obj.open()
                         }
                     }
 
@@ -214,103 +229,6 @@ Control {
                     }
                 }
 
-                ChatviewMessageOptions {
-                    id: messageOptionPopup
-
-                    emojiReplied: emojiReaction.emojiTexts
-                    out: isOutgoing
-                    msgId: Id
-                    msg: Body
-                    type: Type
-                    transferName: TransferName
-                    visible: false
-
-                    property bool isScrolling: JamiQmlUtils.isChatviewScrolling
-                    property real rootWidth: root.width
-                    property var emojiPicker
-
-                    onIsScrollingChanged: {
-                        messageOptionPopup.close()
-                        if (messageOptionPopup.emojiPicker)
-                            messageOptionPopup.emojiPicker.closeEmojiPicker()
-                    }
-
-                    onAddMoreEmoji: {
-                        JamiQmlUtils.updateMessageBarButtonsPoints()
-                        openEmojiPicker()
-                    }
-
-                    onRootWidthChanged: {
-                        if (emojiPicker)
-                            emojiPicker.x = setXposition(JamiTheme.emojiPickerWidth)
-                        messageOptionPopup.x = setXposition(width)
-                        messageOptionPopup.y = setYposition(height)
-                    }
-
-                    Connections {
-                        target: messageOptionPopup.emojiPicker ? messageOptionPopup.emojiPicker : null
-                        function onEmojiIsPicked(content) {
-                            if (messageOptionPopup.emojiReplied.includes(content))
-                                MessagesAdapter.removeEmojiReaction(CurrentConversation.id,content,messageOptionPopup.msgId)
-                            else
-                                MessagesAdapter.addEmojiReaction(CurrentConversation.id,content,messageOptionPopup.msgId)
-                        }
-                    }
-
-                    function openEmojiPicker() {
-                        var component =  WITH_WEBENGINE
-                                  ? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml")
-                                  : Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
-                        messageOptionPopup.emojiPicker = component.createObject(msgRowlayout,
-                                                                                {
-                                                                                 x: setXposition(JamiTheme.emojiPickerWidth),
-                                                                                 y: setYposition(JamiTheme.emojiPickerHeight)
-                                                                                });
-                        if (messageOptionPopup.emojiPicker !== null) {
-                            messageOptionPopup.emojiPicker.open()
-                        } else {
-                            console.log("Error creating emojiPicker in SBSMessageBase");
-                        }
-                    }
-
-                    function setXposition(width) {
-
-                        var distBorders = root.width - bubble.width - width
-                        if (isOutgoing) {
-                            if (distBorders > 0)
-                                x = bubble.x - width
-                            else
-                                x = bubble.x
-                        } else {
-                            if (distBorders > 0)
-                                x = bubble.x + bubble.width
-                            else
-                                x = bubble.x + bubble.width - width
-                        }
-                        return x
-                    }
-
-                    function setYposition(height) {
-                        var bottomOffset = 0
-                        if (JamiQmlUtils.messageBarButtonsRowObj) {
-                            bottomOffset = JamiQmlUtils.messageBarButtonsRowObj.height
-                        }
-                        var mappedCoord = bubble.mapToItem(appWindow.contentItem, 0, 0)
-                        var distBottomScreen = appWindow.height - mappedCoord.y - height - bottomOffset
-                        if (distBottomScreen < 0) {
-                            return distBottomScreen
-                        }
-                        var topOffset = 0
-                        if (JamiQmlUtils.messagingHeaderRectRowLayout) {
-                            topOffset = JamiQmlUtils.messagingHeaderRectRowLayout.height
-                        }
-                        var distTopScreen = mappedCoord.y - topOffset
-                        if (distTopScreen < 0)
-                            return -distTopScreen
-                        return 0
-                    }
-                }
-
                 MessageBubble {
                     id: bubble
 
@@ -321,7 +239,8 @@ Control {
                     function getBaseColor() {
                         var baseColor = isOutgoing ? JamiTheme.messageOutBgColor
                                                    : CurrentConversation.isCoreDialog ?
-                                                         JamiTheme.messageInBgColor : Qt.lighter(CurrentConversation.color, 1.5)
+                                                         JamiTheme.messageInBgColor :
+                                                         Qt.lighter(CurrentConversation.color, 1.5)
                         if (Id === MessagesAdapter.replyToId || Id === MessagesAdapter.editId) {
                             // If we are replying to or editing the message
                             return Qt.darker(baseColor, 1.5)
diff --git a/src/app/constant/JamiQmlUtils.qml b/src/app/constant/JamiQmlUtils.qml
index fff14ba4398285422bb3a89e74f7d3d9f6f5eec3..4d051a9805e602951dfdb24f060722f672102e46 100644
--- a/src/app/constant/JamiQmlUtils.qml
+++ b/src/app/constant/JamiQmlUtils.qml
@@ -38,10 +38,6 @@ Item {
         Object.assign(JamiQmlUtils.accountCreationInputParaObject, inputPara)
         return accountCreationInputParaObject
     }
-    //to know if the chatview is being scrolled
-    property bool isChatviewScrolling
-    //chatviewHeader
-    property var messagingHeaderRectRowLayout
 
     // MessageBar buttons in mainview points
     property var mainViewRectObj
diff --git a/src/app/mainview/components/ChatViewFooter.qml b/src/app/mainview/components/ChatViewFooter.qml
index ce840d554644b4ce8aaed7a2804c9b85ed5980d7..3f14f7aea87c563500f4cc0799324f3947e7f0e7 100644
--- a/src/app/mainview/components/ChatViewFooter.qml
+++ b/src/app/mainview/components/ChatViewFooter.qml
@@ -150,7 +150,11 @@ Rectangle {
                           ? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml")
                           : Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
                 messageBar.emojiPicker =
-                        component.createObject(messageBar, {x: setXposition(), y: setYposition()});
+                        component.createObject(messageBar, {
+                                                   x: setXposition(),
+                                                   y: setYposition(),
+                                                   listView: null
+                                               });
                 if (messageBar.emojiPicker === null) {
                     console.log("Error creating emojiPicker in chatViewFooter");
                 }
diff --git a/src/app/mainview/components/ChatViewHeader.qml b/src/app/mainview/components/ChatViewHeader.qml
index 468f3da14acf463c0a632656ad8b6ba64c3b18d6..9601a0ac323d25c7a4029293a9c2cbc7c43151cf 100644
--- a/src/app/mainview/components/ChatViewHeader.qml
+++ b/src/app/mainview/components/ChatViewHeader.qml
@@ -260,7 +260,6 @@ Rectangle {
             }
 
         }
-        Component.onCompleted: JamiQmlUtils.messagingHeaderRectRowLayout = messagingHeaderRectRowLayout
     }
 
     CustomBorder {
diff --git a/src/app/nowebengine/EmojiPicker.qml b/src/app/nowebengine/EmojiPicker.qml
index 3adca4f9481e32cfc1ba1a397e3348e0c7887c22..ceb6528a148eb376499a72c0b7f4615de3d0e36c 100644
--- a/src/app/nowebengine/EmojiPicker.qml
+++ b/src/app/nowebengine/EmojiPicker.qml
@@ -21,6 +21,8 @@ import QtQuick
 Rectangle {
     id: root
 
+    required property ListView listView
+
     signal emojiIsPicked(string content)
     function openEmojiPicker() {}
     function closeEmojiPicker() {}
diff --git a/src/app/webengine/emojipicker/EmojiPicker.qml b/src/app/webengine/emojipicker/EmojiPicker.qml
index bf22e01a918b98a0566877abf847bf931cce5369..39b151e33fb4e51d30c5dc82c40cdfbbe1ccb10f 100644
--- a/src/app/webengine/emojipicker/EmojiPicker.qml
+++ b/src/app/webengine/emojipicker/EmojiPicker.qml
@@ -23,6 +23,7 @@ import Qt5Compat.GraphicalEffects
 import QtWebEngine
 import QtWebChannel
 
+import net.jami.Models 1.1
 import net.jami.Constants 1.1
 import net.jami.Adapters 1.1
 
@@ -31,8 +32,17 @@ import "../"
 Popup {
     id: root
 
+    required property ListView listView
+
     signal emojiIsPicked(string content)
 
+    // Close the picker when attached to a listView that receives height/scroll
+    // property changes.
+    property real listViewHeight: listView ? listView.height : 0
+    onListViewHeightChanged: close()
+    property bool isScrolling: listView ? listView.verticalScrollBar.active : false
+    onIsScrollingChanged: close()
+
     function openEmojiPicker() {
         root.open()
         emojiPickerWebView.runJavaScript(