From 1ed5bb1e1f2ff740d0d5d9f4ff0f302e1278bdd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Fri, 24 Mar 2023 11:47:25 -0400
Subject: [PATCH] participantsmodel: move to current call

Not useful in calladapter as we need to check if it's for the current
call. Also, fix some race-confitions where the callparticipantsmodel
was empty (in swarm-call with only the host in general)

https://git.jami.net/savoirfairelinux/jami-client-qt/-/issues/639

Change-Id: I69df1aa9f7d2d5b198c0fdc01e88e36f9c2c0bd7
---
 src/app/calladapter.cpp     | 233 +++---------------------------------
 src/app/calladapter.h       |  11 +-
 src/app/currentcall.cpp     | 115 +++++++++++++++++-
 src/app/currentcall.h       |   7 ++
 src/libclient/callmodel.cpp |  29 ++---
 5 files changed, 155 insertions(+), 240 deletions(-)

diff --git a/src/app/calladapter.cpp b/src/app/calladapter.cpp
index 5d45ce8fe..07bf243df 100644
--- a/src/app/calladapter.cpp
+++ b/src/app/calladapter.cpp
@@ -32,8 +32,8 @@
 #include <QTimer>
 #include <QJsonObject>
 
+#include <api/callmodel.h>
 #include <api/callparticipantsmodel.h>
-#include <api/devicemodel.h>
 
 #include <media_const.h>
 
@@ -47,9 +47,6 @@ CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject*
     timer = new QTimer(this);
     connect(timer, &QTimer::timeout, this, &CallAdapter::updateAdvancedInformation);
 
-    participantsModel_.reset(new CallParticipantsModel(lrcInstance_, this));
-    QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, participantsModel_.get(), "CallParticipantsModel");
-
     overlayModel_.reset(new CallOverlayModel(lrcInstance_, this));
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, overlayModel_.get(), "CallOverlayModel");
 
@@ -164,69 +161,6 @@ CallAdapter::onCallStatusChanged(const QString& accountId, const QString& callId
 #endif
 }
 
-void
-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) {
-            qDebug() << "trying to update not current conf";
-            return;
-        }
-        auto infos = getConferencesInfos();
-        if (index < infos.size())
-            participantsModel_->addParticipant(index, infos[index]);
-    } catch (...) {
-    }
-}
-
-void
-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) {
-            qDebug() << "trying to update not current conf";
-            return;
-        }
-        participantsModel_->removeParticipant(index);
-    } catch (...) {
-    }
-}
-
-void
-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) {
-            qDebug() << "trying to update not current conf";
-            return;
-        }
-        auto infos = getConferencesInfos();
-        if (index < infos.size())
-            participantsModel_->updateParticipant(index, infos[index]);
-    } catch (...) {
-    }
-}
-
 void
 CallAdapter::onCallStarted(const QString& callId)
 {
@@ -336,30 +270,6 @@ 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()) {
-            if (!convInfo.confId.isEmpty() && callId != convInfo.confId) {
-                // In this case the conv has a confId, ignore subcalls changes.
-                return;
-            }
-            Q_EMIT callInfosChanged(call.isAudioOnly, accountId, convInfo.uid);
-            participantsModel_->setConferenceLayout(static_cast<int>(call.layout), callId);
-        }
-    } catch (...) {
-    }
-}
-
 void
 CallAdapter::onCallAddedToConference(const QString& callId, const QString& confId)
 {
@@ -525,73 +435,6 @@ CallAdapter::updateCall(const QString& convUid, const QString& accountId, bool f
             }
         }
     }
-
-    participantsModel_->setParticipants(call->id, getConferencesInfos());
-    participantsModel_->setConferenceLayout(static_cast<int>(call->layout), call->id);
-}
-
-void
-CallAdapter::fillParticipantData(QJsonObject& participant) const
-{
-    // TODO: getCurrentDeviceId should be part of CurrentAccount, and Current<thing>
-    //       should be read accessible through LRCInstance ??
-    auto getCurrentDeviceId = [](const account::Info& accInfo) -> QString {
-        const auto& deviceList = accInfo.deviceModel->getAllDevices();
-        auto devIt = std::find_if(std::cbegin(deviceList),
-                                  std::cend(deviceList),
-                                  [](const Device& dev) { return dev.isCurrent; });
-        return devIt != deviceList.cend() ? devIt->id : QString();
-    };
-
-    auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
-    using namespace lrc::api::ParticipantsInfosStrings;
-
-    // If both the URI and the device Id match, we set the "is local" flag
-    // used to filter out the participant.
-    // TODO:
-    //  - This filter should always be applied, and any local streams should render
-    //    using local sinks. Local non-preview participants should have proxy participant
-    //    items replaced into this model using their local sink Ids.
-    //  - The app setting should remain and be used to control whether or not the preview
-    //    sink partipcant is rendered.
-    auto uri = participant[URI].toString();
-    participant[ISLOCAL] = false;
-    if (uri == accInfo.profileInfo.uri && participant[DEVICE] == getCurrentDeviceId(accInfo)) {
-        participant[BESTNAME] = tr("Me");
-        participant[ISLOCAL] = true;
-    } else {
-        try {
-            participant[BESTNAME] = accInfo.contactModel->bestNameForContact(uri);
-        } catch (...) {
-        }
-    }
-}
-
-QVariantList
-CallAdapter::getConferencesInfos() const
-{
-    QVariantList map;
-    const auto& convInfo = lrcInstance_->getConversationFromConvUid(
-        lrcInstance_->get_selectedConvUid());
-    if (convInfo.uid.isEmpty())
-        return map;
-    auto callId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
-    if (!callId.isEmpty()) {
-        try {
-            auto& participantsModel = lrcInstance_->accountModel()
-                                          .getAccountInfo(accountId_)
-                                          .callModel.get()
-                                          ->getParticipantsInfos(callId);
-            for (int index = 0; index < participantsModel.getParticipants().size(); index++) {
-                auto participant = participantsModel.toQJsonObject(index);
-                fillParticipantData(participant);
-                map.push_back(QVariant(participant));
-            }
-            return map;
-        } catch (...) {
-        }
-    }
-    return map;
 }
 
 void
@@ -629,25 +472,6 @@ void
 CallAdapter::connectCallModel(const QString& accountId)
 {
     auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
-
-    connect(accInfo.callModel.get(),
-            &CallModel::participantAdded,
-            this,
-            &CallAdapter::onParticipantAdded,
-            Qt::UniqueConnection);
-
-    connect(accInfo.callModel.get(),
-            &CallModel::participantRemoved,
-            this,
-            &CallAdapter::onParticipantRemoved,
-            Qt::UniqueConnection);
-
-    connect(accInfo.callModel.get(),
-            &CallModel::participantUpdated,
-            this,
-            &CallAdapter::onParticipantUpdated,
-            Qt::UniqueConnection);
-
     connect(accInfo.callModel.get(),
             &CallModel::callStarted,
             this,
@@ -671,11 +495,6 @@ CallAdapter::connectCallModel(const QString& accountId)
             this,
             &CallAdapter::onCallAddedToConference,
             Qt::UniqueConnection);
-
-    connect(accInfo.callModel.get(),
-            &CallModel::callInfosChanged,
-            this,
-            QOverload<const QString&, const QString&>::of(&CallAdapter::onCallInfosChanged));
 }
 
 void
@@ -719,24 +538,19 @@ CallAdapter::setActiveStream(const QString& uri, const QString& deviceId, const
         confId = convInfo.callId;
     try {
         const auto call = callModel->getCall(confId);
-        auto participants = getConferencesInfos();
-        std::vector<QJsonObject> activeParticipants = {};
+        auto& participantsModel = callModel->getParticipantsInfos(call.id);
+        auto participants = participantsModel.getParticipants();
+        decltype(participants) activeParticipants = {};
         bool removeActive = false;
         for (auto part : participants) {
-            auto participant = part.toJsonObject();
-
-            auto puri = participant[lrc::api::ParticipantsInfosStrings::URI].toString();
-            auto pdeviceId = participant[lrc::api::ParticipantsInfosStrings::DEVICE].toString();
-            auto pstreamId = participant[lrc::api::ParticipantsInfosStrings::STREAMID].toString();
-
-            auto isParticipant = puri == uri && pdeviceId == deviceId && pstreamId == streamId;
-            auto active = participant[lrc::api::ParticipantsInfosStrings::ACTIVE].toBool();
-            if (active && !isParticipant)
-                activeParticipants.push_back(participant);
+            auto isParticipant = part.uri == uri && part.device == deviceId
+                                 && part.sinkId == streamId;
+            if (part.active && !isParticipant)
+                activeParticipants.push_back(part);
 
             if (isParticipant) {
                 // Else, continue.
-                if (!active) {
+                if (!part.active) {
                     callModel->setActiveStream(confId, uri, deviceId, streamId, true);
                     callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
                 } else if (call.layout == lrc::api::call::Layout::ONE_WITH_SMALL) {
@@ -747,12 +561,8 @@ CallAdapter::setActiveStream(const QString& uri, const QString& deviceId, const
         }
         if (removeActive) {
             // If in Big, we can remove other actives
-            for (const auto& p : activeParticipants) {
-                auto puri = p[lrc::api::ParticipantsInfosStrings::URI].toString();
-                auto deviceId = p[lrc::api::ParticipantsInfosStrings::DEVICE].toString();
-                auto streamId = p[lrc::api::ParticipantsInfosStrings::STREAMID].toString();
-                callModel->setActiveStream(confId, puri, deviceId, streamId, false);
-            }
+            for (const auto& part : activeParticipants)
+                callModel->setActiveStream(confId, part.uri, part.device, part.sinkId, false);
         }
     } catch (...) {
     }
@@ -770,31 +580,24 @@ CallAdapter::minimizeParticipant(const QString& uri)
         confId = convInfo.callId;
     try {
         const auto call = callModel->getCall(confId);
-        auto participants = getConferencesInfos();
+        auto& participantsModel = callModel->getParticipantsInfos(call.id);
+        auto participants = participantsModel.getParticipants();
         auto activeParticipants = 0;
         for (auto& part : participants) {
-            auto participant = part.toJsonObject();
-            if (participant[lrc::api::ParticipantsInfosStrings::ACTIVE].toBool()) {
+            if (part.active) {
                 activeParticipants += 1;
-                if (participant[lrc::api::ParticipantsInfosStrings::URI].toString() == uri
-                    && call.layout == lrc::api::call::Layout::ONE_WITH_SMALL) {
-                    auto deviceId = participant[lrc::api::ParticipantsInfosStrings::DEVICE]
-                                        .toString();
-                    auto streamId = participant[lrc::api::ParticipantsInfosStrings::STREAMID]
-                                        .toString();
-                    callModel->setActiveStream(confId, uri, deviceId, streamId, false);
+                if (part.uri == uri && call.layout == lrc::api::call::Layout::ONE_WITH_SMALL) {
+                    callModel->setActiveStream(confId, part.uri, part.device, part.sinkId, false);
                 }
             }
         }
         if (activeParticipants == 1) {
             // only one active left, we can change the layout.
-            if (call.layout == lrc::api::call::Layout::ONE) {
+            if (call.layout == lrc::api::call::Layout::ONE)
                 callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
-            } else {
+            else
                 callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
-            }
         }
-
     } catch (...) {
     }
 }
diff --git a/src/app/calladapter.h b/src/app/calladapter.h
index ff1112bc9..a2d554ce0 100644
--- a/src/app/calladapter.h
+++ b/src/app/calladapter.h
@@ -24,7 +24,6 @@
 #include "qmladapterbase.h"
 #include "screensaver.h"
 #include "calloverlaymodel.h"
-#include "callparticipantsmodel.h"
 
 #include <QObject>
 #include <QString>
@@ -80,7 +79,6 @@ public:
     Q_INVOKABLE void muteAudioToggle();
     Q_INVOKABLE void muteCameraToggle();
     Q_INVOKABLE bool isRecordingThisCall();
-    Q_INVOKABLE QVariantList getConferencesInfos() const;
     Q_INVOKABLE void muteParticipant(const QString& accountUri,
                                      const QString& deviceId,
                                      const QString& sinkId,
@@ -95,11 +93,10 @@ public:
     Q_INVOKABLE void setCallInfo();
     Q_INVOKABLE void updateAdvancedInformation();
 
-    Q_INVOKABLE bool takeScreenshot(const QImage &image, const QString &path);
+    Q_INVOKABLE bool takeScreenshot(const QImage& image, const QString& path);
 
 Q_SIGNALS:
     void callStatusChanged(int index, const QString& accountId, const QString& convUid);
-    void callInfosChanged(const QVariant& infos, const QString& accountId, const QString& convUid);
 
     // For Call Overlay
     void updateTimeText(const QString& time);
@@ -109,18 +106,13 @@ 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 onCallStatusChanged(const QString& callId, int code);
     void onCallAddedToConference(const QString& callId, const QString& confId);
-    void onParticipantAdded(const QString& callId, int index);
-    void onParticipantRemoved(const QString& callId, int index);
-    void onParticipantUpdated(const QString& callId, int index);
     void onCallStarted(const QString& callId);
     void onCallEnded(const QString& callId);
 
 private:
     void showNotification(const QString& accountId, const QString& convUid);
-    void fillParticipantData(QJsonObject& participant) const;
     void preventScreenSaver(bool state);
     void saveConferenceSubcalls();
 
@@ -129,7 +121,6 @@ private:
     ScreenSaver screenSaver;
     SystemTray* systemTray_;
     QScopedPointer<CallOverlayModel> overlayModel_;
-    QScopedPointer<CallParticipantsModel> participantsModel_;
     VectorString currentConfSubcalls_;
 
     std::unique_ptr<CallInformationListModel> callInformationListModel_;
diff --git a/src/app/currentcall.cpp b/src/app/currentcall.cpp
index 9213d04ff..8406633e7 100644
--- a/src/app/currentcall.cpp
+++ b/src/app/currentcall.cpp
@@ -16,13 +16,18 @@
  */
 
 #include "currentcall.h"
+#include "qmlregister.h"
 
 #include <api/callparticipantsmodel.h>
+#include <api/devicemodel.h>
 
 CurrentCall::CurrentCall(LRCInstance* lrcInstance, QObject* parent)
     : QObject(parent)
     , lrcInstance_(lrcInstance)
 {
+    participantsModel_.reset(new CallParticipantsModel(lrcInstance_, this));
+    QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, participantsModel_.get(), "CallParticipantsModel");
+
     connect(lrcInstance_,
             &LRCInstance::currentAccountIdChanged,
             this,
@@ -72,7 +77,17 @@ CurrentCall::updateId(QString callId)
         }
     }
     // Set the current id_ if there is a call.
-    set_id((accInfo.callModel->hasCall(callId) ? callId : QString()));
+    auto hasCall = accInfo.callModel->hasCall(callId);
+    set_id((hasCall ? callId : QString()));
+
+    if (hasCall) {
+        try {
+            auto callInfo = accInfo.callModel->getCall(callId);
+            participantsModel_->setParticipants(id_, getConferencesInfos());
+            participantsModel_->setConferenceLayout(static_cast<int>(callInfo.layout), id_);
+        } catch (...) {
+        }
+    }
 }
 
 void
@@ -105,6 +120,88 @@ CurrentCall::updateParticipants()
     set_isConference(uris.size());
 }
 
+void
+CurrentCall::onParticipantAdded(const QString& callId, int index)
+{
+    if (callId != id_)
+        return;
+    auto infos = getConferencesInfos();
+    if (index < infos.size())
+        participantsModel_->addParticipant(index, infos[index]);
+}
+
+void
+CurrentCall::onParticipantRemoved(const QString& callId, int index)
+{
+    if (callId != id_)
+        return;
+    participantsModel_->removeParticipant(index);
+}
+
+void
+CurrentCall::onParticipantUpdated(const QString& callId, int index)
+{
+    if (callId != id_)
+        return;
+    auto infos = getConferencesInfos();
+    if (index < infos.size())
+        participantsModel_->updateParticipant(index, infos[index]);
+}
+
+void
+CurrentCall::fillParticipantData(QJsonObject& participant) const
+{
+    // TODO: getCurrentDeviceId should be part of CurrentAccount, and Current<thing>
+    //       should be read accessible through LRCInstance ??
+    auto getCurrentDeviceId = [](const account::Info& accInfo) -> QString {
+        const auto& deviceList = accInfo.deviceModel->getAllDevices();
+        auto devIt = std::find_if(std::cbegin(deviceList),
+                                  std::cend(deviceList),
+                                  [](const Device& dev) { return dev.isCurrent; });
+        return devIt != deviceList.cend() ? devIt->id : QString();
+    };
+
+    auto& accInfo = lrcInstance_->getCurrentAccountInfo();
+    using namespace lrc::api::ParticipantsInfosStrings;
+
+    // If both the URI and the device Id match, we set the "is local" flag
+    // used to filter out the participant.
+    // TODO:
+    //  - This filter should always be applied, and any local streams should render
+    //    using local sinks. Local non-preview participants should have proxy participant
+    //    items replaced into this model using their local sink Ids.
+    //  - The app setting should remain and be used to control whether or not the preview
+    //    sink partipcant is rendered.
+    auto uri = participant[URI].toString();
+    participant[ISLOCAL] = false;
+    if (uri == accInfo.profileInfo.uri && participant[DEVICE] == getCurrentDeviceId(accInfo)) {
+        participant[BESTNAME] = tr("Me");
+        participant[ISLOCAL] = true;
+    } else {
+        try {
+            participant[BESTNAME] = accInfo.contactModel->bestNameForContact(uri);
+        } catch (...) {
+        }
+    }
+}
+
+QVariantList
+CurrentCall::getConferencesInfos() const
+{
+    QVariantList map;
+    try {
+        auto callModel = lrcInstance_->getCurrentCallModel();
+        auto& participantsModel = callModel->getParticipantsInfos(id_);
+        for (int index = 0; index < participantsModel.getParticipants().size(); index++) {
+            auto participant = participantsModel.toQJsonObject(index);
+            fillParticipantData(participant);
+            map.push_back(QVariant(participant));
+        }
+    } catch (...) {
+    }
+    return map;
+}
+
 void
 CurrentCall::updateCallInfo()
 {
@@ -162,6 +259,7 @@ CurrentCall::updateCallInfo()
     QStringList recorders {};
     if (callModel->hasCall(id_)) {
         auto callInfo = callModel->getCall(id_);
+        participantsModel_->setConferenceLayout(static_cast<int>(callInfo.layout), id_);
         recorders = callInfo.recordingPeers;
     }
     updateRecordingState(callModel->isRecording(id_));
@@ -230,6 +328,21 @@ CurrentCall::connectModel()
             this,
             &CurrentCall::onRecordingStateChanged,
             Qt::UniqueConnection);
+    connect(callModel,
+            &CallModel::participantAdded,
+            this,
+            &CurrentCall::onParticipantAdded,
+            Qt::UniqueConnection);
+    connect(callModel,
+            &CallModel::participantRemoved,
+            this,
+            &CurrentCall::onParticipantRemoved,
+            Qt::UniqueConnection);
+    connect(callModel,
+            &CallModel::participantUpdated,
+            this,
+            &CurrentCall::onParticipantUpdated,
+            Qt::UniqueConnection);
 }
 
 void
diff --git a/src/app/currentcall.h b/src/app/currentcall.h
index 3a0c6bdbe..7a4eea808 100644
--- a/src/app/currentcall.h
+++ b/src/app/currentcall.h
@@ -19,6 +19,7 @@
 
 #include "lrcinstance.h"
 #include "qtutils.h"
+#include "callparticipantsmodel.h"
 
 #include <QObject>
 #include <QString>
@@ -56,6 +57,7 @@ class CurrentCall final : public QObject
 public:
     explicit CurrentCall(LRCInstance* lrcInstance, QObject* parent = nullptr);
     ~CurrentCall() = default;
+    Q_INVOKABLE QVariantList getConferencesInfos() const;
 
 private:
     void updateId(QString callId = {});
@@ -65,6 +67,7 @@ private:
     void updateRemoteRecorders(const QStringList& recorders);
     void updateRecordingState(bool state);
     void connectModel();
+    void fillParticipantData(QJsonObject& participant) const;
 
 private Q_SLOTS:
     void onCurrentConvIdChanged();
@@ -73,10 +76,14 @@ private Q_SLOTS:
     void onCallInfosChanged(const QString& accountId, const QString& callId);
     void onCurrentCallChanged(const QString& callId);
     void onParticipantsChanged(const QString& callId);
+    void onParticipantAdded(const QString& callId, int index);
+    void onParticipantRemoved(const QString& callId, int index);
+    void onParticipantUpdated(const QString& callId, int index);
     void onRemoteRecordersChanged(const QString& callId, const QStringList& recorders);
     void onRecordingStateChanged(const QString& callId, bool state);
     void onShowIncomingCallView(const QString& accountId, const QString& convUid);
 
 private:
     LRCInstance* lrcInstance_;
+    QScopedPointer<CallParticipantsModel> participantsModel_;
 };
diff --git a/src/libclient/callmodel.cpp b/src/libclient/callmodel.cpp
index 530458d6b..449184f0e 100644
--- a/src/libclient/callmodel.cpp
+++ b/src/libclient/callmodel.cpp
@@ -1628,6 +1628,21 @@ CallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId,
     if (it == calls.end() or not it->second)
         return;
 
+    // TODO: remove when the rendez-vous UI will be done
+    // For now, the rendez-vous account can see ongoing calls
+    // And must be notified when a new
+    QStringList callList = CallManager::instance().getParticipantList(linked.owner.id, confId);
+    Q_FOREACH (const auto& call, callList) {
+        Q_EMIT linked.callAddedToConference(call, confId);
+        if (calls.find(call) == calls.end()) {
+            qWarning() << "Call not found";
+        } else {
+            calls[call]->videoMuted = it->second->videoMuted;
+            calls[call]->audioMuted = it->second->audioMuted;
+            Q_EMIT linked.callInfosChanged(linked.owner.id, call);
+        }
+    }
+
     auto participantIt = participantsModel.find(confId);
     if (participantIt == participantsModel.end())
         participantIt = participantsModel
@@ -1657,20 +1672,6 @@ CallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId,
         }
     }
 
-    // TODO: remove when the rendez-vous UI will be done
-    // For now, the rendez-vous account can see ongoing calls
-    // And must be notified when a new
-    QStringList callList = CallManager::instance().getParticipantList(linked.owner.id, confId);
-    Q_FOREACH (const auto& call, callList) {
-        Q_EMIT linked.callAddedToConference(call, confId);
-        if (calls.find(call) == calls.end()) {
-            qWarning() << "Call not found";
-        } else {
-            calls[call]->videoMuted = it->second->videoMuted;
-            calls[call]->audioMuted = it->second->audioMuted;
-            Q_EMIT linked.callInfosChanged(linked.owner.id, call);
-        }
-    }
     Q_EMIT linked.callInfosChanged(linked.owner.id, confId);
     Q_EMIT linked.participantsChanged(confId);
 }
-- 
GitLab