From 695dff39946e71d0cf8d4408fd3a48edefa597a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Mon, 28 Sep 2020 16:38:15 -0400
Subject: [PATCH] calladapter: use infos from daemon to know if we are the conf
 moderator

Make the difference between a host and a moderator. The main difference for
now is that the host can hang up calls, not the moderator because they don't
know the calls hosted

Change-Id: Iec36c4d26ae32126e8628bef6491c35d0228a45f
---
 src/calladapter.cpp                           | 42 +++++++++++++++----
 src/calladapter.h                             |  3 +-
 src/mainview/components/CallOverlay.qml       | 12 +++---
 .../components/CallOverlayButtonGroup.qml     | 14 +++----
 .../components/ParticipantOverlay.qml         |  7 +++-
 5 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index d556a9e59..96dcb7369 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -546,8 +546,9 @@ CallAdapter::maximizeParticipant(const QString& uri, bool isActive)
     auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
     auto* convModel = LRCInstance::getCurrentConversationModel();
     const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
-    const auto confId = conversation.confId;
-
+    auto confId = conversation.confId;
+    if (confId.isEmpty())
+        confId = conversation.callId;
     try {
         const auto call = callModel->getCall(confId);
         switch (call.layout) {
@@ -576,7 +577,9 @@ CallAdapter::minimizeParticipant()
     auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
     auto* convModel = LRCInstance::getCurrentConversationModel();
     const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
-    const auto confId = conversation.confId;
+    auto confId = conversation.confId;
+    if (confId.isEmpty())
+        confId = conversation.callId;
     try {
         auto call = callModel->getCall(confId);
         switch (call.layout) {
@@ -619,19 +622,44 @@ CallAdapter::isRecordingThisCall()
 }
 
 bool
-CallAdapter::isCurrentMaster() const
+CallAdapter::isCurrentHost() const
+{
+    auto* convModel = LRCInstance::getCurrentConversationModel();
+    const auto convInfo = convModel->getConversationForUID(convUid_);
+    if (!convInfo.uid.isEmpty()) {
+        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+        try {
+            auto call = callModel->getCall(convInfo.callId);
+            if (call.participantsInfos.size() == 0) {
+                return true;
+            } else {
+                return !convInfo.confId.isEmpty() && callModel->hasCall(convInfo.confId);
+            }
+        } catch (...) {
+        }
+    }
+    return true;
+}
+
+bool
+CallAdapter::isCurrentModerator() const
 {
     auto* convModel = LRCInstance::getCurrentConversationModel();
     const auto convInfo = convModel->getConversationForUID(convUid_);
     if (!convInfo.uid.isEmpty()) {
         auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
         try {
-            if (!convInfo.confId.isEmpty() && callModel->hasCall(convInfo.confId)) {
+            auto call = callModel->getCall(convInfo.callId);
+            if (call.participantsInfos.size() == 0) {
                 return true;
             } else {
-                auto call = callModel->getCall(convInfo.callId);
-                return call.participantsInfos.size() == 0;
+                auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
+                for (const auto& participant : call.participantsInfos) {
+                    if (participant["uri"] == accInfo.profileInfo.uri)
+                        return participant["isModerator"] == "true";
+                }
             }
+            return false;
         } catch (...) {
         }
     }
diff --git a/src/calladapter.h b/src/calladapter.h
index 6fea6b3be..7ebf64334 100644
--- a/src/calladapter.h
+++ b/src/calladapter.h
@@ -56,7 +56,8 @@ public:
     Q_INVOKABLE void maximizeParticipant(const QString& uri, bool isActive);
     Q_INVOKABLE void minimizeParticipant();
     Q_INVOKABLE void hangUpThisCall();
-    Q_INVOKABLE bool isCurrentMaster() const;
+    Q_INVOKABLE bool isCurrentModerator() const;
+    Q_INVOKABLE bool isCurrentHost() const;
     Q_INVOKABLE int getCurrentLayoutType() const;
     Q_INVOKABLE void holdThisCallToggle();
     Q_INVOKABLE void muteThisCallToggle();
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index ac529f0c8..a29e0d2ec 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -58,8 +58,8 @@ Rectangle {
                                                isConferenceCall)
     }
 
-    function updateMaster() {
-        callOverlayButtonGroup.updateMaster()
+    function updateMenu() {
+        callOverlayButtonGroup.updateMenu()
     }
 
     function showOnHoldImage(visible) {
@@ -75,8 +75,9 @@ Rectangle {
     }
     
     function handleParticipantsInfo(infos) {
-        videoCallOverlay.updateMaster()
-        var isMaster = CallAdapter.isCurrentMaster()
+        videoCallOverlay.updateMenu()
+        var isModerator = CallAdapter.isCurrentModerator()
+        var isHost = CallAdapter.isCurrentHost()
         for (var p in participantOverlays) {
             if (participantOverlays[p])
                 participantOverlays[p].destroy()
@@ -102,7 +103,8 @@ Rectangle {
                 hover.setParticipantName(infos[infoVariant].bestName)
                 hover.active = infos[infoVariant].active;
                 hover.isLocal = infos[infoVariant].isLocal;
-                hover.setMenuVisible(isMaster)
+                hover.setMenuVisible(isModerator)
+                hover.setEndCallVisible(isHost)
                 hover.uri = infos[infoVariant].uri
                 if (infos[infoVariant].videoMuted)
                     hover.setAvatar(infos[infoVariant].avatar)
diff --git a/src/mainview/components/CallOverlayButtonGroup.qml b/src/mainview/components/CallOverlayButtonGroup.qml
index 8efcb55df..7ac4fc986 100644
--- a/src/mainview/components/CallOverlayButtonGroup.qml
+++ b/src/mainview/components/CallOverlayButtonGroup.qml
@@ -32,22 +32,22 @@ Rectangle {
     // ButtonCounts here is to make sure that flow layout margin is calculated correctly,
     // since no other methods can make buttons at the layout center.
     property int buttonPreferredSize: 24
-    property var isMaster: true
+    property var isHost: true
     property var isSip: false
 
     signal chatButtonClicked
     signal addToConferenceButtonClicked
 
-    function updateMaster() {
-        root.isMaster = CallAdapter.isCurrentMaster()
-        addToConferenceButton.visible = !root.isSip && root.isMaster
+    function updateMenu() {
+        root.isHost = CallAdapter.isCurrentHost()
+        addToConferenceButton.visible = !root.isSip && root.isHost
     }
 
     function setButtonStatus(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, isRecording, isSIP, isConferenceCall) {
-        root.isMaster = CallAdapter.isCurrentMaster()
+        root.isHost = CallAdapter.isCurrentModerator()
         root.isSip = isSIP
         noVideoButton.visible = !isAudioOnly
-        addToConferenceButton.visible = !isSIP && isMaster
+        addToConferenceButton.visible = !isSIP && isHost
 
         noMicButton.checked = isAudioMuted
         noVideoButton.checked = isVideoMuted
@@ -161,7 +161,7 @@ Rectangle {
 
             Layout.preferredWidth: buttonPreferredSize * 2
             Layout.preferredHeight: buttonPreferredSize * 2
-            visible: !isMaster
+            visible: !isHost
 
             backgroundColor: Qt.rgba(0, 0, 0, 0.75)
             onEnterColor: Qt.rgba(0, 0, 0, 0.6)
diff --git a/src/mainview/components/ParticipantOverlay.qml b/src/mainview/components/ParticipantOverlay.qml
index 264fc7270..c6e4f706c 100644
--- a/src/mainview/components/ParticipantOverlay.qml
+++ b/src/mainview/components/ParticipantOverlay.qml
@@ -31,6 +31,7 @@ Rectangle {
     property var uri: ""
     property var active: true
     property var isLocal: true
+    property var showEndCall: true
     property var injectedContextMenu: null
 
     function setParticipantName(name) {
@@ -51,6 +52,10 @@ Rectangle {
         optionsButton.visible = isVisible
     }
 
+    function setEndCallVisible(isVisible) {
+        showEndCall = isVisible
+    }
+
     border.width: 1
     opacity: 0
     color: "transparent"
@@ -147,7 +152,7 @@ Rectangle {
                         var layout = CallAdapter.getCurrentLayoutType()
                         var showMaximized = layout !== 2
                         var showMinimized = !(layout === 0 || (layout === 1 && !active))
-                        injectedContextMenu.showHangup = !root.isLocal
+                        injectedContextMenu.showHangup = !root.isLocal && showEndCall
                         injectedContextMenu.showMaximize = showMaximized
                         injectedContextMenu.showMinimize = showMinimized
                         injectedContextMenu.uri = uri
-- 
GitLab