diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 807bfb85be4bedb1424cb81b05d943b94e08cdb9..ec7574c0a71260d3d9c0c04d3fd2e02e0714b559 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -248,6 +248,26 @@ CallAdapter::onCallStatusChanged(const QString& callId, int code)
     }
 }
 
+void
+CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
+{
+    auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
+    auto& callModel = accInfo.callModel;
+
+    try {
+        const auto call = callModel->getCall(callId);
+        /*
+         * Change status label text.
+         */
+        const auto& convInfo = lrcInstance_->getConversationFromCallId(callId);
+        if (!convInfo.uid.isEmpty()) {
+            Q_EMIT callInfosChanged(call.isAudioOnly, accountId, convInfo.uid);
+            updateCallOverlay(convInfo);
+        }
+    } catch (...) {
+    }
+}
+
 void
 CallAdapter::onRemoteRecordingChanged(const QString& callId,
                                       const QSet<QString>& peerRec,
@@ -604,6 +624,11 @@ CallAdapter::connectCallModel(const QString& accountId)
             this,
             &CallAdapter::onCallAddedToConference,
             Qt::UniqueConnection);
+
+    connect(accInfo.callModel.get(),
+            &NewCallModel::callInfosChanged,
+            this,
+            QOverload<const QString&, const QString&>::of(&CallAdapter::onCallInfosChanged));
 }
 
 void
@@ -979,7 +1004,7 @@ CallAdapter::muteThisCallToggle()
     }
     auto* callModel = lrcInstance_->getCurrentCallModel();
     if (callModel->hasCall(callId)) {
-        callModel->toggleMedia(callId, lrc::api::NewCallModel::Media::AUDIO);
+        callModel->requestMediaChange(callId, "audio_0");
     }
 }
 
@@ -1005,7 +1030,9 @@ CallAdapter::videoPauseThisCallToggle()
     }
     auto* callModel = lrcInstance_->getCurrentCallModel();
     if (callModel->hasCall(callId)) {
-        callModel->toggleMedia(callId, lrc::api::NewCallModel::Media::VIDEO);
+        callModel->requestMediaChange(callId, "video_0");
+        // media label should come from qml
+        // also thi function can me emrged with "muteThisCallToggle"
     }
     Q_EMIT previewVisibilityNeedToChange(shouldShowPreview(false));
 }
diff --git a/src/calladapter.h b/src/calladapter.h
index b880f60b5d83364f0740ef261708a86dbf665916..ef126a4d2ba12e8968252c8ba5cab5047ebbb951 100644
--- a/src/calladapter.h
+++ b/src/calladapter.h
@@ -84,6 +84,7 @@ public:
 
 Q_SIGNALS:
     void callStatusChanged(int index, const QString& accountId, const QString& convUid);
+    void callInfosChanged(const QVariant& infos, const QString& accountId, const QString& convUid);
     void updateParticipantsInfos(const QVariantList& infos,
                                  const QString& accountId,
                                  const QString& callId);
@@ -109,6 +110,7 @@ public Q_SLOTS:
     void onShowCallView(const QString& accountId, const QString& convUid);
     void onAccountChanged();
     void onCallStatusChanged(const QString& accountId, const QString& callId);
+    void onCallInfosChanged(const QString& accountId, const QString& callId);
     void onParticipantsChanged(const QString& confId);
     void onCallStatusChanged(const QString& callId, int code);
     void onRemoteRecordingChanged(const QString& callId, const QSet<QString>& peerRec, bool state);
diff --git a/src/mainview/components/CallActionBar.qml b/src/mainview/components/CallActionBar.qml
index ccfa1022ce2dfd3b681dd1da8f8ee53b28d77db2..98809ddf3bf6dbb4522714cd9f540c615d4cfabb 100644
--- a/src/mainview/components/CallActionBar.qml
+++ b/src/mainview/components/CallActionBar.qml
@@ -303,6 +303,7 @@ Control {
 
     Connections {
         target: callOverlay
+
         function onIsAudioOnlyChanged() { reset() }
         function onIsSIPChanged() { reset() }
         function onIsModeratorChanged() { reset() }
@@ -317,8 +318,7 @@ Control {
         // centered controls
         CallOverlayModel.addPrimaryControl(muteAudioAction)
         CallOverlayModel.addPrimaryControl(hangupAction)
-        if (!isAudioOnly)
-            CallOverlayModel.addPrimaryControl(muteVideoAction)
+        CallOverlayModel.addPrimaryControl(muteVideoAction)
 
         // overflow controls
         CallOverlayModel.addSecondaryControl(audioOutputAction)
@@ -337,7 +337,7 @@ Control {
         overflowItemCount = CallOverlayModel.secondaryModel().rowCount()
 
         muteAudioAction.checked = isAudioMuted
-        muteVideoAction.checked = isVideoMuted
+        muteVideoAction.checked = isAudioOnly ? true : isVideoMuted
     }
 
     Item {
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index 0ea72fd45f85cfee3b315d56e2cb27cca75531db..796b8afece741af300b37cd54f726bdd6bad01cc 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -56,8 +56,7 @@ Item {
 
     ParticipantsLayer {
         id: __participantsLayer
-        isAudioOnly: root.isAudioOnly
-        isVideoMuted: root.isVideoMuted
+        visible: !root.isAudioOnly
         anchors.fill: parent
     }
 
diff --git a/src/mainview/components/CallStackView.qml b/src/mainview/components/CallStackView.qml
index 5a03ffe0fce11d6513025a9dda8a088029650e23..3e83cdc3f4ddfd29074aacd593d15a035bffe452 100644
--- a/src/mainview/components/CallStackView.qml
+++ b/src/mainview/components/CallStackView.qml
@@ -147,6 +147,13 @@ Rectangle {
     Connections {
         target: CallAdapter
 
+        function onCallInfosChanged(audioOnly, accountId, convUid) {
+            if (callStackMainView.currentItem.stackNumber === CallStackView.OngoingPageStack
+                    && responsibleConvUid === convUid && responsibleAccountId === accountId) {
+                ongoingCallPage.isAudioOnly = audioOnly
+            }
+        }
+
         function onCallStatusChanged(status, accountId, convUid) {
             if (callStackMainView.currentItem.stackNumber === CallStackView.InitialPageStack
                     && responsibleConvUid === convUid && responsibleAccountId === accountId) {
diff --git a/src/mainview/components/OngoingCallPage.qml b/src/mainview/components/OngoingCallPage.qml
index 5f87dbc115fb84849e692e0673fcb9039f5645eb..e037c9b2aa528bd0646f43eb2a24aa3b91ee3635 100644
--- a/src/mainview/components/OngoingCallPage.qml
+++ b/src/mainview/components/OngoingCallPage.qml
@@ -202,7 +202,7 @@ Rectangle {
                     id: previewRenderer
 
                     lrcInstance: LRCInstance
-                    visible: !root.isAudioOnly
+                    visible: !callOverlay.isAudioOnly && !callOverlay.isConferenceCall && !callOverlay.isVideoMuted && !callOverlay.isPaused
 
                     Connections {
                         target: CallAdapter
@@ -313,6 +313,7 @@ Rectangle {
                                                  isRecording, isSIP, isConferenceCall, isGrid,
                                                  bestName) {
                             callOverlay.showOnHoldImage(isPaused)
+                            root.isAudioOnly = isAudioOnly
                             audioCallPageRectCentralRect.visible = !isPaused && root.isAudioOnly
                             callOverlay.updateUI(isPaused, isAudioOnly,
                                                  isAudioMuted, isVideoMuted,
diff --git a/src/mainview/components/ParticipantsLayer.qml b/src/mainview/components/ParticipantsLayer.qml
index 56d1553ab623a451b9f443348fd3dbec7491fa7c..a147611a25718e1ee01496b97fbb608d2f5df612 100644
--- a/src/mainview/components/ParticipantsLayer.qml
+++ b/src/mainview/components/ParticipantsLayer.qml
@@ -22,8 +22,6 @@ import QtQml 2.14
 Item {
     id: root
 
-    property bool isAudioOnly
-    property bool isVideoMuted
     property var participantOverlays: []
     property var participantComponent: Qt.createComponent("ParticipantOverlay.qml")
 
@@ -37,8 +35,6 @@ Item {
     }
 
     function update(infos) {
-        if (isAudioOnly)
-            return;
         // TODO: in the future the conference layout should be entirely managed by the client
         // Hack: truncate and ceil participant's overlay position and size to correct
         // when they are not exacts
@@ -95,7 +91,7 @@ Item {
         participantOverlays = participantOverlays.filter(part => !deletedUris.includes(part.uri))
 
         if (infos.length === 0) { // Return to normal call
-            previewRenderer.visible = !isVideoMuted
+            previewRenderer.visible = !isAudioOnly && !isVideoMuted && !isConferenceCall && !isPaused
             for (var part in participantOverlays) {
                 if (participantOverlays[part]) {
                     participantOverlays[part].destroy()