diff --git a/src/app/callparticipantsmodel.cpp b/src/app/callparticipantsmodel.cpp index 48a8544febaa200ac654c8956a6c3630c9728e04..e79b29771ef4e37bdf842e05c489b854bf414e3d 100644 --- a/src/app/callparticipantsmodel.cpp +++ b/src/app/callparticipantsmodel.cpp @@ -87,6 +87,8 @@ CallParticipantsModel::data(const QModelIndex& index, int role) const return QVariant(item.value(HANDRAISED).toBool()); case Role::VoiceActivity: return QVariant(item.value(VOICEACTIVITY).toBool()); + case Role::IsRecording: + return QVariant(item.value(ISRECORDING).toBool()); } return QVariant(); } diff --git a/src/app/callparticipantsmodel.h b/src/app/callparticipantsmodel.h index 15330360c45830221c4af57eacb7da0874b4ee38..b701cf239b891494c04220c6a2f4f7a64998bbc1 100644 --- a/src/app/callparticipantsmodel.h +++ b/src/app/callparticipantsmodel.h @@ -46,6 +46,7 @@ X(IsLocal) \ X(IsContact) \ X(VoiceActivity) \ + X(IsRecording) \ X(HandRaised) namespace CallParticipant { diff --git a/src/app/constant/JamiTheme.qml b/src/app/constant/JamiTheme.qml index 5267a12e9aca8c7c3c297bac7182db12a5292d58..67447c7883dcce7adf885ab59174817d1e67fac8 100644 --- a/src/app/constant/JamiTheme.qml +++ b/src/app/constant/JamiTheme.qml @@ -322,6 +322,10 @@ Item { property real lineEditContextMenuItemsWidth: 100 property real lineEditContextMenuSeparatorsHeight: 2 + // Recording + property real recordingBtnSize: 12 + property real recordingIndicatorSize: 24 + //TimestampInfo property int timestampLinePadding: 40 property int dayTimestampTopMargin: 30 diff --git a/src/app/mainview/components/ParticipantOverlay.qml b/src/app/mainview/components/ParticipantOverlay.qml index 1adbc5968425bfec9cc88a74fefd69665cad8909..e66bdb54bcc68d688db21b18cdaa8ddf8de4461f 100644 --- a/src/app/mainview/components/ParticipantOverlay.qml +++ b/src/app/mainview/components/ParticipantOverlay.qml @@ -58,6 +58,7 @@ Item { property bool videoMuted: true property bool voiceActive: false property bool isLocalMuted: true + property bool isRecording: false property bool meHost: CallAdapter.isCurrentHost() property bool meModerator: CallAdapter.isModerator() @@ -331,6 +332,45 @@ Item { radius: 5 } + Item { + id: recordingIndicator + + visible: root.isRecording + z: participantRect.z + 1 + + width: JamiTheme.recordingIndicatorSize + height: shapeHeight + + anchors.right: isRaiseHandIndicator.visible ? isRaiseHandIndicator.left : participantRect.right + anchors.top: participantRect.top + + Rectangle { + anchors.centerIn: parent + + height: JamiTheme.recordingBtnSize + width: JamiTheme.recordingBtnSize + + radius: height / 2 + color: JamiTheme.recordIconColor + + SequentialAnimation on color { + loops: Animation.Infinite + running: recordingIndicator.visible + ColorAnimation { + from: JamiTheme.recordIconColor + to: "transparent" + duration: JamiTheme.recordBlinkDuration + } + ColorAnimation { + from: "transparent" + to: JamiTheme.recordIconColor + duration: JamiTheme.recordBlinkDuration + } + } + } + } + + Rectangle { id: alertMessage diff --git a/src/app/mainview/components/ParticipantsLayer.qml b/src/app/mainview/components/ParticipantsLayer.qml index 2e5c8b78c00d6a4c0abde7e032c5314f62a7fa67..b3fddbf0d10b03d0b3630574664c5fae541f3d25 100644 --- a/src/app/mainview/components/ParticipantsLayer.qml +++ b/src/app/mainview/components/ParticipantsLayer.qml @@ -65,6 +65,7 @@ Item { participantIsActive: active_ isLocalMuted: audioLocalMuted_ voiceActive: voiceActive_ + isRecording: isRecording_ participantIsModeratorMuted: audioModeratorMuted_ participantHandIsRaised: isHandRaised_ diff --git a/src/app/mainview/components/ParticipantsLayoutHorizontal.qml b/src/app/mainview/components/ParticipantsLayoutHorizontal.qml index 285be952817fb9da740184d2303de0ae0764ce2b..79d472ca5856003eaead71269e1717fa66269c48 100644 --- a/src/app/mainview/components/ParticipantsLayoutHorizontal.qml +++ b/src/app/mainview/components/ParticipantsLayoutHorizontal.qml @@ -121,6 +121,7 @@ SplitView { property bool audioModeratorMuted_: AudioModeratorMuted property bool isHandRaised_: HandRaised property bool voiceActive_: VoiceActivity + property bool isRecording_: IsRecording } } } @@ -309,6 +310,7 @@ SplitView { property bool audioModeratorMuted_: AudioModeratorMuted property bool isHandRaised_: HandRaised property bool voiceActive_: VoiceActivity + property bool isRecording_: IsRecording } } } diff --git a/src/app/mainview/components/ParticipantsLayoutVertical.qml b/src/app/mainview/components/ParticipantsLayoutVertical.qml index 23a834e17ff90a9384dd8ba25a2b562273aa9ccf..0d466e00c98e3800306655edae1d96ee70f22599 100644 --- a/src/app/mainview/components/ParticipantsLayoutVertical.qml +++ b/src/app/mainview/components/ParticipantsLayoutVertical.qml @@ -216,6 +216,7 @@ SplitView { property bool audioModeratorMuted_: AudioModeratorMuted property bool isHandRaised_: HandRaised property bool voiceActive_: VoiceActivity + property bool isRecording_: IsRecording } } } @@ -290,6 +291,7 @@ SplitView { property bool audioModeratorMuted_: AudioModeratorMuted property bool isHandRaised_: HandRaised property bool voiceActive_: VoiceActivity + property bool isRecording_: IsRecording } } } diff --git a/src/libclient/api/callparticipantsmodel.h b/src/libclient/api/callparticipantsmodel.h index c51cb10197f4d07fadbeb02985ee4ba82f23b15e..c1c7bf9b251045573d42f3d169419607ff636082 100644 --- a/src/libclient/api/callparticipantsmodel.h +++ b/src/libclient/api/callparticipantsmodel.h @@ -53,6 +53,7 @@ const QString AUDIOMODERATORMUTED = "audioModeratorMuted"; const QString ISMODERATOR = "isModerator"; const QString HANDRAISED = "handRaised"; const QString VOICEACTIVITY = "voiceActivity"; +const QString ISRECORDING = "recording"; const QString STREAMID = "sinkId"; // TODO update const QString BESTNAME = "bestName"; const QString ISLOCAL = "isLocal"; @@ -83,6 +84,7 @@ struct ParticipantInfos isModerator = infos[ParticipantsInfosStrings::ISMODERATOR] == "true"; handRaised = infos[ParticipantsInfosStrings::HANDRAISED] == "true"; voiceActivity = infos[ParticipantsInfosStrings::VOICEACTIVITY] == "true"; + isRecording = infos[ParticipantsInfosStrings::ISRECORDING] == "true"; if (infos[ParticipantsInfosStrings::STREAMID].isEmpty()) sinkId = callId + uri + device; @@ -110,6 +112,7 @@ struct ParticipantInfos bool isContact {false}; bool handRaised {false}; bool voiceActivity {false}; + bool isRecording {false}; bool operator==(const ParticipantInfos& other) const { @@ -118,7 +121,8 @@ struct ParticipantInfos && audioModeratorMuted == other.audioModeratorMuted && avatar == other.avatar && bestName == other.bestName && isContact == other.isContact && islocal == other.islocal && videoMuted == other.videoMuted - && handRaised == other.handRaised && voiceActivity == other.voiceActivity; + && handRaised == other.handRaised && voiceActivity == other.voiceActivity + && isRecording == other.isRecording; } }; diff --git a/src/libclient/callparticipantsmodel.cpp b/src/libclient/callparticipantsmodel.cpp index 523a38ec9b1baf4c2324a019d163d3cee5205fa9..cfe85f52b306acdb4980c888b110b9965ab66d28 100644 --- a/src/libclient/callparticipantsmodel.cpp +++ b/src/libclient/callparticipantsmodel.cpp @@ -201,6 +201,7 @@ CallParticipants::toQJsonObject(uint index) const ret[ParticipantsInfosStrings::ISCONTACT] = participant->isContact; ret[ParticipantsInfosStrings::HANDRAISED] = participant->handRaised; ret[ParticipantsInfosStrings::VOICEACTIVITY] = participant->voiceActivity; + ret[ParticipantsInfosStrings::ISRECORDING] = participant->isRecording; ret[ParticipantsInfosStrings::CALLID] = callId_; return ret;