diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 1b3955ccfb0576b128258cb17386be32f4323070..58f33f78080d1162cb2c8de70b4b9ef80f71f49f 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -40,6 +40,16 @@ CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject*
 {
     participantsModel_.reset(new CallParticipantsModel(lrcInstance_, this));
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, participantsModel_.get(), "CallParticipantsModel");
+    participantsModelFiltered_.reset(
+        new GenericParticipantsFilterModel(lrcInstance_, participantsModel_.get()));
+    QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS,
+                                      participantsModelFiltered_.get(),
+                                      "GenericParticipantsFilterModel");
+    activeParticipantsModel_.reset(
+        new ActiveParticipantsFilterModel(lrcInstance_, participantsModel_.get()));
+    QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS,
+                                      activeParticipantsModel_.get(),
+                                      "ActiveParticipantsFilterModel");
     overlayModel_.reset(new CallOverlayModel(lrcInstance_, this));
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, overlayModel_.get(), "CallOverlayModel");
 
@@ -147,6 +157,8 @@ CallAdapter::onParticipantAdded(const QString& callId, int index)
     auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
     auto& callModel = accInfo.callModel;
     try {
+        if (lrcInstance_->get_selectedConvUid().isEmpty())
+            return;
         const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
             lrcInstance_->get_selectedConvUid());
         if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
@@ -154,8 +166,8 @@ CallAdapter::onParticipantAdded(const QString& callId, int index)
             return;
         }
         auto infos = getConferencesInfos();
-        participantsModel_->addParticipant(index, infos[index]);
-        Q_EMIT updateParticipantsLayout();
+        if (index < infos.size())
+            participantsModel_->addParticipant(index, infos[index]);
     } catch (...) {
     }
 }
@@ -166,6 +178,8 @@ CallAdapter::onParticipantRemoved(const QString& callId, int index)
     auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
     auto& callModel = accInfo.callModel;
     try {
+        if (lrcInstance_->get_selectedConvUid().isEmpty())
+            return;
         const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
             lrcInstance_->get_selectedConvUid());
         if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
@@ -173,7 +187,6 @@ CallAdapter::onParticipantRemoved(const QString& callId, int index)
             return;
         }
         participantsModel_->removeParticipant(index);
-        Q_EMIT updateParticipantsLayout();
     } catch (...) {
     }
 }
@@ -184,6 +197,8 @@ CallAdapter::onParticipantUpdated(const QString& callId, int index)
     auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
     auto& callModel = accInfo.callModel;
     try {
+        if (lrcInstance_->get_selectedConvUid().isEmpty())
+            return;
         const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
             lrcInstance_->get_selectedConvUid());
         if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
@@ -298,6 +313,7 @@ CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
         const auto& convInfo = lrcInstance_->getConversationFromCallId(callId);
         if (!convInfo.uid.isEmpty()) {
             Q_EMIT callInfosChanged(call.isAudioOnly, accountId, convInfo.uid);
+            participantsModel_->setConferenceLayout(static_cast<int>(call.layout), callId);
             updateCallOverlay(convInfo);
         }
     } catch (...) {
@@ -494,6 +510,7 @@ CallAdapter::updateCall(const QString& convUid, const QString& accountId, bool f
     updateCallOverlay(convInfo);
     updateRecordingPeers(true);
     participantsModel_->setParticipants(call->id, getConferencesInfos());
+    participantsModel_->setConferenceLayout(static_cast<int>(call->layout), call->id);
 }
 
 void
@@ -730,9 +747,6 @@ CallAdapter::maximizeParticipant(const QString& uri)
                 if (participant["active"].toBool()) {
                     callModel->setActiveParticipant(confId, uri);
                     callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
-                } else if (participant["y"].toInt() != 0) {
-                    callModel->setActiveParticipant(confId, uri);
-                    callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE);
                 } else {
                     callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
                 }
@@ -760,12 +774,7 @@ CallAdapter::minimizeParticipant(const QString& uri)
             if (participant["uri"].toString() == uri) {
                 if (participant["active"].toBool()) {
                     participant["active"] = !participant["active"].toBool();
-                    if (participant["y"].toInt() == 0) {
-                        callModel->setConferenceLayout(confId,
-                                                       lrc::api::call::Layout::ONE_WITH_SMALL);
-                    } else {
-                        callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
-                    }
+                    callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
                 }
                 return;
             }
@@ -902,34 +911,6 @@ CallAdapter::setHandRaised(const QString& uri, bool state)
     }
 }
 
-bool
-CallAdapter::isCurrentModerator() const
-{
-    const auto& convInfo = lrcInstance_->getConversationFromConvUid(
-        lrcInstance_->get_selectedConvUid());
-    if (!convInfo.uid.isEmpty()) {
-        auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
-        try {
-            auto confId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
-            auto participants = getConferencesInfos();
-            if (participants.size() == 0) {
-                return true;
-            } else {
-                auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
-                for (const auto& part : participants) {
-                    auto participant = part.toJsonObject();
-                    if (participant["uri"].toString() == accInfo.profileInfo.uri) {
-                        return participant["isModerator"].toBool();
-                    }
-                }
-            }
-            return false;
-        } catch (...) {
-        }
-    }
-    return true;
-}
-
 void
 CallAdapter::setModerator(const QString& uri, const bool state)
 {
diff --git a/src/calladapter.h b/src/calladapter.h
index 03f1915ab855fb46a477ab3da4723f7e466fef70..89dabc0df660a5c199e17ac6f3fa524afddc5f01 100644
--- a/src/calladapter.h
+++ b/src/calladapter.h
@@ -70,7 +70,6 @@ public:
     Q_INVOKABLE bool isModerator(const QString& uri = {}) const;
     Q_INVOKABLE bool isHandRaised(const QString& uri = {}) const;
     Q_INVOKABLE void setHandRaised(const QString& uri, bool state);
-    Q_INVOKABLE bool isCurrentModerator() const;
     Q_INVOKABLE void holdThisCallToggle();
     Q_INVOKABLE void muteThisCallToggle(bool mute);
     Q_INVOKABLE void recordThisCallToggle();
@@ -101,7 +100,6 @@ Q_SIGNALS:
                        const QString& previewId);
     void remoteRecordingChanged(const QStringList& peers, bool state);
     void eraseRemoteRecording();
-    void updateParticipantsLayout();
 
 public Q_SLOTS:
     void onShowIncomingCallView(const QString& accountId, const QString& convUid);
@@ -130,5 +128,7 @@ private:
     SystemTray* systemTray_;
     QScopedPointer<CallOverlayModel> overlayModel_;
     QScopedPointer<CallParticipantsModel> participantsModel_;
+    QScopedPointer<GenericParticipantsFilterModel> participantsModelFiltered_;
+    QScopedPointer<ActiveParticipantsFilterModel> activeParticipantsModel_;
     VectorString currentConfSubcalls_;
 };
diff --git a/src/callparticipantsmodel.cpp b/src/callparticipantsmodel.cpp
index c35f3ac1fb9a681dc9b10ba77a920e045bec1284..d45589cb12d0fc8d513d762fb6540f840fd1d057 100644
--- a/src/callparticipantsmodel.cpp
+++ b/src/callparticipantsmodel.cpp
@@ -92,10 +92,13 @@ CallParticipantsModel::roleNames() const
 void
 CallParticipantsModel::addParticipant(int index, const QVariant& infos)
 {
+    if (index > participants_.size())
+        return;
+    beginInsertRows(QModelIndex(), index, index);
+
     auto it = participants_.begin() + index;
     participants_.insert(it, CallParticipant::Item {infos.toJsonObject()});
 
-    beginInsertRows(QModelIndex(), index, index);
     endInsertRows();
 
     callId_ = participants_[index].item["callId"].toString();
@@ -110,32 +113,31 @@ CallParticipantsModel::updateParticipant(int index, const QVariant& infos)
     (*it) = CallParticipant::Item {infos.toJsonObject()};
 
     callId_ = participants_[index].item["callId"].toString();
-    Q_EMIT updateParticipant(it->item.toVariantMap());
+    Q_EMIT dataChanged(createIndex(index, 0), createIndex(index, 0));
 }
 
 void
 CallParticipantsModel::removeParticipant(int index)
 {
+    if (participants_.size() <= index)
+        return;
     callId_ = participants_[index].item["callId"].toString();
 
+    beginRemoveRows(QModelIndex(), index, index);
+
     auto it = participants_.begin() + index;
     participants_.erase(it);
 
-    beginRemoveRows(QModelIndex(), index, index);
     endRemoveRows();
 }
 
 void
 CallParticipantsModel::setParticipants(const QString& callId, const QVariantList& participants)
 {
-    if (callId_ == callId)
-        return;
-
     callId_ = callId;
 
     participants_.clear();
-    beginResetModel();
-    endResetModel();
+    reset();
 
     if (!participants.isEmpty()) {
         int idx = 0;
diff --git a/src/callparticipantsmodel.h b/src/callparticipantsmodel.h
index 62342d8c7f66eee7640fa9099113e2e056662540..0273bfb19786cc5c8fdfa16128f543476cefa321 100644
--- a/src/callparticipantsmodel.h
+++ b/src/callparticipantsmodel.h
@@ -68,12 +68,87 @@ struct Item
 };
 } // namespace CallParticipant
 
+/*
+ * The CurrentAccountFilterModel class
+ * is for the sole purpose of filtering out current account.
+ */
+class GenericParticipantsFilterModel final : public QSortFilterProxyModel
+{
+    Q_OBJECT
+
+public:
+    explicit GenericParticipantsFilterModel(LRCInstance* lrcInstance,
+                                            QAbstractListModel* parent = nullptr)
+        : QSortFilterProxyModel(parent)
+        , lrcInstance_(lrcInstance)
+    {
+        setSourceModel(parent);
+        setFilterRole(CallParticipant::Role::Active);
+    }
+
+    virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override
+    {
+        // Accept all participants in participants list filtered with active status.
+        auto index = sourceModel()->index(sourceRow, 0, sourceParent);
+        return !sourceModel()->data(index, CallParticipant::Role::Active).toBool();
+    }
+
+    Q_INVOKABLE void reset()
+    {
+        beginResetModel();
+        endResetModel();
+    }
+
+protected:
+    LRCInstance* lrcInstance_ {nullptr};
+};
+
+/*
+ * The ActiveParticipantsFilterModel class
+ * is for the sole purpose of filtering out current account.
+ */
+class ActiveParticipantsFilterModel final : public QSortFilterProxyModel
+{
+    Q_OBJECT
+
+public:
+    explicit ActiveParticipantsFilterModel(LRCInstance* lrcInstance,
+                                           QAbstractListModel* parent = nullptr)
+        : QSortFilterProxyModel(parent)
+        , lrcInstance_(lrcInstance)
+    {
+        setSourceModel(parent);
+        setFilterRole(CallParticipant::Role::Active);
+    }
+
+    virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override
+    {
+        // Accept all participants in participants list filtered with active status.
+        auto index = sourceModel()->index(sourceRow, 0, sourceParent);
+        return sourceModel()->data(index, CallParticipant::Role::Active).toBool();
+    }
+
+    Q_INVOKABLE void reset()
+    {
+        beginResetModel();
+        endResetModel();
+    }
+
+protected:
+    LRCInstance* lrcInstance_ {nullptr};
+};
+
 class CallParticipantsModel : public QAbstractListModel
 {
     Q_OBJECT
+
+    Q_PROPERTY(LayoutType conferenceLayout READ conferenceLayout NOTIFY layoutChanged)
 public:
     CallParticipantsModel(LRCInstance* instance, QObject* parent = nullptr);
 
+    typedef enum { GRID = 0, ONE_WITH_SMALL, ONE } LayoutType;
+    Q_ENUM(LayoutType);
+
     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
     QHash<int, QByteArray> roleNames() const override;
@@ -83,13 +158,27 @@ public:
     void removeParticipant(int index);
     void setParticipants(const QString& callId, const QVariantList& participants);
     Q_INVOKABLE void reset();
+    void setConferenceLayout(int layout, const QString& callId)
+    {
+        auto newLayout = static_cast<LayoutType>(layout);
+        if (callId == callId_ && newLayout != layout_) {
+            layout_ = newLayout;
+            Q_EMIT layoutChanged();
+        }
+    }
+    const LayoutType conferenceLayout()
+    {
+        return layout_;
+    }
 
 Q_SIGNALS:
     void updateParticipant(QVariant participantInfos);
+    void layoutChanged();
 
 private:
     LRCInstance* lrcInstance_ {nullptr};
 
     QList<CallParticipant::Item> participants_ {};
     QString callId_;
+    LayoutType layout_;
 };
diff --git a/src/commoncomponents/VideoView.qml b/src/commoncomponents/VideoView.qml
index ecfb5c3d8adfb864e3b4c024882118392a1d8868..7be9099f5df2f9f9e0faf3d6199590ee33b6f689 100644
--- a/src/commoncomponents/VideoView.qml
+++ b/src/commoncomponents/VideoView.qml
@@ -26,6 +26,7 @@ Item {
     property string rendererId
     property alias videoSink: videoOutput.videoSink
     property alias underlayItems: rootUnderlayItem.children
+    property alias overlayItems: rootOverlayItem.children
     property real invAspectRatio: (videoOutput.sourceRect.height
                                    / videoOutput.sourceRect.width) ||
                                   0.5625 // 16:9 default
@@ -79,4 +80,9 @@ Item {
             radius: (1. - opacity) * 100
         }
     }
+
+    Item {
+        id: rootOverlayItem
+        anchors.fill: parent
+    }
 }
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index 4fd22f4264071a674b3b83bd1f61112657d9bfe1..4940a099ead195c15a3990e6b1bee7e96fe5b462 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -71,7 +71,7 @@ Item {
             root.localHandRaised = CallAdapter.isHandRaised()
         }
         root.isRecording = CallAdapter.isRecordingThisCall()
-        root.isModerator = CallAdapter.isCurrentModerator()
+        root.isModerator = CallAdapter.isModerator()
     }
 
     function showOnHoldImage(visible) {
diff --git a/src/mainview/components/OngoingCallPage.qml b/src/mainview/components/OngoingCallPage.qml
index 6e91a5a892b94e939d7b8f30fe4a4f2d818c1e5c..76d6d9c9a894429a0e38ecc651ff37f2b827fa21 100644
--- a/src/mainview/components/OngoingCallPage.qml
+++ b/src/mainview/components/OngoingCallPage.qml
@@ -183,6 +183,10 @@ Rectangle {
                     anchors.centerIn: parent
                     anchors.margins: 3
                     visible: !root.isAudioOnly &&  participantsLayer.count !== 0
+
+                    onCountChanged: {
+                        callOverlay.isConference = participantsLayer.count > 0
+                    }
                 }
 
                 LocalVideo {
@@ -266,7 +270,7 @@ Rectangle {
                     id: callOverlay
 
                     anchors.fill: parent
-                    isConference: participantsLayer.count >= 0
+                    isConference: participantsLayer.count > 0
 
                     function toggleConversation() {
                         if (inCallMessageWebViewStack.visible)
diff --git a/src/mainview/components/ParticipantOverlay.qml b/src/mainview/components/ParticipantOverlay.qml
index 3b6faedd3cf2c46bbfd78597f03d325aa9c459ff..5ecc4188897203ed76fd33456ddcedd6cbeff53f 100644
--- a/src/mainview/components/ParticipantOverlay.qml
+++ b/src/mainview/components/ParticipantOverlay.qml
@@ -1,7 +1,8 @@
 /*
- * Copyright (C) 2020-2022 Savoir-faire Linux Inc.
- * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
- * Author: Albert Babí <albert.babi@savoirfairelinux.com>
+ * Copyright (C) 2020-2022 Savoir-faire Linux
+ * Authors: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *          Albert Babí <albert.babi@savoirfairelinux.com>
+ *          Aline Gondim Santos <aline.gondimsantos@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
@@ -34,24 +35,27 @@ Item {
     // svg path for the participant indicators background shape
     property int shapeWidth: participantFootInfo.width + 8
     property int shapeHeight: 30
-    property int shapeRadius: 6
+    property int shapeRadius: 5
     property string pathShape: "M0,0 h%1 q%2,0 %2,%2 v%3 h-%4 z"
         .arg(shapeWidth - shapeRadius)
         .arg(shapeRadius)
         .arg(shapeHeight - shapeRadius)
         .arg(shapeWidth)
 
-    property string uri: overlayMenu.uri
+    property string uri: ""
     property string bestName: ""
-    property alias sinkId:  mediaDistRender.rendererId
+    property string sinkId: ""
     property bool participantIsActive: false
-    property bool participantIsHost: false
+    property bool participantIsHost: CallAdapter.participantIsHost(uri)
     property bool participantIsModerator: false
-    property bool participantIsMuted: false
+    property bool participantIsMuted: isLocalMuted || participantIsModeratorMuted
     property bool participantIsModeratorMuted: false
     property bool participantHandIsRaised: false
+    property bool videoMuted: true
+    property bool isLocalMuted: true
 
-    property bool meModerator: false
+    property bool meHost: CallAdapter.isCurrentHost()
+    property bool meModerator: CallAdapter.isModerator()
     property bool isMe: false
 
     property string muteAlertMessage: ""
@@ -63,92 +67,12 @@ Item {
         }
     }
 
-    Connections {
-        target: CallParticipantsModel
-
-        function onUpdateParticipant(participantInfos) {
-            if (participantInfos.uri === overlayMenu.uri) {
-                root.sinkId = participantInfos.videoMuted ? "" : participantInfos.sinkId
-                setMenu(participantInfos.uri, participantInfos.bestName, participantInfos.isLocal, participantInfos.active)
-                setAvatar(participantInfos.videoMuted, participantInfos.uri, participantInfos.isLocal)
-            }
-        }
-    }
-
-    function setAvatar(show, uri, isLocal) {
-        if (!show)
-            avatar.active = false
-        else {
-            avatar.mode_ = isLocal ? Avatar.Mode.Account : Avatar.Mode.Contact
-            avatar.imageId_ = isLocal ? LRCInstance.currentAccountId : uri
-            avatar.active = true
-        }
-    }
-
-    function setMenu(newUri, bestName, isLocal, isActive) {
-
-        overlayMenu.uri = newUri
-        root.bestName = bestName
-        isMe = overlayMenu.uri === CurrentAccount.uri
-
-        var isHost = CallAdapter.isCurrentHost()
-        meModerator = CallAdapter.isCurrentModerator()
-        participantIsHost = CallAdapter.participantIsHost(overlayMenu.uri)
-        participantIsModerator = CallAdapter.isModerator(overlayMenu.uri)
-        participantIsActive = isActive
-        participantHandIsRaised = CallAdapter.isHandRaised(overlayMenu.uri)
-        overlayMenu.showSetModerator = isHost && !isLocal && !participantIsModerator
-        overlayMenu.showUnsetModerator = isHost && !isLocal && participantIsModerator
-
-        var muteState = CallAdapter.getMuteState(overlayMenu.uri)
-        overlayMenu.isLocalMuted = muteState === CallAdapter.LOCAL_MUTED
-                || muteState === CallAdapter.BOTH_MUTED
-        participantIsModeratorMuted = muteState === CallAdapter.MODERATOR_MUTED
-                || muteState === CallAdapter.BOTH_MUTED
-
-        participantIsMuted = overlayMenu.isLocalMuted || participantIsModeratorMuted
-
-        overlayMenu.showModeratorMute = meModerator && !participantIsModeratorMuted
-        overlayMenu.showModeratorUnmute = (meModerator || isMe) && participantIsModeratorMuted
-        overlayMenu.showMaximize = meModerator
-        overlayMenu.showMinimize = meModerator && participantIsActive
-        overlayMenu.showHangup = meModerator && !isLocal && !participantIsHost
-    }
-
     TextMetrics {
         id: nameTextMetrics
         text: bestName
         font.pointSize: JamiTheme.participantFontSize
     }
 
-    Loader {
-        id: avatar
-
-        anchors.centerIn: parent
-
-        active: false
-
-        property real size_: Math.min(parent.width / 2, parent.height / 2)
-        height:  size_
-        width:  size_
-        z: 0
-
-        property int mode_
-        property string imageId_
-
-        sourceComponent: Component {
-            Avatar {
-                // round the avatar source size up to some nearest multiple
-                readonly property real step: 96
-                property real size: Math.floor((size_ + step - 1) / step) * step
-                sourceSize: Qt.size(size, size)
-                mode: mode_
-                imageId: size_ ? imageId_ : ""
-                showPresenceIndicator: false
-            }
-        }
-    }
-
     // Timer to decide when ParticipantOverlay fade out
     Timer {
         id: fadeOutTimer
@@ -164,251 +88,273 @@ Item {
 
     VideoView {
         id: mediaDistRender
-        width: parent.width
-        height: width * invAspectRatio
-        anchors.centerIn: parent
+        anchors.fill: parent
         rendererId: root.sinkId
-        visible: !root.videoMuted
 
-        // Update overlays if the internal or visual geometry changes.
-        property real area: width * height
+        underlayItems: Avatar {
+            property real componentSize: Math.min(mediaDistRender.contentRect.width / 2, mediaDistRender.contentRect.height / 2)
+            height:  componentSize
+            width:  componentSize
+            anchors.centerIn: parent
+            // round the avatar source size up to some nearest multiple
+            readonly property real step: 96
+            property real size: Math.floor((componentSize + step - 1) / step) * step
+            sourceSize: Qt.size(size, size)
+            mode: root.isMe ? Avatar.Mode.Account : Avatar.Mode.Contact
+            imageId: root.isMe ? LRCInstance.currentAccountId : root.uri
+            showPresenceIndicator: false
+            visible: root.videoMuted
+        }
 
-        Item {
-            anchors.fill: parent
+        overlayItems: Rectangle {
+            id: overlayRect
 
-            HoverHandler {
-                onPointChanged: {
-                    participantRect.opacity = 1
-                    fadeOutTimer.restart()
-                }
+            width: mediaDistRender.contentRect.width
+            height: mediaDistRender.contentRect.height
+            anchors.centerIn: parent
+            color: "transparent"
 
-                onHoveredChanged: {
-                    if (overlayMenu.hovered) {
+            Item {
+                anchors.fill: parent
+
+                HoverHandler {
+                    onPointChanged: {
                         participantRect.opacity = 1
                         fadeOutTimer.restart()
-                        return
                     }
-                    participantRect.opacity = hovered ? 1 : 0
-                }
-            }
-        }
 
-        layer.enabled: !root.videoMuted
-        layer.effect: OpacityMask {
-            maskSource: Item {
-                width: mediaDistRender.width
-                height: mediaDistRender.height
-                Rectangle {
-                    anchors.centerIn: parent
-                    width: participantRect.width
-                    height: participantRect.height
-                    radius: 10
+                    onHoveredChanged: {
+                        if (overlayMenu.hovered) {
+                            participantRect.opacity = 1
+                            fadeOutTimer.restart()
+                            return
+                        }
+                        participantRect.opacity = hovered ? 1 : 0
+                    }
                 }
             }
-        }
-    }
 
-    // Participant background
-    Rectangle {
-        id: participantRect
-
-        width: mediaDistRender.width
-        height: mediaDistRender.height
-        anchors.centerIn: parent
-        color: "transparent"
-        opacity: 0
-
-        // Participant background and buttons for moderation
-        ParticipantOverlayMenu {
-            id: overlayMenu
-            visible: isMe || meModerator
-            anchors.fill: parent
-
-            onHoveredChanged: {
-                if (hovered) {
-                    participantRect.opacity = 1
-                    fadeOutTimer.restart()
-                } else {
-                    participantRect.opacity = 0
-                }
-            }
-        }
+            Rectangle {
+                id: participantRect
+                anchors.fill: parent
+                color: "transparent"
+                opacity: 0
+
+                // Participant buttons for moderation
+                ParticipantOverlayMenu {
+                    id: overlayMenu
+                    visible: isMe || meModerator
+                    anchors.fill: parent
+
+                    onHoveredChanged: {
+                        if (hovered) {
+                            participantRect.opacity = 1
+                            fadeOutTimer.restart()
+                        } else {
+                            participantRect.opacity = 0
+                        }
+                    }
 
-        // Participant footer with host, moderator and mute indicators
-        // Mute indicator is as follow:
-        // - In another participant, if i am not moderator, the mute state is isLocalMuted || participantIsModeratorMuted
-        // - In another participant, if i am moderator, the mute state is isLocalMuted
-        // - In my video, the mute state is isLocalMuted
-        Rectangle {
-            id: participantIndicators
-            width: participantRect.width
-            height: shapeHeight
-            color: "transparent"
-            anchors.bottom: parent.bottom
-
-            Shape {
-                id: backgroundShape
-                ShapePath {
-                    id: backgroundShapePath
-                    strokeColor: "transparent"
-                    fillColor: JamiTheme.darkGreyColorOpacity
-                    capStyle: ShapePath.RoundCap
-                    PathSvg { path: pathShape }
+                    showSetModerator: root.meHost && !root.isMe && !root.participantIsModerator
+                    showUnsetModerator: root.meHost && !root.isMe && root.participantIsModerator
+                    showModeratorMute: root.meModerator && !root.participantIsModeratorMuted
+                    showModeratorUnmute: (root.meModerator || root.isMe) && root.participantIsModeratorMuted
+                    showMaximize: root.meModerator && !root.participantIsActive
+                    showMinimize: root.meModerator && root.participantIsActive
+                    showHangup: root.meModerator && !root.isMe && !root.participantIsHost
                 }
-            }
-
-            RowLayout {
-                id: participantFootInfo
-                height: parent.height
-                anchors.verticalCenter: parent.verticalCenter
-                Text {
-                    id: bestNameLabel
 
-                    Layout.leftMargin: 8
-                    Layout.preferredWidth: Math.min(nameTextMetrics.boundingRect.width + 8,
-                                                    participantIndicators.width - indicatorsRowLayout.width - 16)
-                    Layout.preferredHeight: shapeHeight
-
-                    text: bestName
-                    elide: Text.ElideRight
-                    color: JamiTheme.whiteColor
-                    font.pointSize: JamiTheme.participantFontSize
-                    horizontalAlignment: Text.AlignLeft
-                    verticalAlignment: Text.AlignVCenter
-                    HoverHandler { id: hoverName }
-                    MaterialToolTip {
-                        visible: hoverName.hovered && (text.length > 0)
-                        text: bestNameLabel.truncated ? bestName : ""
+                // Participant footer with host, moderator and mute indicators
+                // Mute indicator is as follow:
+                // - In another participant, if i am not moderator, the mute state is isLocalMuted || participantIsModeratorMuted
+                // - In another participant, if i am moderator, the mute state is isLocalMuted
+                // - In my video, the mute state is isLocalMuted
+                Rectangle {
+                    id: participantIndicators
+                    width: participantRect.width
+                    height: shapeHeight
+                    color: "transparent"
+                    anchors.bottom: parent.bottom
+
+                    Shape {
+                        id: backgroundShape
+                        ShapePath {
+                            id: backgroundShapePath
+                            strokeColor: "transparent"
+                            fillColor: JamiTheme.darkGreyColorOpacity
+                            capStyle: ShapePath.RoundCap
+                            PathSvg { path: pathShape }
+                        }
                     }
-                }
-
-                RowLayout {
-                    id: indicatorsRowLayout
-                    height: parent.height
-                    Layout.alignment: Qt.AlignVCenter
-
-                    ResponsiveImage {
-                        id: isHostIndicator
 
-                        Layout.alignment: Qt.AlignVCenter
-                        Layout.leftMargin: 6
-
-                        containerHeight: 12
-                        containerWidth: 12
-
-                        visible: participantIsHost
+                    RowLayout {
+                        id: participantFootInfo
+                        height: parent.height
+                        anchors.verticalCenter: parent.verticalCenter
+                        Text {
+                            id: bestNameLabel
+
+                            Layout.leftMargin: 8
+                            Layout.preferredWidth: Math.min(nameTextMetrics.boundingRect.width + 8,
+                                                            participantIndicators.width - indicatorsRowLayout.width - 16)
+                            Layout.preferredHeight: shapeHeight
+
+                            text: bestName
+                            elide: Text.ElideRight
+                            color: JamiTheme.whiteColor
+                            font.pointSize: JamiTheme.participantFontSize
+                            horizontalAlignment: Text.AlignLeft
+                            verticalAlignment: Text.AlignVCenter
+                            HoverHandler { id: hoverName }
+                            MaterialToolTip {
+                                visible: hoverName.hovered && (text.length > 0)
+                                text: bestNameLabel.truncated ? bestName : ""
+                            }
+                        }
 
-                        source: JamiResources.star_outline_24dp_svg
-                        color: JamiTheme.whiteColor
+                        RowLayout {
+                            id: indicatorsRowLayout
+                            height: parent.height
+                            Layout.alignment: Qt.AlignVCenter
 
-                        HoverHandler { id: hoverHost }
-                        MaterialToolTip {
-                            visible: hoverHost.hovered
-                            text: JamiStrings.host
-                        }
-                    }
+                            ResponsiveImage {
+                                id: isHostIndicator
 
-                    ResponsiveImage {
-                        id: isModeratorIndicator
+                                Layout.alignment: Qt.AlignVCenter
+                                Layout.leftMargin: 6
 
-                        Layout.alignment: Qt.AlignVCenter
-                        Layout.leftMargin: 6
+                                containerHeight: 12
+                                containerWidth: 12
 
-                        containerHeight: 12
-                        containerWidth: 12
+                                visible: root.participantIsHost
 
-                        visible: !participantIsHost && participantIsModerator
+                                source: JamiResources.star_outline_24dp_svg
+                                color: JamiTheme.whiteColor
 
-                        source: JamiResources.moderator_svg
-                        color: JamiTheme.whiteColor
+                                HoverHandler { id: hoverHost }
+                                MaterialToolTip {
+                                    visible: hoverHost.hovered
+                                    text: JamiStrings.host
+                                }
+                            }
 
-                        HoverHandler { id: hoverModerator }
-                        MaterialToolTip {
-                            visible: hoverModerator.hovered
-                            text: JamiStrings.moderator
-                        }
-                    }
+                            ResponsiveImage {
+                                id: isModeratorIndicator
 
-                    ResponsiveImage {
-                        id: isMutedIndicator
+                                Layout.alignment: Qt.AlignVCenter
+                                Layout.leftMargin: 6
 
-                        Layout.alignment: Qt.AlignVCenter
-                        Layout.leftMargin: 6
+                                containerHeight: 12
+                                containerWidth: 12
 
-                        containerHeight: 12
-                        containerWidth: 12
+                                visible: !root.participantIsHost && root.participantIsModerator
 
-                        visible: (!isMe && !meModerator) ? participantIsMuted : overlayMenu.isLocalMuted
+                                source: JamiResources.moderator_svg
+                                color: JamiTheme.whiteColor
 
-                        source: JamiResources.micro_off_black_24dp_svg
-                        color: "red"
+                                HoverHandler { id: hoverModerator }
+                                MaterialToolTip {
+                                    visible: hoverModerator.hovered
+                                    text: JamiStrings.moderator
+                                }
+                            }
 
-                        HoverHandler { id: hoverMicrophone }
-                        MaterialToolTip {
-                            visible: hoverMicrophone.hovered
-                            text: {
-                                if (!isMe && !meModerator && participantIsModeratorMuted && overlayMenu.isLocalMuted)
-                                    return JamiStrings.bothMuted
-                                if (overlayMenu.isLocalMuted)
-                                    return JamiStrings.localMuted
-                                if (!isMe && !meModerator && participantIsModeratorMuted)
-                                    return JamiStrings.moderatorMuted
-                                return JamiStrings.notMuted
+                            ResponsiveImage {
+                                id: isMutedIndicator
+
+                                Layout.alignment: Qt.AlignVCenter
+                                Layout.leftMargin: 6
+
+                                containerHeight: 12
+                                containerWidth: 12
+
+                                visible: (!root.isMe && !root.meModerator) ? root.participantIsMuted : root.isLocalMuted
+
+                                source: JamiResources.micro_off_black_24dp_svg
+                                color: "red"
+
+                                HoverHandler { id: hoverMicrophone }
+                                MaterialToolTip {
+                                    visible: hoverMicrophone.hovered
+                                    text: {
+                                        if (!root.isMe && !root.meModerator && root.participantIsModeratorMuted && root.isLocalMuted)
+                                            return JamiStrings.bothMuted
+                                        if (root.isLocalMuted)
+                                            return JamiStrings.localMuted
+                                        if (!root.isMe && !root.meModerator && root.participantIsModeratorMuted)
+                                            return JamiStrings.moderatorMuted
+                                        return JamiStrings.notMuted
+                                    }
+                                }
                             }
                         }
                     }
                 }
+
+                Behavior on opacity { NumberAnimation { duration: JamiTheme.shortFadeDuration }}
             }
-        }
 
-        Behavior on opacity { NumberAnimation { duration: JamiTheme.shortFadeDuration }}
-    }
+            PushButton {
+                id: isRaiseHandIndicator
+                source: JamiResources.hand_black_24dp_svg
+                imageColor: JamiTheme.whiteColor
+                preferredSize: shapeHeight
+                visible: root.participantHandIsRaised
+                anchors.right: participantRect.right
+                anchors.top: participantRect.top
+                checkable: root.meModerator
+                pressedColor: JamiTheme.raiseHandColor
+                hoveredColor: JamiTheme.raiseHandColor
+                normalColor: JamiTheme.raiseHandColor
+                z: participantRect.z + 1
+                toolTipText: root.meModerator ? JamiStrings.lowerHand : ""
+                onClicked: CallAdapter.setHandRaised(uri, false)
+                radius: 5
+            }
 
-    PushButton {
-        id: isRaiseHandIndicator
-        source: JamiResources.hand_black_24dp_svg
-        imageColor: JamiTheme.whiteColor
-        preferredSize: shapeHeight
-        visible: root.participantHandIsRaised
-        anchors.right: participantRect.right
-        anchors.top: participantRect.top
-        checkable: root.meModerator
-        pressedColor: JamiTheme.raiseHandColor
-        hoveredColor: JamiTheme.raiseHandColor
-        normalColor: JamiTheme.raiseHandColor
-        z: participantRect.z + 1
-        toolTipText: root.meModerator ? JamiStrings.lowerHand : ""
-        onClicked: CallAdapter.setHandRaised(uri, false)
-        radius: 5
-    }
+            Rectangle {
+                id: alertMessage
 
-    Rectangle {
-        id: alertMessage
+                anchors.centerIn: parent
+                width: alertMessageTxt.width + 16
+                height: alertMessageTxt.contentHeight + 16
+                radius: 5
+                visible: root.muteAlertActive
+                color: JamiTheme.darkGreyColorOpacity
 
-        anchors.centerIn: parent
-        width: alertMessageTxt.width + 16
-        height: alertMessageTxt.contentHeight + 16
-        radius: 5
-        visible: root.muteAlertActive
-        color: JamiTheme.darkGreyColorOpacity
+                Text {
+                    id: alertMessageTxt
+                    text: root.muteAlertMessage
+                    anchors.centerIn: parent
+                    width: Math.min(participantRect.width, contentWidth)
+                    color: JamiTheme.whiteColor
+                    font.pointSize: JamiTheme.textFontSize
+                    wrapMode: Text.Wrap
+                    horizontalAlignment: Text.AlignHCenter
+                    verticalAlignment: Text.AlignVCenter
+                }
 
-        Text {
-            id: alertMessageTxt
-            text: root.muteAlertMessage
-            anchors.centerIn: parent
-            width: Math.min(participantRect.width, contentWidth)
-            color: JamiTheme.whiteColor
-            font.pointSize: JamiTheme.textFontSize
-            wrapMode: Text.Wrap
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
+                Timer {
+                    id: alertTimer
+                    interval: JamiTheme.overlayFadeDelay
+                    onTriggered: {
+                        root.muteAlertActive = false
+                    }
+                }
+            }
         }
 
-        Timer {
-            id: alertTimer
-            interval: JamiTheme.overlayFadeDelay
-            onTriggered: {
-                root.muteAlertActive = false
+        layer.enabled: !root.videoMuted
+        layer.effect: OpacityMask {
+            maskSource: Item {
+                width: mediaDistRender.width
+                height: mediaDistRender.height
+                Rectangle {
+                    anchors.centerIn: parent
+                    width: participantRect.width
+                    height: participantRect.height
+                    radius: 10
+                }
             }
         }
     }
diff --git a/src/mainview/components/ParticipantOverlayMenu.qml b/src/mainview/components/ParticipantOverlayMenu.qml
index 5fd6f5a7a2fc15f2aeb5d0dbfdfb607c8f4a5f83..114257c8baf9329e37e27f1dd261564a13f5cccc 100644
--- a/src/mainview/components/ParticipantOverlayMenu.qml
+++ b/src/mainview/components/ParticipantOverlayMenu.qml
@@ -30,8 +30,6 @@ import "../../commoncomponents"
 Item {
     id: root
 
-    property string uri: ""
-    property bool isLocalMuted: true
     property bool showSetModerator: false
     property bool showUnsetModerator: false
     property bool showModeratorMute: false
@@ -41,12 +39,12 @@ Item {
     property bool showHangup: false
 
     property int shapeHeight: 30
-    property int shapeRadius: 8
+    property int shapeRadius: 10
 
     property bool isBarLayout: root.width > 220
     property int isSmall: !isBarLayout && (root.height < 100 || root.width < 160)
 
-    property int buttonPreferredSize: 24
+    property int buttonPreferredSize: 20
     property int iconButtonPreferredSize: 16
 
     property alias hovered: hover.hovered
diff --git a/src/mainview/components/ParticipantsLayer.qml b/src/mainview/components/ParticipantsLayer.qml
index 1c24868492e702d22630678c8854ba2c1ccb37cc..f9fb361249b4b4e5d35b20238da1e7253f85c193 100644
--- a/src/mainview/components/ParticipantsLayer.qml
+++ b/src/mainview/components/ParticipantsLayer.qml
@@ -1,6 +1,7 @@
 /*
- * Copyright (C) 2020-2022 Savoir-faire Linux Inc.
- * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ * Copyright (C) 2020-2022 by Savoir-faire Linux
+ * Authors: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *          Aline Gondim Santos <aline.gondimsantos@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
@@ -19,23 +20,17 @@
 import QtQuick
 
 import QtQuick.Layouts 1.15
+import QtQuick.Controls 2.15
+
 import net.jami.Adapters 1.1
 import net.jami.Models 1.1
+import net.jami.Constants 1.1
 
 Item {
     id: root
 
-    property alias count: participantincall.count
-
-    Connections {
-        target: CallAdapter
-
-        function onUpdateParticipantsLayout() {
-            participantsFlow.columns = Math.max(1, Math.ceil(Math.sqrt(participantincall.count)))
-            participantsFlow.rows = Math.max(1, Math.ceil(participantincall.count/participantsFlow.columns))
-        }
-    }
-
+    property int count: commonParticipants.count + activeParticipants.count
+    property bool inLine: CallParticipantsModel.conferenceLayout === CallParticipantsModel.ONE_WITH_SMALL
 
     Component {
         id: callVideoMedia
@@ -45,45 +40,221 @@ Item {
             anchors.centerIn: parent
 
             sinkId: sinkId_
-
-            Component.onCompleted: {
-                setMenu(uri_, bestName_, isLocal_, active_)
-                setAvatar(videoMuted_, uri_, isLocal_)
-                VideoDevices.startDevice(sinkId)
-            }
+            uri: uri_
+            isMe: isLocal_
+            participantIsModerator: isModerator_
+            bestName: bestName_
+            videoMuted: videoMuted_
+            participantIsActive: active_
+            isLocalMuted: audioLocalMuted_
+            participantIsModeratorMuted: audioModeratorMuted_
+            participantHandIsRaised: isHandRaised_
         }
     }
 
-    Flow {
-        id: participantsFlow
+    SplitView {
         anchors.fill: parent
-        anchors.centerIn: parent
-        spacing: 8
-        property int columns: Math.max(1, Math.ceil(Math.sqrt(participantincall.count)))
-        property int rows: Math.max(1, Math.ceil(participantincall.count/columns))
-        property int columnsSpacing: 5 * (columns - 1)
-        property int rowsSpacing: 5 * (rows - 1)
-
-        Repeater {
-            id: participantincall
-            anchors.fill: parent
-            anchors.centerIn: parent
 
-            model: CallParticipantsModel
-            delegate: Loader {
-                sourceComponent: callVideoMedia
-                width: Math.ceil(participantsFlow.width / participantsFlow.columns) - participantsFlow.columnsSpacing
-                height: Math.ceil(participantsFlow.height / participantsFlow.rows) - participantsFlow.rowsSpacing
-
-                property string uri_: Uri
-                property string bestName_: BestName
-                property string avatar_: Avatar ? Avatar : ""
-                property string sinkId_: SinkId ? SinkId : ""
-                property bool isLocal_: IsLocal
-                property bool active_: Active
-                property bool videoMuted_: VideoMuted
-                property bool isContact_: IsContact
-                property bool isHandRaised_: HandRaised
+        orientation: Qt.Vertical
+        handle: Rectangle {
+            implicitWidth: root.width
+            implicitHeight: 11
+            color: "transparent"
+            Rectangle {
+                anchors.centerIn: parent
+                height: 1
+                width: parent.implicitWidth - 40
+                color: JamiTheme.darkGreyColor
+            }
+
+            Rectangle {
+                width: 45
+                anchors.centerIn: parent
+                height: 1
+                color: "black"
+            }
+
+            ColumnLayout {
+                anchors.centerIn: parent
+                height: 11
+                width: 45
+                Rectangle {
+                    Layout.fillWidth: true
+                    Layout.leftMargin: 10
+                    Layout.rightMargin: 10
+                    height: 2
+                    color: JamiTheme.darkGreyColor
+                }
+                Rectangle {
+                    Layout.fillWidth: true
+                    Layout.leftMargin: 10
+                    Layout.rightMargin: 10
+                    height: 2
+                    color: JamiTheme.darkGreyColor
+                }
+            }
+        }
+
+        Rectangle {
+            id: genericParticipantsRect
+
+            SplitView.preferredHeight: (parent.height / 4)
+            SplitView.minimumHeight: parent.height / 4
+            SplitView.maximumHeight: inLine? parent.height / 4 : parent.height
+
+            visible: inLine || CallParticipantsModel.conferenceLayout === CallParticipantsModel.GRID
+            color: "transparent"
+
+            property int lowLimit: 0
+            property int topLimit: commonParticipants.count
+            property int currentPos: 0
+            property int showable: {
+                var placeableElements = inLine ? Math.floor((width * 0.95)/commonParticipantsFlow.componentWidth) : commonParticipants.count
+                if (commonParticipants.count - placeableElements < currentPos)
+                    currentPos = Math.max(commonParticipants.count - placeableElements, 0)
+                return placeableElements
+            }
+
+            RowLayout {
+                anchors.fill: parent
+                anchors.centerIn: parent
+                z: 1
+
+                RoundButton {
+                    Layout.alignment: Qt.AlignVCenter
+                    width : 30
+                    height : 30
+                    radius: 10
+                    text: "<"
+                    visible: genericParticipantsRect.currentPos > 0
+                    onClicked: {
+                        if (genericParticipantsRect.currentPos > 0)
+                            genericParticipantsRect.currentPos--
+                    }
+                    background: Rectangle {
+                        anchors.fill: parent
+                        color: JamiTheme.lightGrey_
+                        radius: JamiTheme.primaryRadius
+                    }
+                }
+                Item {
+                    Layout.fillHeight: true
+                    Layout.fillWidth: true
+                }
+
+                RoundButton {
+                    Layout.alignment: Qt.AlignVCenter
+                    width : 30
+                    height : 30
+                    radius: 10
+                    text: ">"
+                    visible: genericParticipantsRect.topLimit - genericParticipantsRect.showable > genericParticipantsRect.currentPos
+                    onClicked: {
+                        if (genericParticipantsRect.topLimit - genericParticipantsRect.showable > genericParticipantsRect.currentPos)
+                            genericParticipantsRect.currentPos++
+                    }
+                    background: Rectangle {
+                        anchors.fill: parent
+                        color: JamiTheme.lightGrey_
+                        radius: JamiTheme.primaryRadius
+                    }
+                }
+            }
+
+            Rectangle {
+                z:0
+                anchors.centerIn: parent
+                property int elements: inLine ? Math.min(genericParticipantsRect.showable, commonParticipants.count) : commonParticipantsFlow.columns
+                width: commonParticipantsFlow.componentWidth * elements + elements - 1
+                implicitHeight: parent.height + commonParticipantsFlow.rows - 1
+                color: "transparent"
+
+                // GENERIC
+                Flow {
+                    id: commonParticipantsFlow
+                    anchors.centerIn: parent
+                    anchors.fill: parent
+
+                    spacing: 1
+                    property int columns: inLine ? commonParticipants.count : Math.max(1, Math.ceil(Math.sqrt(commonParticipants.count)))
+                    property int rows: Math.max(1, Math.ceil(commonParticipants.count/columns))
+                    property int componentWidth: inLine ? height : Math.floor(genericParticipantsRect.width / commonParticipantsFlow.columns) - 1
+
+                    Repeater {
+                        id: commonParticipants
+
+                        model: GenericParticipantsFilterModel
+                        delegate: Loader {
+                            sourceComponent: callVideoMedia
+                            visible: inLine ? index >= genericParticipantsRect.currentPos && index < genericParticipantsRect.currentPos + genericParticipantsRect.showable : true
+                            width: {
+                                var lastLine = commonParticipants.count % commonParticipantsFlow.columns
+                                var horComponents = ((commonParticipants.count - index) > lastLine || index < 0) ? commonParticipantsFlow.columns : lastLine
+                                if (horComponents === lastLine)
+                                    return Math.floor(commonParticipantsFlow.width / horComponents) - 1
+                                else
+                                    return commonParticipantsFlow.componentWidth
+                            }
+                            height: inLine ? commonParticipantsFlow.componentWidth : Math.floor(genericParticipantsRect.height / commonParticipantsFlow.rows) - 1
+
+                            property string uri_: Uri
+                            property string bestName_: BestName
+                            property string avatar_: Avatar ? Avatar : ""
+                            property string sinkId_: SinkId ? SinkId : ""
+                            property bool isLocal_: IsLocal
+                            property bool active_: Active
+                            property bool videoMuted_: VideoMuted
+                            property bool isContact_: IsContact
+                            property bool isModerator_: IsModerator
+                            property bool audioLocalMuted_: AudioLocalMuted
+                            property bool audioModeratorMuted_: AudioModeratorMuted
+                            property bool isHandRaised_: HandRaised
+                        }
+                    }
+                }
+            }
+        }
+
+        // ACTIVE
+        Flow {
+            id: activeParticipantsFlow
+
+            SplitView.minimumHeight: parent.height / 4
+            SplitView.maximumHeight: parent.height
+            SplitView.fillHeight: true
+
+            spacing: 8
+            property int columns: Math.max(1, Math.ceil(Math.sqrt(activeParticipants.count)))
+            property int rows: Math.max(1, Math.ceil(activeParticipants.count/columns))
+            property int columnsSpacing: 5 * (columns - 1)
+            property int rowsSpacing: 5 * (rows - 1)
+
+            visible: inLine || CallParticipantsModel.conferenceLayout === CallParticipantsModel.ONE
+
+            Repeater {
+                id: activeParticipants
+                anchors.fill: parent
+                anchors.centerIn: parent
+
+                model: ActiveParticipantsFilterModel
+                delegate: Loader {
+                    sourceComponent: callVideoMedia
+                    width: Math.ceil(activeParticipantsFlow.width / activeParticipantsFlow.columns) - activeParticipantsFlow.columnsSpacing
+                    height: Math.ceil(activeParticipantsFlow.height / activeParticipantsFlow.rows) - activeParticipantsFlow.rowsSpacing
+
+                    property string uri_: Uri
+                    property string bestName_: BestName
+                    property string avatar_: Avatar ? Avatar : ""
+                    property string sinkId_: SinkId ? SinkId : ""
+                    property bool isLocal_: IsLocal
+                    property bool active_: Active
+                    property bool videoMuted_: VideoMuted
+                    property bool isContact_: IsContact
+                    property bool isModerator_: IsModerator
+                    property bool audioLocalMuted_: AudioLocalMuted
+                    property bool audioModeratorMuted_: AudioModeratorMuted
+                    property bool isHandRaised_: HandRaised
+                }
             }
         }
     }