From 08236cf5e74eb3d1ec30a124a9c568c3bebc8938 Mon Sep 17 00:00:00 2001 From: ababi <albert.babi@savoirfairelinux.com> Date: Thu, 17 Dec 2020 12:40:08 +0100 Subject: [PATCH] recording: show message when peer starts / stops recording the call Gitlab: #160 Change-Id: Id8125c56145cc661941f445c2f52b73fd983c97d --- src/calladapter.cpp | 23 ++++++ src/calladapter.h | 2 + src/constant/JamiStrings.qml | 5 ++ src/mainview/components/CallOverlay.qml | 74 ++++++++++++++----- .../components/CallOverlayButtonGroup.qml | 2 +- .../components/CallViewContextMenu.qml | 5 +- src/mainview/components/VideoCallPage.qml | 4 + 7 files changed, 94 insertions(+), 21 deletions(-) diff --git a/src/calladapter.cpp b/src/calladapter.cpp index c3b27152a..9acffcc29 100644 --- a/src/calladapter.cpp +++ b/src/calladapter.cpp @@ -469,6 +469,29 @@ CallAdapter::connectCallModel(const QString& accountId) emit LRCInstance::instance().updateSmartList(); }); + + remoteRecordingChangedConnection_ = QObject::connect( + accInfo.callModel.get(), + &lrc::api::NewCallModel::remoteRecordingChanged, + [this](const QString& callId, const QSet<QString>& peerRec, bool state) { + const auto currentCallId = + LRCInstance::getCallIdForConversationUid(convUid_, accountId_); + if (callId == currentCallId) { + const auto& accInfo = LRCInstance::getCurrentAccountInfo(); + QStringList peers {}; + for (const auto& uri: peerRec) { + auto bestName = accInfo.contactModel->bestNameForContact(uri); + if (!bestName.isEmpty()) { + peers.append(bestName); + } + } + if (!peers.isEmpty()) { + emit remoteRecordingChanged(peers, true); + } else if (!state) { + emit remoteRecordingChanged(peers, false); + } + } + }); } void diff --git a/src/calladapter.h b/src/calladapter.h index f8767b721..6d1616849 100644 --- a/src/calladapter.h +++ b/src/calladapter.h @@ -96,6 +96,7 @@ signals: bool isSIP, bool isConferenceCall, const QString& bestName); + void remoteRecordingChanged(const QStringList& peers, bool state); public slots: void slotShowIncomingCallView(const QString& accountId, @@ -117,6 +118,7 @@ private: QMetaObject::Connection onParticipantsChangedConnection_; QMetaObject::Connection closeIncomingCallPageConnection_; QMetaObject::Connection appStateChangedConnection_; + QMetaObject::Connection remoteRecordingChangedConnection_; /* * For Call Overlay diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml index af29f73b6..dbb213c0d 100644 --- a/src/constant/JamiStrings.qml +++ b/src/constant/JamiStrings.qml @@ -174,6 +174,11 @@ Item { property string name: qsTr("name") property string identifier: qsTr("Identifier") + // CallOverlay + property string isRecording: qsTr("is recording") + property string areRecording: qsTr("are recording") + property string peerStoppedRecording: qsTr("Peer stopped recording") + // CallOverlayButtonGroup property string mute: qsTr("Mute") property string unmute: qsTr("Unmute") diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml index c2956a4d0..84dc5bd9f 100644 --- a/src/mainview/components/CallOverlay.qml +++ b/src/mainview/components/CallOverlay.qml @@ -36,15 +36,17 @@ Rectangle { id: callOverlayRect property string timeText: "00:00" - - signal overlayChatButtonClicked + property string remoteRecordingLabel: "" property var participantOverlays: [] property var participantComponent: Qt.createComponent("ParticipantOverlay.qml") - function setRecording(isRecording) { - callViewContextMenu.isRecording = isRecording - recordingRect.visible = isRecording + signal overlayChatButtonClicked + + function setRecording(localIsRecording) { + callViewContextMenu.localIsRecording = localIsRecording + recordingRect.visible = localIsRecording + || callViewContextMenu.peerIsRecording } function updateButtonStatus(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, @@ -52,12 +54,11 @@ Rectangle { callViewContextMenu.isSIP = isSIP callViewContextMenu.isPaused = isPaused callViewContextMenu.isAudioOnly = isAudioOnly - callViewContextMenu.isRecording = isRecording + callViewContextMenu.localIsRecording = isRecording recordingRect.visible = isRecording callOverlayButtonGroup.setButtonStatus(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, - isRecording, isSIP, - isConferenceCall) + isSIP, isConferenceCall) } function updateMenu() { @@ -91,7 +92,6 @@ Rectangle { && pW >= distantRenderer.width - distantRenderer.getXOffset() * 2 - 1) } - function handleParticipantsInfo(infos) { // TODO: in the future the conference layout should be entirely managed by the client videoCallOverlay.updateMenu() @@ -185,7 +185,6 @@ Rectangle { } } } - } // x, y position does not need to be translated @@ -196,6 +195,27 @@ Rectangle { callViewContextMenu.openMenu() } + function showRemoteRecording(peers, state) { + var label = "" + var i = 0 + if (state) { + for (var p in peers) { + label += peers[p] + if (i !== (peers.length - 1)) + label += ", " + i += 1 + } + label += " " + ((peers.length > 1)? JamiStrings.areRecording + : JamiStrings.isRecording) + } + + remoteRecordingLabel = state? label : JamiStrings.peerStoppedRecording + callViewContextMenu.peerIsRecording = state + recordingRect.visible = callViewContextMenu.localIsRecording + || callViewContextMenu.peerIsRecording + callOverlayRectMouseArea.entered() + } + anchors.fill: parent SipInputPanel { @@ -212,13 +232,26 @@ Rectangle { onTriggered: { if (overlayUpperPartRect.state !== 'freezed') { overlayUpperPartRect.state = 'freezed' + resetRecordingLabelTimer.restart() } if (callOverlayButtonGroup.state !== 'freezed') { callOverlayButtonGroup.state = 'freezed' + resetRecordingLabelTimer.restart() } } } + // Timer to reset recording label text + Timer { + id: resetRecordingLabelTimer + interval: 1000 + onTriggered: { + if (callOverlayButtonGroup.state === 'freezed' + && !callViewContextMenu.peerIsRecording) + remoteRecordingLabel = "" + } + } + Rectangle { id: overlayUpperPartRect @@ -287,8 +320,13 @@ Rectangle { id: textMetricsjamiBestNameText font: jamiBestNameText.font text: { - if (videoCallPageRect) - return videoCallPageRect.bestName + if (videoCallPageRect) { + if (remoteRecordingLabel === "") { + return videoCallPageRect.bestName + } else { + return remoteRecordingLabel + } + } return "" } elideWidth: overlayUpperPartRect.width / 3 @@ -299,8 +337,11 @@ Rectangle { Text { id: callTimerText Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.preferredWidth: overlayUpperPartRect.width / 3 + Layout.preferredWidth: 64 + Layout.minimumWidth: 64 Layout.preferredHeight: 48 + Layout.rightMargin: recordingRect.visible? + 0 : JamiTheme.preferredMarginSize font.pointSize: JamiTheme.textFontSize horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter @@ -310,7 +351,7 @@ Rectangle { id: textMetricscallTimerText font: callTimerText.font text: timeText - elideWidth: overlayUpperPartRect.width / 3 + elideWidth: overlayUpperPartRect.width / 4 elide: Qt.ElideRight } } @@ -318,6 +359,7 @@ Rectangle { Rectangle { id: recordingRect Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + Layout.rightMargin: JamiTheme.preferredMarginSize height: 16 width: 16 radius: height / 2 @@ -330,10 +372,6 @@ Rectangle { ColorAnimation { from: "transparent"; to: "red"; duration: 500 } } } - - Item { - width: 8 - } } color: "transparent" diff --git a/src/mainview/components/CallOverlayButtonGroup.qml b/src/mainview/components/CallOverlayButtonGroup.qml index 6d66301b4..b7fce991c 100644 --- a/src/mainview/components/CallOverlayButtonGroup.qml +++ b/src/mainview/components/CallOverlayButtonGroup.qml @@ -45,7 +45,7 @@ Rectangle { } function setButtonStatus(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, - isRecording, isSIP, isConferenceCall) { + isSIP, isConferenceCall) { root.isModerator = CallAdapter.isCurrentModerator() root.isSip = isSIP noVideoButton.visible = !isAudioOnly diff --git a/src/mainview/components/CallViewContextMenu.qml b/src/mainview/components/CallViewContextMenu.qml index 9667aaf12..75919c5cd 100644 --- a/src/mainview/components/CallViewContextMenu.qml +++ b/src/mainview/components/CallViewContextMenu.qml @@ -37,7 +37,8 @@ Item { property bool isSIP: false property bool isPaused: false property bool isAudioOnly: false - property bool isRecording: false + property bool localIsRecording: false + property bool peerIsRecording: false signal pluginItemClicked signal transferCallButtonClicked @@ -67,7 +68,7 @@ Item { ContextMenuGenerator.addMenuSeparator() } - ContextMenuGenerator.addMenuItem(isRecording ? JamiStrings.stopRec : + ContextMenuGenerator.addMenuItem(localIsRecording ? JamiStrings.stopRec : JamiStrings.startRec, "qrc:/images/icons/av_icons/fiber_manual_record-24px.svg", function (){ diff --git a/src/mainview/components/VideoCallPage.qml b/src/mainview/components/VideoCallPage.qml index a7897d3f0..52e879d5b 100644 --- a/src/mainview/components/VideoCallPage.qml +++ b/src/mainview/components/VideoCallPage.qml @@ -197,6 +197,10 @@ Rectangle { function onShowOnHoldLabel(isPaused) { videoCallOverlay.showOnHoldImage(isPaused) } + + function onRemoteRecordingChanged(label, state) { + videoCallOverlay.showRemoteRecording(label, state) + } } onOverlayChatButtonClicked: { -- GitLab