diff --git a/qml.qrc b/qml.qrc
index 3151607882fb5326c67f3574ca0cd343a430a68c..fd9a00373927053cf407ed396ddbfcd52c25fc76 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -112,6 +112,7 @@
         <file>src/mainview/components/CallViewContextMenu.qml</file>
         <file>src/mainview/components/UserProfile.qml</file>
         <file>src/mainview/components/SwarmDetailsPanel.qml</file>
+        <file>src/mainview/components/AddMemberPanel.qml</file>
         <file>src/mainview/components/SelectScreen.qml</file>
         <file>src/mainview/components/ScreenRubberBand.qml</file>
         <file>src/mainview/components/ContactPicker.qml</file>
diff --git a/src/constant/JamiTheme.qml b/src/constant/JamiTheme.qml
index 732241cf736f42a5136d5690642e7f6cb99611cb..2cd0c36676a529f2cf61a106d075650f46bd93cb 100644
--- a/src/constant/JamiTheme.qml
+++ b/src/constant/JamiTheme.qml
@@ -368,6 +368,9 @@ Item {
     property real mainViewPreferredWidth: 725
     property real mainViewPreferredHeight: 600
 
+    // Details page
+    property real detailsPageMinWidth: 300
+
     function setTheme(dark) {
         darkTheme = dark
     }
diff --git a/src/contactadapter.cpp b/src/contactadapter.cpp
index 6ae89c87f722d22341acc881e2ec51b77205bab7..e9aafdf8f615a87e5be8a1f85a4c61e52215c666 100644
--- a/src/contactadapter.cpp
+++ b/src/contactadapter.cpp
@@ -32,6 +32,18 @@ ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
     }
 }
 
+bool
+ContactAdapter::hasDifferentMembers(const VectorString& currentMembers,
+                                    const VectorString& convMembers) const
+{
+    for (const auto& uri : convMembers) {
+        if (uri != lrcInstance_->getCurrentAccountInfo().profileInfo.uri
+            && !currentMembers.contains(uri))
+            return true;
+    }
+    return false;
+}
+
 QVariant
 ContactAdapter::getContactSelectableModel(int type)
 {
@@ -54,11 +66,16 @@ ContactAdapter::getContactSelectableModel(int type)
                 return !defaultModerators_.contains(index.data(Role::URI).toString());
             });
         break;
-    case SmartListModel::Type::ADDCONVMEMBER:
-        selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegularExpression&) {
-            return index.data(Role::IsCoreDialog).toBool();
-        });
+    case SmartListModel::Type::ADDCONVMEMBER: {
+        auto currentConvID = lrcInstance_->get_selectedConvUid();
+        auto* convModel = lrcInstance_->getCurrentConversationModel();
+        auto members = convModel->peersForConversation(currentConvID);
+        selectableProxyModel_->setPredicate(
+            [this, members](const QModelIndex& index, const QRegularExpression&) {
+                return hasDifferentMembers(members, index.data(Role::Uris).toStringList());
+            });
         break;
+    }
     case SmartListModel::Type::CONFERENCE:
         selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegularExpression&) {
             return index.data(Role::Presence).toBool();
@@ -107,15 +124,18 @@ ContactAdapter::setSearchFilter(const QString& filter)
                         && index.data(Role::Title).toString().contains(filter));
             });
     } else if (listModeltype_ == SmartListModel::Type::ADDCONVMEMBER) {
-        selectableProxyModel_->setPredicate(
-            [this, filter](const QModelIndex& index, const QRegularExpression&) {
-                return (index.data(Role::Title).toString().contains(filter, Qt::CaseInsensitive)
-                        || index.data(Role::RegisteredName)
-                               .toString()
-                               .contains(filter, Qt::CaseInsensitive)
-                        || index.data(Role::URI).toString().contains(filter, Qt::CaseInsensitive))
-                       && index.data(Role::IsCoreDialog).toBool();
-            });
+        auto currentConvID = lrcInstance_->get_selectedConvUid();
+        auto* convModel = lrcInstance_->getCurrentConversationModel();
+        auto members = convModel->peersForConversation(currentConvID);
+        selectableProxyModel_->setPredicate([this, filter, members](const QModelIndex& index,
+                                                                    const QRegularExpression&) {
+            return hasDifferentMembers(members, index.data(Role::Uris).toStringList())
+                   && (index.data(Role::Title).toString().contains(filter, Qt::CaseInsensitive)
+                       || index.data(Role::RegisteredName)
+                              .toString()
+                              .contains(filter, Qt::CaseInsensitive)
+                       || index.data(Role::Uris).toString().contains(filter, Qt::CaseInsensitive));
+        });
     }
     selectableProxyModel_->setFilterRegularExpression(
         QRegularExpression(filter, QRegularExpression::CaseInsensitiveOption));
@@ -132,8 +152,16 @@ ContactAdapter::contactSelected(int index)
     if (contactIndex.isValid()) {
         switch (listModeltype_) {
         case SmartListModel::Type::ADDCONVMEMBER: {
-            const auto uri = contactIndex.data(Role::URI).value<QString>();
-            convModel->addConversationMember(lrcInstance_->get_selectedConvUid(), uri);
+            auto members = convModel->peersForConversation(lrcInstance_->get_selectedConvUid());
+            auto cntMembers = members.size();
+            const auto uris = contactIndex.data(Role::Uris).toStringList();
+            for (const auto& uri : uris) {
+                // TODO remove < 9
+                if (!members.contains(uri) && cntMembers < 9) {
+                    cntMembers++;
+                    convModel->addConversationMember(lrcInstance_->get_selectedConvUid(), uri);
+                }
+            }
             break;
         }
         case SmartListModel::Type::CONFERENCE: {
diff --git a/src/contactadapter.h b/src/contactadapter.h
index b7a17917436216ac446f08b52c53c162d2ea0e56..c736816ffe62ce836298c074fedf385a77d204b2 100644
--- a/src/contactadapter.h
+++ b/src/contactadapter.h
@@ -104,6 +104,8 @@ private:
 
     QStringList defaultModerators_;
 
+    bool hasDifferentMembers(const VectorString& currentMembers, const VectorString& convMembers) const;
+
 Q_SIGNALS:
     void defaultModeratorsUpdated();
 };
diff --git a/src/mainview/components/AddMemberPanel.qml b/src/mainview/components/AddMemberPanel.qml
new file mode 100644
index 0000000000000000000000000000000000000000..95cb7db6f9729c34ebefb88832d3b432e38a2914
--- /dev/null
+++ b/src/mainview/components/AddMemberPanel.qml
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 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
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import net.jami.Models 1.1
+import net.jami.Adapters 1.1
+import net.jami.Constants 1.1
+
+import "../../commoncomponents"
+
+Rectangle {
+    id: root
+
+    color: JamiTheme.backgroundColor
+    property int type: ContactList.ADDCONVMEMBER
+
+    width: 250
+
+    ColumnLayout {
+        id: contactPickerPopupRectColumnLayout
+
+        anchors.top: root.top
+        anchors.bottom: root.bottom
+        anchors.margins: 16
+
+        ContactSearchBar {
+            id: contactPickerContactSearchBar
+
+            Layout.alignment: Qt.AlignCenter
+            Layout.margins: 5
+            Layout.fillWidth: true
+            Layout.preferredHeight: 35
+
+            placeHolderText: JamiStrings.addParticipant
+
+            onContactSearchBarTextChanged: {
+                ContactAdapter.setSearchFilter(text)
+            }
+        }
+
+        JamiListView {
+            id: contactPickerListView
+
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: root.width - 8
+            Layout.preferredHeight: contactPickerPopupRectColumnLayout.height - contactPickerContactSearchBar.height
+
+            model: ContactAdapter.getContactSelectableModel(type)
+
+            Connections {
+                enabled: visible
+                target: CurrentConversation
+
+                onUrisChanged: {
+                    model = ContactAdapter.getContactSelectableModel(type)
+                }
+            }
+
+            onVisibleChanged: {
+                if (visible)
+                    model = ContactAdapter.getContactSelectableModel(type)
+            }
+
+            delegate: ContactPickerItemDelegate {
+                id: contactPickerItemDelegate
+
+                showPresenceIndicator: true
+            }
+        }
+    }
+}
diff --git a/src/mainview/components/ChatView.qml b/src/mainview/components/ChatView.qml
index 0a4691ac9d054145a5ad387f75e04a1f16ace1ce..c9b34bfb0f6aa8da51328ce26097d38cb28b4617 100644
--- a/src/mainview/components/ChatView.qml
+++ b/src/mainview/components/ChatView.qml
@@ -44,6 +44,7 @@ Rectangle {
     function focusChatView() {
         chatViewFooter.textInput.forceActiveFocus()
         swarmDetailsPanel.visible = false
+        addMemberPanel.visible = false
     }
 
     color: JamiTheme.chatviewBgColor
@@ -78,9 +79,26 @@ Rectangle {
             }
 
             onShowDetailsClicked: {
+                addMemberPanel.visible = false
                 swarmDetailsPanel.visible = !swarmDetailsPanel.visible
             }
 
+            Connections {
+                target: CurrentConversation
+
+                onUrisChanged: {
+                    if (CurrentConversation.uris.length >= 8 && addMemberPanel.visible) {
+                        swarmDetailsPanel.visible = false
+                        addMemberPanel.visible = !addMemberPanel.visible
+                    }
+                }
+            }
+
+            onAddToConversationClicked: {
+                swarmDetailsPanel.visible = false
+                addMemberPanel.visible = !addMemberPanel.visible
+            }
+
             onPluginSelector: {
                 // Create plugin handler picker - PLUGINS
                 PluginHandlerPickerCreation.createPluginHandlerPickerObjects(
@@ -91,14 +109,27 @@ Rectangle {
             }
         }
 
-        RowLayout {
+        SplitView {
             id: chatViewMainRow
             Layout.fillWidth: true
             Layout.fillHeight: true
 
+            handle: Rectangle {
+                implicitWidth: JamiTheme.splitViewHandlePreferredWidth
+                implicitHeight: splitView.height
+                color: JamiTheme.primaryBackgroundColor
+                Rectangle {
+                    implicitWidth: 1
+                    implicitHeight: splitView.height
+                    color: JamiTheme.tabbarBorderColor
+                }
+            }
+
             ColumnLayout {
-                Layout.fillHeight: true
-                Layout.fillWidth: true
+                SplitView.maximumWidth: splitView.width
+                // Note, without JamiTheme.detailsPageMinWidth, sometimes the details page is hidden at the right
+                SplitView.preferredWidth: Math.max(0, 2 * splitView.width / 3 - JamiTheme.detailsPageMinWidth)
+                SplitView.fillHeight: true
 
                 StackLayout {
                     id: chatViewStack
@@ -162,6 +193,23 @@ Rectangle {
             SwarmDetailsPanel {
                 id: swarmDetailsPanel
                 visible: false
+
+                SplitView.maximumWidth: splitView.width
+                SplitView.preferredWidth: Math.max(JamiTheme.detailsPageMinWidth, splitView.width / 3)
+                SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
+                SplitView.fillHeight: true
+                Layout.fillHeight: true
+                Layout.fillWidth: true
+            }
+
+            AddMemberPanel {
+                id: addMemberPanel
+                visible: false
+
+                SplitView.maximumWidth: splitView.width
+                SplitView.preferredWidth: Math.max(JamiTheme.detailsPageMinWidth, splitView.width / 3)
+                SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
+                SplitView.fillHeight: true
                 Layout.fillHeight: true
                 Layout.fillWidth: true
             }
diff --git a/src/mainview/components/ChatViewHeader.qml b/src/mainview/components/ChatViewHeader.qml
index ff0cdcd172674d4a9f4a483519439e230df48baa..8f150f711a3231914fff6475db2e0fccdf72c1a3 100644
--- a/src/mainview/components/ChatViewHeader.qml
+++ b/src/mainview/components/ChatViewHeader.qml
@@ -25,7 +25,6 @@ import net.jami.Constants 1.1
 import net.jami.Adapters 1.1
 
 import "../../commoncomponents"
-import "../js/contactpickercreation.js" as ContactPickerCreation
 
 Rectangle {
     id: root
@@ -35,6 +34,7 @@ Rectangle {
 
     signal backClicked
     signal needToHideConversationInCall
+    signal addToConversationClicked
     signal pluginSelector
     signal showDetailsClicked
 
@@ -61,11 +61,6 @@ Rectangle {
 
     color: JamiTheme.chatviewBgColor
 
-    function addToConversationClicked() {
-        ContactPickerCreation.createContactPickerObjects(ContactList.ADDCONVMEMBER, root)
-        ContactPickerCreation.openContactPicker()
-    }
-
     RowLayout {
         id: messagingHeaderRectRowLayout
 
@@ -185,15 +180,15 @@ Rectangle {
             PushButton {
                 id: addParticipantsButton
 
-                visible: addMemberVisibility
-
                 source: JamiResources.add_people_24dp_svg
                 toolTipText: JamiStrings.addParticipants
 
                 normalColor: JamiTheme.chatviewBgColor
                 imageColor: JamiTheme.chatviewButtonColor
 
-                onClicked: root.addToConversationClicked()
+                visible: CurrentConversation.uris.length < 8 && addMemberVisibility
+
+                onClicked: addToConversationClicked()
             }
 
             PushButton {
diff --git a/src/mainview/components/ContactPickerItemDelegate.qml b/src/mainview/components/ContactPickerItemDelegate.qml
index 0963f6052efee8a35338b2caf5c9fa60566e40ae..238046ac2f2fe9400ed0a1d0d19575766d00d8fb 100644
--- a/src/mainview/components/ContactPickerItemDelegate.qml
+++ b/src/mainview/components/ContactPickerItemDelegate.qml
@@ -28,7 +28,9 @@ import "../../commoncomponents"
 ItemDelegate {
     id: contactPickerItemDelegate
 
-    property alias showPresenceIndicator: avatar.showPresenceIndicator
+    property var showPresenceIndicator: false
+
+    signal contactClicked
 
     ConversationAvatar {
         id: avatar
@@ -41,6 +43,8 @@ ItemDelegate {
         height: 40
 
         imageId: UID
+
+        showPresenceIndicator: contactPickerItemDelegate.showPresenceIndicator && Presence
     }
 
     Rectangle {
@@ -102,7 +106,7 @@ ItemDelegate {
         color: JamiTheme.backgroundColor
 
 
-        implicitWidth: contactPickerPopupRect.width
+        implicitWidth: root.width
         implicitHeight: Math.max(
                             contactPickerContactName.height
                             + textMetricsContactPickerContactId.height + 10,
@@ -125,7 +129,10 @@ ItemDelegate {
             itemSmartListBackground.color = JamiTheme.normalButtonColor
 
             ContactAdapter.contactSelected(index)
-            contactPickerPopup.close()
+            root.contactClicked()
+            // TODO remove from there
+            if (contactPickerPopup)
+                contactPickerPopup.close()
         }
 
         onEntered: {
diff --git a/src/mainview/components/SwarmDetailsPanel.qml b/src/mainview/components/SwarmDetailsPanel.qml
index 923f798fb7dcb5a04b39ce73281a2148a13aaeb6..12bab5f768a3dc2dc9fa947032f618fc4435148e 100644
--- a/src/mainview/components/SwarmDetailsPanel.qml
+++ b/src/mainview/components/SwarmDetailsPanel.qml
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 by Savoir-faire Linux
+ * Copyright (C) 2022 by Savoir-faire Linux
  * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
  *
  * This program is free software; you can redistribute it and/or modify