diff --git a/qml.qrc b/qml.qrc
index fd9a00373927053cf407ed396ddbfcd52c25fc76..2d10eef933d77dfb95c431df990caa1012d2e672 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -109,6 +109,7 @@
         <file>src/mainview/components/SidePanelTabBar.qml</file>
         <file>src/mainview/components/WelcomePageQrDialog.qml</file>
         <file>src/mainview/components/ConversationSmartListContextMenu.qml</file>
+        <file>src/mainview/components/SwarmParticipantContextMenu.qml</file>
         <file>src/mainview/components/CallViewContextMenu.qml</file>
         <file>src/mainview/components/UserProfile.qml</file>
         <file>src/mainview/components/SwarmDetailsPanel.qml</file>
diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml
index 4a88a1ed81746e86d0eb7058e70a75316157497e..bb1a7917edb0f1f02f32ae4396480e05df34812f 100644
--- a/src/constant/JamiStrings.qml
+++ b/src/constant/JamiStrings.qml
@@ -623,4 +623,9 @@ Item {
     // NewSwarmPage
 
     property string createTheSwarm: qsTr("Create the swarm")
+    property string goToConversation: qsTr("Go to conversation")
+    property string promoteAdministrator: qsTr("Promote to administrator")
+    property string kickMember: qsTr("Kick member")
+    property string administrator: qsTr("Administrator")
+    property string invited: qsTr("Invited")
 }
diff --git a/src/mainview/components/SwarmDetailsPanel.qml b/src/mainview/components/SwarmDetailsPanel.qml
index 12bab5f768a3dc2dc9fa947032f618fc4435148e..8cac190c883cf262e88b83c6c7e7580b7643b290 100644
--- a/src/mainview/components/SwarmDetailsPanel.qml
+++ b/src/mainview/components/SwarmDetailsPanel.qml
@@ -48,6 +48,8 @@ Rectangle {
                 Layout.alignment: Qt.AlignCenter
                 Layout.preferredWidth: JamiTheme.avatarSizeInCall
                 Layout.preferredHeight: JamiTheme.avatarSizeInCall
+                Layout.topMargin: JamiTheme.swarmDetailsPageTopMargin
+                Layout.bottomMargin: JamiTheme.preferredMarginSize
 
                 imageId: LRCInstance.selectedConvUid
 
@@ -164,50 +166,97 @@ Rectangle {
                 spacing: JamiTheme.preferredMarginSize
                 anchors.topMargin: JamiTheme.preferredMarginSize
 
-                model: CurrentConversation.uris
-                delegate: RowLayout {
-                    spacing: 10
+                SwarmParticipantContextMenu {
+                    id: contextMenu
 
-                    Avatar {
-                        width: JamiTheme.smartListAvatarSize
-                        height: JamiTheme.smartListAvatarSize
-                        z: -index
+                    function openMenuAt(x, y, participantUri) {
+                        contextMenu.x = x
+                        contextMenu.y = y
+                        contextMenu.conversationId = CurrentConversation.id
+                        contextMenu.participantUri = participantUri
 
-                        imageId: CurrentAccount.uri == modelData ? CurrentAccount.id : modelData
-                        showPresenceIndicator: UtilsAdapter.getContactPresence(CurrentAccount.id, modelData)
-                        mode: CurrentAccount.uri == modelData ? Avatar.Mode.Account : Avatar.Mode.Contact
+                        openMenu()
                     }
+                }
 
-                    ElidedTextLabel {
-                        id: bestName
-
-                        Layout.preferredWidth: JamiTheme.preferredFieldWidth
-                        Layout.preferredHeight: JamiTheme.preferredFieldHeight
-
-                        eText: UtilsAdapter.getContactBestName(CurrentAccount.id, modelData)
-                        maxWidth: JamiTheme.preferredFieldWidth
+                model: CurrentConversation.uris
+                delegate: Item {
 
-                        font.pointSize: JamiTheme.participantFontSize
-                        color: JamiTheme.primaryForegroundColor
-                        font.kerning: true
+                    width: members.width
+                    height: JamiTheme.smartListItemHeight
 
-                        verticalAlignment: Text.AlignVCenter
+                    MouseArea {
+                        anchors.fill: parent
+                        acceptedButtons: Qt.RightButton
+                        onClicked: function (mouse) {
+                            contextMenu.openMenuAt(x + mouse.x, y + mouse.y, modelData)
+                        }
                     }
 
-                    ElidedTextLabel {
-                        id: role
-
-                        Layout.preferredHeight: JamiTheme.preferredFieldHeight
-
-                        eText: UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData)
-                        maxWidth: JamiTheme.preferredFieldWidth
-
-                        font.pointSize: JamiTheme.participantFontSize
-                        color: JamiTheme.textColorHovered
-                        font.kerning: true
-
-                        horizontalAlignment: Text.AlignRight
-                        verticalAlignment: Text.AlignVCenter
+                    RowLayout {
+                        spacing: 10
+
+                        Avatar {
+                            width: JamiTheme.smartListAvatarSize
+                            height: JamiTheme.smartListAvatarSize
+                            Layout.leftMargin: JamiTheme.preferredMarginSize
+                            z: -index
+                            opacity: {
+                                var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData)
+                                return role === Member.Role.INVITED ? 0.5 : 1
+                            }
+
+                            imageId: CurrentAccount.uri == modelData ? CurrentAccount.id : modelData
+                            showPresenceIndicator: UtilsAdapter.getContactPresence(CurrentAccount.id, modelData)
+                            mode: CurrentAccount.uri == modelData ? Avatar.Mode.Account : Avatar.Mode.Contact
+                        }
+
+                        ElidedTextLabel {
+                            id: bestName
+
+                            Layout.preferredWidth: JamiTheme.preferredFieldWidth
+                            Layout.preferredHeight: JamiTheme.preferredFieldHeight
+
+                            eText: UtilsAdapter.getContactBestName(CurrentAccount.id, modelData)
+                            maxWidth: JamiTheme.preferredFieldWidth
+
+                            font.pointSize: JamiTheme.participantFontSize
+                            color: JamiTheme.primaryForegroundColor
+                            opacity: {
+                                var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData)
+                                return role === Member.Role.INVITED ? 0.5 : 1
+                            }
+                            font.kerning: true
+
+                            verticalAlignment: Text.AlignVCenter
+                        }
+
+                        ElidedTextLabel {
+                            id: role
+
+                            Layout.preferredHeight: JamiTheme.preferredFieldHeight
+
+                            eText: {
+                                var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData)
+                                if (role === Member.Role.ADMIN)
+                                    return JamiStrings.administrator
+                                if (role === Member.Role.INVITED)
+                                    return JamiStrings.invited
+                                return ""
+                            }
+                            maxWidth: JamiTheme.preferredFieldWidth
+
+                            font.pointSize: JamiTheme.participantFontSize
+                            color: JamiTheme.textColorHovered
+                            opacity: {
+                                var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData)
+                                return role === Member.Role.INVITED ? 0.5 : 1
+                            }
+                            font.kerning: true
+
+                            horizontalAlignment: Text.AlignRight
+                            verticalAlignment: Text.AlignVCenter
+                        }
                     }
                 }
             }
diff --git a/src/mainview/components/SwarmParticipantContextMenu.qml b/src/mainview/components/SwarmParticipantContextMenu.qml
new file mode 100644
index 0000000000000000000000000000000000000000..17f0df985f6ca07f9034d9a2c78f812ef8820faf
--- /dev/null
+++ b/src/mainview/components/SwarmParticipantContextMenu.qml
@@ -0,0 +1,76 @@
+/*
+ * 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
+
+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 var conversationId: ""
+    property var participantUri: ""
+
+    // TODO get authorization
+
+    property list<GeneralMenuItem> menuItems: [
+        GeneralMenuItem {
+            id: startVideoCallItem
+            itemName: JamiStrings.startVideoCall
+            onClicked: {
+            }
+        },
+        GeneralMenuItem {
+            id: startAudioCall
+            itemName: JamiStrings.startAudioCall
+            onClicked: {
+            }
+        },
+        GeneralMenuItem {
+            id: goToConversation
+
+            itemName: JamiStrings.goToConversation
+            onClicked: {
+            }
+        },
+        GeneralMenuItem {
+            id: promoteAdministrator
+            itemName: JamiStrings.promoteAdministrator
+        },
+        GeneralMenuItem {
+            id: blockContact
+            itemName: JamiStrings.blockContact
+            iconSource: JamiResources.block_black_24dp_svg
+        },
+        GeneralMenuItem {
+            id: kickMember
+            itemName: JamiStrings.kickMember
+
+            // TODO can trigger (enough permission for self and member accepted)
+            onClicked: {
+                MessagesAdapter.removeConversationMember(conversationId, participantUri)
+            }
+        }
+    ]
+
+    Component.onCompleted: menuItemsToLoad = menuItems
+}
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index 64ed54c7fab26f2d7f5bbf875b831386352b13e1..fb4a4c0a8a3d9f749c623475c2e6aa0f75eeb06e 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -384,6 +384,13 @@ MessagesAdapter::removeConversation(const QString& convUid)
     accInfo.conversationModel->removeConversation(convUid);
 }
 
+void
+MessagesAdapter::removeConversationMember(const QString& convUid, const QString& memberUri)
+{
+    auto& accInfo = lrcInstance_->getCurrentAccountInfo();
+    accInfo.conversationModel->removeConversationMember(convUid, memberUri);
+}
+
 void
 MessagesAdapter::removeContact(const QString& convUid, bool banContact)
 {
diff --git a/src/messagesadapter.h b/src/messagesadapter.h
index c64cef54553d164fd459a8a833d06aef7b2cdd50..1840cb6aa985205a875ee5448338b147252ec67c 100644
--- a/src/messagesadapter.h
+++ b/src/messagesadapter.h
@@ -85,6 +85,7 @@ protected:
     Q_INVOKABLE void connectConversationModel();
     Q_INVOKABLE void sendConversationRequest();
     Q_INVOKABLE void removeConversation(const QString& convUid);
+    Q_INVOKABLE void removeConversationMember(const QString& convUid, const QString& participantUri);
     Q_INVOKABLE void removeContact(const QString& convUid, bool banContact = false);
     Q_INVOKABLE void clearConversationHistory(const QString& accountId, const QString& convUid);
     Q_INVOKABLE void acceptInvitation(const QString& convId = {});