mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-08-29 19:23:40 +02:00
callview: implement an observable object to detail the current call
Change-Id: Ic7025f66e472457e32149911053c8ff32e06bf21
This commit is contained in:
parent
fc91cdc23c
commit
ce6c7dc02b
22 changed files with 572 additions and 333 deletions
|
@ -221,7 +221,7 @@ set(COMMON_SOURCES
|
||||||
${APP_SRC_DIR}/callparticipantsmodel.cpp
|
${APP_SRC_DIR}/callparticipantsmodel.cpp
|
||||||
${APP_SRC_DIR}/tipsmodel.cpp
|
${APP_SRC_DIR}/tipsmodel.cpp
|
||||||
${APP_SRC_DIR}/positioning.cpp
|
${APP_SRC_DIR}/positioning.cpp
|
||||||
)
|
${APP_SRC_DIR}/currentcall.cpp)
|
||||||
|
|
||||||
set(COMMON_HEADERS
|
set(COMMON_HEADERS
|
||||||
${APP_SRC_DIR}/avatarimageprovider.h
|
${APP_SRC_DIR}/avatarimageprovider.h
|
||||||
|
@ -280,7 +280,8 @@ set(COMMON_HEADERS
|
||||||
${APP_SRC_DIR}/videoprovider.h
|
${APP_SRC_DIR}/videoprovider.h
|
||||||
${APP_SRC_DIR}/callparticipantsmodel.h
|
${APP_SRC_DIR}/callparticipantsmodel.h
|
||||||
${APP_SRC_DIR}/tipsmodel.h
|
${APP_SRC_DIR}/tipsmodel.h
|
||||||
${APP_SRC_DIR}/positioning.h)
|
${APP_SRC_DIR}/positioning.h
|
||||||
|
${APP_SRC_DIR}/currentcall.h)
|
||||||
|
|
||||||
if(WITH_WEBENGINE)
|
if(WITH_WEBENGINE)
|
||||||
list(APPEND COMMON_SOURCES
|
list(APPEND COMMON_SOURCES
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 2195ee0883efc92828a0cf33b830f43f9bd7e01b
|
|
|
@ -238,7 +238,6 @@ CallAdapter::onCallStatusChanged(const QString& callId, int code)
|
||||||
const auto& convInfo = lrcInstance_->getConversationFromCallId(callId);
|
const auto& convInfo = lrcInstance_->getConversationFromCallId(callId);
|
||||||
if (!convInfo.uid.isEmpty()) {
|
if (!convInfo.uid.isEmpty()) {
|
||||||
Q_EMIT callStatusChanged(static_cast<int>(call.status), accountId_, convInfo.uid);
|
Q_EMIT callStatusChanged(static_cast<int>(call.status), accountId_, convInfo.uid);
|
||||||
updateCallOverlay(convInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (call.status) {
|
switch (call.status) {
|
||||||
|
@ -330,25 +329,11 @@ CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
|
||||||
}
|
}
|
||||||
Q_EMIT callInfosChanged(call.isAudioOnly, accountId, convInfo.uid);
|
Q_EMIT callInfosChanged(call.isAudioOnly, accountId, convInfo.uid);
|
||||||
participantsModel_->setConferenceLayout(static_cast<int>(call.layout), callId);
|
participantsModel_->setConferenceLayout(static_cast<int>(call.layout), callId);
|
||||||
updateCallOverlay(convInfo);
|
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CallAdapter::onRemoteRecordingChanged(const QString& callId,
|
|
||||||
const QSet<QString>& peerRec,
|
|
||||||
bool state)
|
|
||||||
{
|
|
||||||
Q_UNUSED(peerRec)
|
|
||||||
Q_UNUSED(state)
|
|
||||||
const auto currentCallId
|
|
||||||
= lrcInstance_->getCallIdForConversationUid(lrcInstance_->get_selectedConvUid(), accountId_);
|
|
||||||
if (callId == currentCallId)
|
|
||||||
updateRecordingPeers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallAdapter::onCallAddedToConference(const QString& callId, const QString& confId)
|
CallAdapter::onCallAddedToConference(const QString& callId, const QString& confId)
|
||||||
{
|
{
|
||||||
|
@ -511,8 +496,6 @@ CallAdapter::updateCall(const QString& convUid, const QString& accountId, bool f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCallOverlay(convInfo);
|
|
||||||
updateRecordingPeers(true);
|
|
||||||
participantsModel_->setParticipants(call->id, getConferencesInfos());
|
participantsModel_->setParticipants(call->id, getConferencesInfos());
|
||||||
participantsModel_->setConferenceLayout(static_cast<int>(call->layout), call->id);
|
participantsModel_->setConferenceLayout(static_cast<int>(call->layout), call->id);
|
||||||
}
|
}
|
||||||
|
@ -569,7 +552,6 @@ CallAdapter::getConferencesInfos() const
|
||||||
.getAccountInfo(accountId_)
|
.getAccountInfo(accountId_)
|
||||||
.callModel.get()
|
.callModel.get()
|
||||||
->getParticipantsInfos(callId);
|
->getParticipantsInfos(callId);
|
||||||
int index = 0;
|
|
||||||
for (int index = 0; index < participantsModel.getParticipants().size(); index++) {
|
for (int index = 0; index < participantsModel.getParticipants().size(); index++) {
|
||||||
auto participant = participantsModel.toQJsonObject(index);
|
auto participant = participantsModel.toQJsonObject(index);
|
||||||
fillParticipantData(participant);
|
fillParticipantData(participant);
|
||||||
|
@ -642,12 +624,6 @@ CallAdapter::connectCallModel(const QString& accountId)
|
||||||
QOverload<const QString&, int>::of(&CallAdapter::onCallStatusChanged),
|
QOverload<const QString&, int>::of(&CallAdapter::onCallStatusChanged),
|
||||||
Qt::UniqueConnection);
|
Qt::UniqueConnection);
|
||||||
|
|
||||||
connect(accInfo.callModel.get(),
|
|
||||||
&CallModel::remoteRecordingChanged,
|
|
||||||
this,
|
|
||||||
&CallAdapter::onRemoteRecordingChanged,
|
|
||||||
Qt::UniqueConnection);
|
|
||||||
|
|
||||||
connect(accInfo.callModel.get(),
|
connect(accInfo.callModel.get(),
|
||||||
&CallModel::callAddedToConference,
|
&CallModel::callAddedToConference,
|
||||||
this,
|
this,
|
||||||
|
@ -660,32 +636,6 @@ CallAdapter::connectCallModel(const QString& accountId)
|
||||||
QOverload<const QString&, const QString&>::of(&CallAdapter::onCallInfosChanged));
|
QOverload<const QString&, const QString&>::of(&CallAdapter::onCallInfosChanged));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CallAdapter::updateRecordingPeers(bool eraseLabelOnEmpty)
|
|
||||||
{
|
|
||||||
const auto& convInfo = lrcInstance_->getConversationFromConvUid(
|
|
||||||
lrcInstance_->get_selectedConvUid());
|
|
||||||
auto* call = lrcInstance_->getCallInfoForConversation(convInfo);
|
|
||||||
if (!call) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
|
||||||
QStringList peers {};
|
|
||||||
for (const auto& uri : call->peerRec) {
|
|
||||||
auto bestName = accInfo.contactModel->bestNameForContact(uri);
|
|
||||||
if (!bestName.isEmpty()) {
|
|
||||||
peers.append(bestName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!peers.isEmpty())
|
|
||||||
Q_EMIT remoteRecordingChanged(peers, true);
|
|
||||||
else if (eraseLabelOnEmpty)
|
|
||||||
Q_EMIT eraseRemoteRecording();
|
|
||||||
else
|
|
||||||
Q_EMIT remoteRecordingChanged(peers, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallAdapter::sipInputPanelPlayDTMF(const QString& key)
|
CallAdapter::sipInputPanelPlayDTMF(const QString& key)
|
||||||
{
|
{
|
||||||
|
@ -698,49 +648,6 @@ CallAdapter::sipInputPanelPlayDTMF(const QString& key)
|
||||||
lrcInstance_->getCurrentCallModel()->playDTMF(callId, key);
|
lrcInstance_->getCurrentCallModel()->playDTMF(callId, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* For Call Overlay
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
CallAdapter::updateCallOverlay(const lrc::api::conversation::Info& convInfo)
|
|
||||||
{
|
|
||||||
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
|
|
||||||
auto* callModel = accInfo.callModel.get();
|
|
||||||
|
|
||||||
const auto* callInfo = lrcInstance_->getCallInfoForConversation(convInfo);
|
|
||||||
const auto currentCallId = lrcInstance_->getCurrentCallId();
|
|
||||||
if (!callInfo || callInfo->id != currentCallId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool isPaused = callInfo->status == lrc::api::call::Status::PAUSED;
|
|
||||||
bool isAudioOnly = callInfo->isAudioOnly && !isPaused;
|
|
||||||
bool isAudioMuted = callInfo->status == lrc::api::call::Status::PAUSED;
|
|
||||||
bool isGrid = callInfo->layout == lrc::api::call::Layout::GRID;
|
|
||||||
QString previewId {};
|
|
||||||
if (callInfo->status != lrc::api::call::Status::ENDED) {
|
|
||||||
for (const auto& media : callInfo->mediaList) {
|
|
||||||
if (media[libjami::Media::MediaAttributeKey::MEDIA_TYPE]
|
|
||||||
== libjami::Media::Details::MEDIA_TYPE_VIDEO) {
|
|
||||||
if (media[libjami::Media::MediaAttributeKey::ENABLED] == TRUE_STR
|
|
||||||
&& media[libjami::Media::MediaAttributeKey::MUTED] == FALSE_STR) {
|
|
||||||
if (previewId.isEmpty()) {
|
|
||||||
previewId = media[libjami::Media::MediaAttributeKey::SOURCE];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (media[libjami::Media::MediaAttributeKey::LABEL] == "audio_0") {
|
|
||||||
isAudioMuted |= media[libjami::Media::MediaAttributeKey::MUTED] == TRUE_STR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT updateOverlay(isPaused,
|
|
||||||
isAudioOnly,
|
|
||||||
isAudioMuted,
|
|
||||||
accInfo.profileInfo.type == lrc::api::profile::Type::SIP,
|
|
||||||
isGrid,
|
|
||||||
previewId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallAdapter::saveConferenceSubcalls()
|
CallAdapter::saveConferenceSubcalls()
|
||||||
{
|
{
|
||||||
|
@ -1075,7 +982,6 @@ CallAdapter::holdThisCallToggle()
|
||||||
if (callModel->hasCall(callId)) {
|
if (callModel->hasCall(callId)) {
|
||||||
callModel->togglePause(callId);
|
callModel->togglePause(callId);
|
||||||
}
|
}
|
||||||
Q_EMIT showOnHoldLabel(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -100,15 +100,6 @@ Q_SIGNALS:
|
||||||
|
|
||||||
// For Call Overlay
|
// For Call Overlay
|
||||||
void updateTimeText(const QString& time);
|
void updateTimeText(const QString& time);
|
||||||
void showOnHoldLabel(bool isPaused);
|
|
||||||
void updateOverlay(bool isPaused,
|
|
||||||
bool isAudioOnly,
|
|
||||||
bool isAudioMuted,
|
|
||||||
bool isSIP,
|
|
||||||
bool isGrid,
|
|
||||||
const QString& previewId);
|
|
||||||
void remoteRecordingChanged(const QStringList& peers, bool state);
|
|
||||||
void eraseRemoteRecording();
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onShowIncomingCallView(const QString& accountId, const QString& convUid);
|
void onShowIncomingCallView(const QString& accountId, const QString& convUid);
|
||||||
|
@ -117,18 +108,15 @@ public Q_SLOTS:
|
||||||
void onCallStatusChanged(const QString& accountId, const QString& callId);
|
void onCallStatusChanged(const QString& accountId, const QString& callId);
|
||||||
void onCallInfosChanged(const QString& accountId, const QString& callId);
|
void onCallInfosChanged(const QString& accountId, const QString& callId);
|
||||||
void onCallStatusChanged(const QString& callId, int code);
|
void onCallStatusChanged(const QString& callId, int code);
|
||||||
void onRemoteRecordingChanged(const QString& callId, const QSet<QString>& peerRec, bool state);
|
|
||||||
void onCallAddedToConference(const QString& callId, const QString& confId);
|
void onCallAddedToConference(const QString& callId, const QString& confId);
|
||||||
void onParticipantAdded(const QString& callId, int index);
|
void onParticipantAdded(const QString& callId, int index);
|
||||||
void onParticipantRemoved(const QString& callId, int index);
|
void onParticipantRemoved(const QString& callId, int index);
|
||||||
void onParticipantUpdated(const QString& callId, int index);
|
void onParticipantUpdated(const QString& callId, int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateRecordingPeers(bool eraseLabelOnEmpty = false);
|
|
||||||
void showNotification(const QString& accountId, const QString& convUid);
|
void showNotification(const QString& accountId, const QString& convUid);
|
||||||
void fillParticipantData(QJsonObject& participant) const;
|
void fillParticipantData(QJsonObject& participant) const;
|
||||||
void preventScreenSaver(bool state);
|
void preventScreenSaver(bool state);
|
||||||
void updateCallOverlay(const lrc::api::conversation::Info& convInfo);
|
|
||||||
void saveConferenceSubcalls();
|
void saveConferenceSubcalls();
|
||||||
|
|
||||||
QString accountId_;
|
QString accountId_;
|
||||||
|
|
308
src/app/currentcall.cpp
Normal file
308
src/app/currentcall.cpp
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "currentcall.h"
|
||||||
|
|
||||||
|
#include <api/callparticipantsmodel.h>
|
||||||
|
|
||||||
|
CurrentCall::CurrentCall(LRCInstance* lrcInstance, QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, lrcInstance_(lrcInstance)
|
||||||
|
{
|
||||||
|
connect(lrcInstance_,
|
||||||
|
&LRCInstance::currentAccountIdChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onCurrentAccountIdChanged);
|
||||||
|
|
||||||
|
connect(lrcInstance_,
|
||||||
|
&LRCInstance::selectedConvUidChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onCurrentConvIdChanged);
|
||||||
|
|
||||||
|
connectModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::updateId(QString callId)
|
||||||
|
{
|
||||||
|
auto convId = lrcInstance_->get_selectedConvUid();
|
||||||
|
auto optConv = lrcInstance_->getCurrentConversationModel()->getConversationForUid(convId);
|
||||||
|
if (!optConv.has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the optional parameter callId is empty, then we've just
|
||||||
|
// changed conversation selection and need to check the current
|
||||||
|
// conv's callId for an existing call.
|
||||||
|
// Otherwise, return if callId doesn't belong to this conversation.
|
||||||
|
if (callId.isEmpty()) {
|
||||||
|
callId = optConv->get().getCallId();
|
||||||
|
} else if (optConv->get().getCallId() != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the current id_ if there is a call.
|
||||||
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
||||||
|
if (accInfo.callModel->hasCall(callId)) {
|
||||||
|
set_id(callId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::updateCallStatus()
|
||||||
|
{
|
||||||
|
call::Status status {};
|
||||||
|
auto callModel = lrcInstance_->getCurrentCallModel();
|
||||||
|
if (callModel->hasCall(id_)) {
|
||||||
|
auto callInfo = callModel->getCall(id_);
|
||||||
|
status = callInfo.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_status(status);
|
||||||
|
set_isActive(status_ == call::Status::CONNECTED || status_ == call::Status::IN_PROGRESS
|
||||||
|
|| status_ == call::Status::PAUSED);
|
||||||
|
set_isPaused(status_ == call::Status::PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::updateParticipants()
|
||||||
|
{
|
||||||
|
auto callModel = lrcInstance_->getCurrentCallModel();
|
||||||
|
QStringList uris;
|
||||||
|
auto& participantsModel = callModel->getParticipantsInfos(id_);
|
||||||
|
for (int index = 0; index < participantsModel.getParticipants().size(); index++) {
|
||||||
|
auto participantInfo = participantsModel.toQJsonObject(index);
|
||||||
|
uris.append(participantInfo[ParticipantsInfosStrings::URI].toString());
|
||||||
|
}
|
||||||
|
set_uris(uris);
|
||||||
|
set_isConference(uris.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::updateCallInfo()
|
||||||
|
{
|
||||||
|
auto callModel = lrcInstance_->getCurrentCallModel();
|
||||||
|
if (!callModel->hasCall(id_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto callInfo = callModel->getCall(id_);
|
||||||
|
|
||||||
|
set_isGrid(callInfo.layout == call::Layout::GRID);
|
||||||
|
set_isAudioOnly(callInfo.isAudioOnly);
|
||||||
|
|
||||||
|
bool isAudioMuted {};
|
||||||
|
bool isVideoMuted {};
|
||||||
|
bool isSharing {};
|
||||||
|
bool isCapturing {};
|
||||||
|
QString previewId {};
|
||||||
|
using namespace libjami::Media;
|
||||||
|
if (callInfo.status != lrc::api::call::Status::ENDED) {
|
||||||
|
for (const auto& media : callInfo.mediaList) {
|
||||||
|
if (media[MediaAttributeKey::MEDIA_TYPE] == Details::MEDIA_TYPE_VIDEO) {
|
||||||
|
if (media[MediaAttributeKey::SOURCE].startsWith(VideoProtocolPrefix::DISPLAY)
|
||||||
|
|| media[MediaAttributeKey::SOURCE].startsWith(VideoProtocolPrefix::FILE)) {
|
||||||
|
isSharing = true;
|
||||||
|
}
|
||||||
|
if (media[MediaAttributeKey::ENABLED] == TRUE_STR
|
||||||
|
&& media[MediaAttributeKey::MUTED] == FALSE_STR && previewId.isEmpty()) {
|
||||||
|
previewId = media[libjami::Media::MediaAttributeKey::SOURCE];
|
||||||
|
}
|
||||||
|
if (media[libjami::Media::MediaAttributeKey::SOURCE].startsWith(
|
||||||
|
libjami::Media::VideoProtocolPrefix::CAMERA)) {
|
||||||
|
isVideoMuted |= media[MediaAttributeKey::MUTED] == TRUE_STR;
|
||||||
|
isCapturing = media[MediaAttributeKey::MUTED] == FALSE_STR;
|
||||||
|
}
|
||||||
|
} else if (media[MediaAttributeKey::MEDIA_TYPE] == Details::MEDIA_TYPE_AUDIO) {
|
||||||
|
if (media[MediaAttributeKey::LABEL] == "audio_0") {
|
||||||
|
isAudioMuted |= media[libjami::Media::MediaAttributeKey::MUTED] == TRUE_STR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_previewId(previewId);
|
||||||
|
set_isAudioMuted(isAudioMuted);
|
||||||
|
set_isVideoMuted(isVideoMuted);
|
||||||
|
set_isSharing(isSharing);
|
||||||
|
set_isCapturing(isCapturing);
|
||||||
|
set_isHandRaised(callModel->isHandRaised(id_));
|
||||||
|
set_isModerator(callModel->isModerator(id_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::updateRemoteRecorders(const QStringList& recorders)
|
||||||
|
{
|
||||||
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
||||||
|
remoteRecorderNameList_.clear();
|
||||||
|
Q_FOREACH (const auto& uri, recorders) {
|
||||||
|
auto bestName = accInfo.contactModel->bestNameForContact(uri);
|
||||||
|
if (!bestName.isEmpty()) {
|
||||||
|
remoteRecorderNameList_.append(bestName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience flag.
|
||||||
|
set_isRecordingRemotely(!remoteRecorderNameList_.isEmpty());
|
||||||
|
|
||||||
|
Q_EMIT remoteRecorderNameListChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::updateRecordingState(bool state)
|
||||||
|
{
|
||||||
|
set_isRecordingLocally(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::connectModel()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::callStatusChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onCallStatusChanged,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::callInfosChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onCallInfosChanged,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::currentCallChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onCurrentCallChanged,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::participantsChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onParticipantsChanged,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::remoteRecordersChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onRemoteRecordersChanged,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::recordingStateChanged,
|
||||||
|
this,
|
||||||
|
&CurrentCall::onRecordingStateChanged,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
qWarning() << "Exception getting account info." << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onCurrentConvIdChanged()
|
||||||
|
{
|
||||||
|
updateId();
|
||||||
|
updateCallStatus();
|
||||||
|
updateParticipants();
|
||||||
|
updateCallInfo();
|
||||||
|
|
||||||
|
auto callModel = lrcInstance_->getCurrentCallModel();
|
||||||
|
QStringList recorders {};
|
||||||
|
if (callModel->hasCall(id_)) {
|
||||||
|
auto callInfo = callModel->getCall(id_);
|
||||||
|
recorders = callInfo.recordingPeers;
|
||||||
|
}
|
||||||
|
updateRecordingState(callModel->isRecording(id_));
|
||||||
|
updateRemoteRecorders(recorders);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onCurrentAccountIdChanged()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
||||||
|
set_isSIP(accInfo.profileInfo.type == profile::Type::SIP);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
qWarning() << "Can't update current call type" << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
connectModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onCallStatusChanged(const QString& callId, int code)
|
||||||
|
{
|
||||||
|
Q_UNUSED(code)
|
||||||
|
|
||||||
|
if (id_ != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCallStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onCallInfosChanged(const QString& accountId, const QString& callId)
|
||||||
|
{
|
||||||
|
if (id_ != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCallInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onCurrentCallChanged(const QString& callId)
|
||||||
|
{
|
||||||
|
// If this status change's callId is not the current, it's possible that
|
||||||
|
// the current value of id_ is stale, and needs to be updated after checking
|
||||||
|
// the current conversation's getCallId(). Other slots need not do this, as the
|
||||||
|
// id_ is updated here.
|
||||||
|
if (id_ == callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateId(callId);
|
||||||
|
updateCallStatus();
|
||||||
|
updateParticipants();
|
||||||
|
updateCallInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onParticipantsChanged(const QString& callId)
|
||||||
|
{
|
||||||
|
if (id_ != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateParticipants();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onRemoteRecordersChanged(const QString& callId, const QStringList& recorders)
|
||||||
|
{
|
||||||
|
if (id_ != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRemoteRecorders(recorders);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CurrentCall::onRecordingStateChanged(const QString& callId, bool state)
|
||||||
|
{
|
||||||
|
if (id_ != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRecordingState(state);
|
||||||
|
}
|
75
src/app/currentcall.h
Normal file
75
src/app/currentcall.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lrcinstance.h"
|
||||||
|
#include "qtutils.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class CurrentCall final : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QML_RO_PROPERTY(QString, id)
|
||||||
|
QML_RO_PROPERTY(QStringList, uris)
|
||||||
|
QML_RO_PROPERTY(bool, isAudioOnly)
|
||||||
|
QML_RO_PROPERTY(bool, isSIP)
|
||||||
|
QML_RO_PROPERTY(bool, isGrid)
|
||||||
|
QML_RO_PROPERTY(call::Status, status)
|
||||||
|
QML_RO_PROPERTY(bool, isActive)
|
||||||
|
QML_RO_PROPERTY(bool, isPaused)
|
||||||
|
QML_RO_PROPERTY(bool, isAudioMuted)
|
||||||
|
QML_RO_PROPERTY(bool, isCapturing)
|
||||||
|
QML_RO_PROPERTY(bool, isVideoMuted)
|
||||||
|
QML_RO_PROPERTY(QString, previewId)
|
||||||
|
QML_RO_PROPERTY(bool, isRecordingLocally)
|
||||||
|
QML_RO_PROPERTY(bool, isRecordingRemotely)
|
||||||
|
QML_RO_PROPERTY(QStringList, remoteRecorderNameList)
|
||||||
|
QML_RO_PROPERTY(bool, isSharing)
|
||||||
|
QML_RO_PROPERTY(bool, isHandRaised)
|
||||||
|
QML_RO_PROPERTY(bool, isConference)
|
||||||
|
QML_RO_PROPERTY(bool, isModerator)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CurrentCall(LRCInstance* lrcInstance, QObject* parent = nullptr);
|
||||||
|
~CurrentCall() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateId(QString callId = {});
|
||||||
|
void updateCallStatus();
|
||||||
|
void updateParticipants();
|
||||||
|
void updateCallInfo();
|
||||||
|
void updateRemoteRecorders(const QStringList& recorders);
|
||||||
|
void updateRecordingState(bool state);
|
||||||
|
void connectModel();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onCurrentConvIdChanged();
|
||||||
|
void onCurrentAccountIdChanged();
|
||||||
|
void onCallStatusChanged(const QString& callId, int code);
|
||||||
|
void onCallInfosChanged(const QString& accountId, const QString& callId);
|
||||||
|
void onCurrentCallChanged(const QString& callId);
|
||||||
|
void onParticipantsChanged(const QString& callId);
|
||||||
|
void onRemoteRecordersChanged(const QString& callId, const QStringList& recorders);
|
||||||
|
void onRecordingStateChanged(const QString& callId, bool state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LRCInstance* lrcInstance_;
|
||||||
|
};
|
|
@ -186,7 +186,6 @@ Rectangle {
|
||||||
callStackView.setLinkedWebview(chatView)
|
callStackView.setLinkedWebview(chatView)
|
||||||
callStackView.responsibleAccountId = LRCInstance.currentAccountId
|
callStackView.responsibleAccountId = LRCInstance.currentAccountId
|
||||||
callStackView.responsibleConvUid = convId
|
callStackView.responsibleConvUid = convId
|
||||||
callStackView.isAudioOnly = item.isAudioOnly
|
|
||||||
currentConvUID = convId
|
currentConvUID = convId
|
||||||
|
|
||||||
if (item.callState === Call.Status.IN_PROGRESS ||
|
if (item.callState === Call.Status.IN_PROGRESS ||
|
||||||
|
|
|
@ -162,7 +162,7 @@ Control {
|
||||||
layoutModel.get(index).ActiveSetting = layoutManager.isCallFullscreen
|
layoutModel.get(index).ActiveSetting = layoutManager.isCallFullscreen
|
||||||
break
|
break
|
||||||
case JamiStrings.mosaic:
|
case JamiStrings.mosaic:
|
||||||
if (!isGrid)
|
if (!CurrentCall.isGrid)
|
||||||
CallAdapter.showGridConferenceLayout()
|
CallAdapter.showGridConferenceLayout()
|
||||||
break
|
break
|
||||||
case JamiStrings.participantsSide:
|
case JamiStrings.participantsSide:
|
||||||
|
@ -189,10 +189,10 @@ Control {
|
||||||
}
|
}
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
layoutModel.clear()
|
layoutModel.clear()
|
||||||
if (isConference) {
|
if (CurrentCall.isConference) {
|
||||||
layoutModel.append({"Name": JamiStrings.mosaic,
|
layoutModel.append({"Name": JamiStrings.mosaic,
|
||||||
"IconSource": JamiResources.mosaic_black_24dp_svg,
|
"IconSource": JamiResources.mosaic_black_24dp_svg,
|
||||||
"ActiveSetting": isGrid,
|
"ActiveSetting": CurrentCall.isGrid,
|
||||||
"TopMargin": true,
|
"TopMargin": true,
|
||||||
"BottomMargin": true,
|
"BottomMargin": true,
|
||||||
"SectionEnd": true})
|
"SectionEnd": true})
|
||||||
|
@ -223,8 +223,8 @@ Control {
|
||||||
"ActiveSetting": layoutManager.isCallFullscreen,
|
"ActiveSetting": layoutManager.isCallFullscreen,
|
||||||
"TopMargin": true,
|
"TopMargin": true,
|
||||||
"BottomMargin": true,
|
"BottomMargin": true,
|
||||||
"SectionEnd": isConference})
|
"SectionEnd": CurrentCall.isConference})
|
||||||
if (isConference) {
|
if (CurrentCall.isConference) {
|
||||||
layoutModel.append({"Name": JamiStrings.hideSpectators,
|
layoutModel.append({"Name": JamiStrings.hideSpectators,
|
||||||
"IconSource": JamiResources.videocam_off_24dp_svg,
|
"IconSource": JamiResources.videocam_off_24dp_svg,
|
||||||
"ActiveSetting": UtilsAdapter.getAppValue(Settings.HideSpectators),
|
"ActiveSetting": UtilsAdapter.getAppValue(Settings.HideSpectators),
|
||||||
|
@ -263,6 +263,7 @@ Control {
|
||||||
JamiResources.micro_black_24dp_svg
|
JamiResources.micro_black_24dp_svg
|
||||||
icon.color: checked ? "red" : "white"
|
icon.color: checked ? "red" : "white"
|
||||||
text: !checked ? JamiStrings.mute : JamiStrings.unmute
|
text: !checked ? JamiStrings.mute : JamiStrings.unmute
|
||||||
|
checked: CurrentCall.isAudioMuted
|
||||||
property var menuAction: audioInputMenuAction
|
property var menuAction: audioInputMenuAction
|
||||||
},
|
},
|
||||||
Action {
|
Action {
|
||||||
|
@ -282,6 +283,7 @@ Control {
|
||||||
JamiResources.videocam_24dp_svg
|
JamiResources.videocam_24dp_svg
|
||||||
icon.color: checked ? "red" : "white"
|
icon.color: checked ? "red" : "white"
|
||||||
text: !checked ? JamiStrings.muteCamera : JamiStrings.unmuteCamera
|
text: !checked ? JamiStrings.muteCamera : JamiStrings.unmuteCamera
|
||||||
|
checked: !CurrentCall.isCapturing
|
||||||
property var menuAction: videoInputMenuAction
|
property var menuAction: videoInputMenuAction
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -314,11 +316,13 @@ Control {
|
||||||
Action {
|
Action {
|
||||||
id: resumePauseCallAction
|
id: resumePauseCallAction
|
||||||
onTriggered: root.resumePauseCallClicked()
|
onTriggered: root.resumePauseCallClicked()
|
||||||
icon.source: isPaused ?
|
icon.source: CurrentCall.isPaused ?
|
||||||
JamiResources.play_circle_outline_24dp_svg :
|
JamiResources.play_circle_outline_24dp_svg :
|
||||||
JamiResources.pause_circle_outline_24dp_svg
|
JamiResources.pause_circle_outline_24dp_svg
|
||||||
icon.color: "white"
|
icon.color: "white"
|
||||||
text: isPaused ? JamiStrings.resumeCall : JamiStrings.pauseCall
|
text: CurrentCall.isPaused ?
|
||||||
|
JamiStrings.resumeCall :
|
||||||
|
JamiStrings.pauseCall
|
||||||
},
|
},
|
||||||
Action {
|
Action {
|
||||||
id: inputPanelSIPAction
|
id: inputPanelSIPAction
|
||||||
|
@ -337,17 +341,17 @@ Control {
|
||||||
Action {
|
Action {
|
||||||
id: shareAction
|
id: shareAction
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (sharingActive)
|
if (CurrentCall.isSharing)
|
||||||
root.stopSharingClicked()
|
root.stopSharingClicked()
|
||||||
else
|
else
|
||||||
root.shareScreenClicked()
|
root.shareScreenClicked()
|
||||||
}
|
}
|
||||||
icon.source: sharingActive ?
|
icon.source: CurrentCall.isSharing ?
|
||||||
JamiResources.share_stop_black_24dp_svg :
|
JamiResources.share_stop_black_24dp_svg :
|
||||||
JamiResources.share_screen_black_24dp_svg
|
JamiResources.share_screen_black_24dp_svg
|
||||||
icon.color: sharingActive ?
|
icon.color: CurrentCall.isSharing ?
|
||||||
"red" : "white"
|
"red" : "white"
|
||||||
text: sharingActive ?
|
text: CurrentCall.isSharing ?
|
||||||
JamiStrings.stopSharing :
|
JamiStrings.stopSharing :
|
||||||
JamiStrings.shareScreen
|
JamiStrings.shareScreen
|
||||||
property real size: 34
|
property real size: 34
|
||||||
|
@ -362,12 +366,13 @@ Control {
|
||||||
text: checked ?
|
text: checked ?
|
||||||
JamiStrings.lowerHand :
|
JamiStrings.lowerHand :
|
||||||
JamiStrings.raiseHand
|
JamiStrings.raiseHand
|
||||||
|
checked: CurrentCall.isHandRaised
|
||||||
property real size: 34
|
property real size: 34
|
||||||
},
|
},
|
||||||
Action {
|
Action {
|
||||||
id: layoutAction
|
id: layoutAction
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (!isGrid)
|
if (!CurrentCall.isGrid)
|
||||||
CallAdapter.showGridConferenceLayout()
|
CallAdapter.showGridConferenceLayout()
|
||||||
}
|
}
|
||||||
checkable: true
|
checkable: true
|
||||||
|
@ -386,6 +391,7 @@ Control {
|
||||||
text: !checked ? JamiStrings.startRec : JamiStrings.stopRec
|
text: !checked ? JamiStrings.startRec : JamiStrings.stopRec
|
||||||
property bool blinksWhenChecked: true
|
property bool blinksWhenChecked: true
|
||||||
property real size: 28
|
property real size: 28
|
||||||
|
checked: CurrentCall.isRecordingLocally
|
||||||
onCheckedChanged: function(checked) {
|
onCheckedChanged: function(checked) {
|
||||||
CallOverlayModel.setUrgentCount(recordAction,
|
CallOverlayModel.setUrgentCount(recordAction,
|
||||||
checked ? -1 : 0)
|
checked ? -1 : 0)
|
||||||
|
@ -397,27 +403,29 @@ Control {
|
||||||
icon.source: JamiResources.plugins_24dp_svg
|
icon.source: JamiResources.plugins_24dp_svg
|
||||||
icon.color: "white"
|
icon.color: "white"
|
||||||
text: JamiStrings.viewPlugin
|
text: JamiStrings.viewPlugin
|
||||||
enabled: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
|
enabled: PluginAdapter.isEnabled
|
||||||
|
&& PluginAdapter.callMediaHandlersListCount
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
property var overflowItemCount
|
property var overflowItemCount
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: callOverlay
|
target: CurrentCall
|
||||||
|
|
||||||
function onIsAudioOnlyChanged() { Qt.callLater(reset) }
|
function onIsActiveChanged() { if (CurrentCall.isActive) reset() }
|
||||||
function onIsSIPChanged() { Qt.callLater(reset) }
|
function onIsRecordingLocallyChanged() { Qt.callLater(reset) }
|
||||||
|
function onIsHandRaisedChanged() { Qt.callLater(reset) }
|
||||||
|
function onIsConferenceChanged() { Qt.callLater(reset) }
|
||||||
function onIsModeratorChanged() { Qt.callLater(reset) }
|
function onIsModeratorChanged() { Qt.callLater(reset) }
|
||||||
|
function onIsSIPChanged() { Qt.callLater(reset) }
|
||||||
|
function onIsAudioOnlyChanged() { Qt.callLater(reset) }
|
||||||
function onIsAudioMutedChanged() { Qt.callLater(reset) }
|
function onIsAudioMutedChanged() { Qt.callLater(reset) }
|
||||||
function onIsVideoMutedChanged() { Qt.callLater(reset) }
|
function onIsVideoMutedChanged() { Qt.callLater(reset) }
|
||||||
function onIsRecordingChanged() { Qt.callLater(reset) }
|
|
||||||
function onLocalHandRaisedChanged() { Qt.callLater(reset) }
|
|
||||||
function onIsConferenceChanged() { Qt.callLater(reset) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: CurrentAccount
|
target: CurrentAccount
|
||||||
|
|
||||||
function onVideoEnabledVideoChanged() { reset() }
|
function onVideoEnabledVideoChanged() { reset() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,29 +441,24 @@ Control {
|
||||||
|
|
||||||
// overflow controls
|
// overflow controls
|
||||||
CallOverlayModel.addSecondaryControl(audioOutputAction)
|
CallOverlayModel.addSecondaryControl(audioOutputAction)
|
||||||
if (isConference) {
|
if (CurrentCall.isConference) {
|
||||||
CallOverlayModel.addSecondaryControl(raiseHandAction)
|
CallOverlayModel.addSecondaryControl(raiseHandAction)
|
||||||
raiseHandAction.checked = CallAdapter.isHandRaised()
|
|
||||||
}
|
}
|
||||||
if (isModerator && !isSIP)
|
if (CurrentCall.isModerator && !CurrentCall.isSIP)
|
||||||
CallOverlayModel.addSecondaryControl(addPersonAction)
|
CallOverlayModel.addSecondaryControl(addPersonAction)
|
||||||
if (isSIP) {
|
if (CurrentCall.isSIP) {
|
||||||
CallOverlayModel.addSecondaryControl(resumePauseCallAction)
|
CallOverlayModel.addSecondaryControl(resumePauseCallAction)
|
||||||
CallOverlayModel.addSecondaryControl(inputPanelSIPAction)
|
CallOverlayModel.addSecondaryControl(inputPanelSIPAction)
|
||||||
CallOverlayModel.addSecondaryControl(callTransferAction)
|
CallOverlayModel.addSecondaryControl(callTransferAction)
|
||||||
}
|
}
|
||||||
CallOverlayModel.addSecondaryControl(chatAction)
|
CallOverlayModel.addSecondaryControl(chatAction)
|
||||||
if (CurrentAccount.videoEnabled_Video)
|
if (CurrentAccount.videoEnabled_Video && !CurrentCall.isSIP)
|
||||||
CallOverlayModel.addSecondaryControl(shareAction)
|
CallOverlayModel.addSecondaryControl(shareAction)
|
||||||
CallOverlayModel.addSecondaryControl(layoutAction)
|
CallOverlayModel.addSecondaryControl(layoutAction)
|
||||||
CallOverlayModel.addSecondaryControl(recordAction)
|
CallOverlayModel.addSecondaryControl(recordAction)
|
||||||
if (pluginsAction.enabled)
|
if (pluginsAction.enabled)
|
||||||
CallOverlayModel.addSecondaryControl(pluginsAction)
|
CallOverlayModel.addSecondaryControl(pluginsAction)
|
||||||
overflowItemCount = CallOverlayModel.secondaryModel().rowCount()
|
overflowItemCount = CallOverlayModel.secondaryModel().rowCount()
|
||||||
|
|
||||||
muteAudioAction.checked = isAudioMuted
|
|
||||||
recordAction.checked = CallAdapter.isRecordingThisCall()
|
|
||||||
muteVideoAction.checked = isAudioOnly ? true : isVideoMuted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
|
@ -39,6 +39,7 @@ ItemDelegate {
|
||||||
|
|
||||||
action: ItemAction
|
action: ItemAction
|
||||||
checkable: ItemAction.checkable
|
checkable: ItemAction.checkable
|
||||||
|
hoverEnabled: ItemAction.enabled
|
||||||
|
|
||||||
// hide the action's visual elements like the blurry looking icon
|
// hide the action's visual elements like the blurry looking icon
|
||||||
icon.source: ""
|
icon.source: ""
|
||||||
|
@ -122,7 +123,11 @@ ItemDelegate {
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: ItemAction ? ItemAction.icon.source : ""
|
source: ItemAction ? ItemAction.icon.source : ""
|
||||||
color: ItemAction ? ItemAction.icon.color : null
|
color: ItemAction ?
|
||||||
|
(ItemAction.enabled ?
|
||||||
|
ItemAction.icon.color :
|
||||||
|
Qt.lighter(ItemAction.icon.color)) :
|
||||||
|
null
|
||||||
|
|
||||||
SequentialAnimation on opacity {
|
SequentialAnimation on opacity {
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
|
@ -172,7 +177,8 @@ ItemDelegate {
|
||||||
|
|
||||||
indicator: null
|
indicator: null
|
||||||
|
|
||||||
visible: menuAction !== undefined && !UrgentCount && menuAction.enabled
|
visible: ItemAction.enabled
|
||||||
|
&& menuAction !== undefined && !UrgentCount && menuAction.enabled
|
||||||
|
|
||||||
y: isVertical ? 0 : -4
|
y: isVertical ? 0 : -4
|
||||||
x: isVertical ? -4 : 0
|
x: isVertical ? -4 : 0
|
||||||
|
|
|
@ -35,48 +35,11 @@ import "../../commoncomponents"
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isPaused
|
|
||||||
property bool isAudioOnly
|
|
||||||
property bool isAudioMuted
|
|
||||||
property bool isVideoMuted
|
|
||||||
property bool isRecording
|
|
||||||
property bool remoteRecording
|
|
||||||
property bool isSIP
|
|
||||||
property bool isModerator
|
|
||||||
property bool isConference
|
|
||||||
property bool isGrid
|
|
||||||
property bool participantsSide: UtilsAdapter.getAppValue(Settings.ParticipantsSide)
|
property bool participantsSide: UtilsAdapter.getAppValue(Settings.ParticipantsSide)
|
||||||
property bool localHandRaised
|
|
||||||
property bool sharingActive: AvAdapter.isSharing()
|
|
||||||
property string callId: ""
|
|
||||||
|
|
||||||
signal chatButtonClicked
|
signal chatButtonClicked
|
||||||
signal fullScreenClicked
|
signal fullScreenClicked
|
||||||
|
|
||||||
function setRecording(localIsRecording) {
|
|
||||||
callViewContextMenu.localIsRecording = localIsRecording
|
|
||||||
mainOverlay.recordingVisible = localIsRecording
|
|
||||||
|| callViewContextMenu.peerIsRecording
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateUI(isPaused, isAudioOnly, isAudioMuted, isSIP, isGrid) {
|
|
||||||
if (isPaused !== undefined) {
|
|
||||||
root.isPaused = isPaused
|
|
||||||
root.isAudioOnly = isAudioOnly
|
|
||||||
root.isAudioMuted = isAudioMuted
|
|
||||||
callViewContextMenu.isVideoMuted = root.isVideoMuted
|
|
||||||
root.isSIP = isSIP
|
|
||||||
root.isGrid = isGrid
|
|
||||||
root.localHandRaised = CallAdapter.isHandRaised()
|
|
||||||
}
|
|
||||||
root.isRecording = CallAdapter.isRecordingThisCall()
|
|
||||||
root.isModerator = CallAdapter.isModerator()
|
|
||||||
}
|
|
||||||
|
|
||||||
function showOnHoldImage(visible) {
|
|
||||||
onHoldImage.visible = visible
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeContextMenuAndRelatedWindows() {
|
function closeContextMenuAndRelatedWindows() {
|
||||||
ContactPickerCreation.closeContactPicker()
|
ContactPickerCreation.closeContactPicker()
|
||||||
sipInputPanel.close()
|
sipInputPanel.close()
|
||||||
|
@ -94,29 +57,6 @@ Item {
|
||||||
callViewContextMenu.openMenu()
|
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
mainOverlay.remoteRecordingLabel = state ? label : JamiStrings.peerStoppedRecording
|
|
||||||
root.remoteRecording = state
|
|
||||||
callOverlayRectMouseArea.entered()
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetRemoteRecording() {
|
|
||||||
mainOverlay.remoteRecordingLabel = ""
|
|
||||||
root.remoteRecording = false
|
|
||||||
}
|
|
||||||
|
|
||||||
DropArea {
|
DropArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onDropped: function(drop) {
|
onDropped: function(drop) {
|
||||||
|
@ -158,7 +98,7 @@ Item {
|
||||||
width: 200
|
width: 200
|
||||||
height: 200
|
height: 200
|
||||||
|
|
||||||
visible: false
|
visible: CurrentCall.isPaused
|
||||||
|
|
||||||
source: JamiResources.ic_pause_white_100px_svg
|
source: JamiResources.ic_pause_white_100px_svg
|
||||||
}
|
}
|
||||||
|
@ -199,17 +139,10 @@ Item {
|
||||||
PluginHandlerPickerCreation.openPluginHandlerPicker()
|
PluginHandlerPickerCreation.openPluginHandlerPicker()
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordClicked() {
|
|
||||||
CallAdapter.recordThisCallToggle()
|
|
||||||
updateUI()
|
|
||||||
}
|
|
||||||
|
|
||||||
MainOverlay {
|
MainOverlay {
|
||||||
id: mainOverlay
|
id: mainOverlay
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
isRecording: root.isRecording
|
|
||||||
remoteRecording: root.remoteRecording
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: mainOverlay.callActionBar
|
target: mainOverlay.callActionBar
|
||||||
|
@ -222,7 +155,7 @@ Item {
|
||||||
function onShareWindowClicked() { openShareWindow() }
|
function onShareWindowClicked() { openShareWindow() }
|
||||||
function onStopSharingClicked() { AvAdapter.stopSharing() }
|
function onStopSharingClicked() { AvAdapter.stopSharing() }
|
||||||
function onShareScreenAreaClicked() { openShareScreenArea() }
|
function onShareScreenAreaClicked() { openShareScreenArea() }
|
||||||
function onRecordCallClicked() { recordClicked() }
|
function onRecordCallClicked() { CallAdapter.recordThisCallToggle() }
|
||||||
function onShareFileClicked() { jamiFileDialog.open() }
|
function onShareFileClicked() { jamiFileDialog.open() }
|
||||||
function onPluginsClicked() { openPluginsMenu() }
|
function onPluginsClicked() { openPluginsMenu() }
|
||||||
function onFullScreenClicked() { root.fullScreenClicked() }
|
function onFullScreenClicked() { root.fullScreenClicked() }
|
||||||
|
@ -232,13 +165,9 @@ Item {
|
||||||
CallViewContextMenu {
|
CallViewContextMenu {
|
||||||
id: callViewContextMenu
|
id: callViewContextMenu
|
||||||
|
|
||||||
isSIP: root.isSIP
|
|
||||||
isPaused: root.isPaused
|
|
||||||
isRecording: root.isRecording
|
|
||||||
|
|
||||||
onTransferCallButtonClicked: openContactPicker(ContactList.TRANSFER)
|
onTransferCallButtonClicked: openContactPicker(ContactList.TRANSFER)
|
||||||
onPluginItemClicked: openPluginsMenu()
|
onPluginItemClicked: openPluginsMenu()
|
||||||
onRecordCallClicked: root.recordClicked()
|
onRecordCallClicked: CallAdapter.recordThisCallToggle()
|
||||||
onOpenSelectionWindow: {
|
onOpenSelectionWindow: {
|
||||||
SelectScreenWindowCreation.createSelectScreenWindowObject(appWindow)
|
SelectScreenWindowCreation.createSelectScreenWindowObject(appWindow)
|
||||||
SelectScreenWindowCreation.showSelectScreenWindow(callPreviewId, windowSelection)
|
SelectScreenWindowCreation.showSelectScreenWindow(callPreviewId, windowSelection)
|
||||||
|
|
|
@ -28,7 +28,6 @@ import "../../commoncomponents"
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isAudioOnly: false
|
|
||||||
property var sipKeys: [
|
property var sipKeys: [
|
||||||
"1", "2", "3", "A",
|
"1", "2", "3", "A",
|
||||||
"4", "5", "6", "B",
|
"4", "5", "6", "B",
|
||||||
|
@ -123,13 +122,6 @@ Rectangle {
|
||||||
Connections {
|
Connections {
|
||||||
target: CallAdapter
|
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) {
|
function onCallStatusChanged(status, accountId, convUid) {
|
||||||
if (callStackMainView.currentItem.stackNumber === CallStackView.InitialPageStack
|
if (callStackMainView.currentItem.stackNumber === CallStackView.InitialPageStack
|
||||||
&& responsibleConvUid === convUid && responsibleAccountId === accountId) {
|
&& responsibleConvUid === convUid && responsibleAccountId === accountId) {
|
||||||
|
@ -143,8 +135,6 @@ Rectangle {
|
||||||
|
|
||||||
property int stackNumber: CallStackView.OngoingPageStack
|
property int stackNumber: CallStackView.OngoingPageStack
|
||||||
|
|
||||||
isAudioOnly: root.isAudioOnly
|
|
||||||
|
|
||||||
visible: callStackMainView.currentItem.stackNumber === stackNumber
|
visible: callStackMainView.currentItem.stackNumber === stackNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +143,6 @@ Rectangle {
|
||||||
|
|
||||||
property int stackNumber: CallStackView.InitialPageStack
|
property int stackNumber: CallStackView.InitialPageStack
|
||||||
|
|
||||||
isAudioOnly: root.isAudioOnly
|
|
||||||
|
|
||||||
onCallAccepted: {
|
onCallAccepted: {
|
||||||
CallAdapter.acceptACall(responsibleAccountId, responsibleConvUid)
|
CallAdapter.acceptACall(responsibleAccountId, responsibleConvUid)
|
||||||
mainViewSidePanel.selectTab(SidePanelTabBar.Conversations)
|
mainViewSidePanel.selectTab(SidePanelTabBar.Conversations)
|
||||||
|
|
|
@ -31,11 +31,6 @@ import "../js/screenrubberbandcreation.js" as ScreenRubberBandCreation
|
||||||
ContextMenuAutoLoader {
|
ContextMenuAutoLoader {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isSIP: false
|
|
||||||
property bool isPaused: false
|
|
||||||
property bool isVideoMuted: false
|
|
||||||
property bool isRecording: false
|
|
||||||
|
|
||||||
property bool windowSelection: false
|
property bool windowSelection: false
|
||||||
|
|
||||||
signal pluginItemClicked
|
signal pluginItemClicked
|
||||||
|
@ -47,9 +42,11 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: resumePauseCall
|
id: resumePauseCall
|
||||||
|
|
||||||
canTrigger: isSIP
|
canTrigger: CurrentCall.isSIP
|
||||||
itemName: isPaused ? JamiStrings.resumeCall : JamiStrings.pauseCall
|
itemName: CurrentCall.isPaused ?
|
||||||
iconSource: isPaused ?
|
JamiStrings.resumeCall :
|
||||||
|
JamiStrings.pauseCall
|
||||||
|
iconSource: CurrentCall.isPaused ?
|
||||||
JamiResources.play_circle_outline_24dp_svg :
|
JamiResources.play_circle_outline_24dp_svg :
|
||||||
JamiResources.pause_circle_outline_24dp_svg
|
JamiResources.pause_circle_outline_24dp_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -59,7 +56,7 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: inputPanelSIP
|
id: inputPanelSIP
|
||||||
|
|
||||||
canTrigger: isSIP
|
canTrigger: CurrentCall.isSIP
|
||||||
itemName: JamiStrings.sipInputPanel
|
itemName: JamiStrings.sipInputPanel
|
||||||
iconSource: JamiResources.ic_keypad_svg
|
iconSource: JamiResources.ic_keypad_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -69,10 +66,10 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: callTransfer
|
id: callTransfer
|
||||||
|
|
||||||
canTrigger: isSIP
|
canTrigger: CurrentCall.isSIP
|
||||||
itemName: JamiStrings.transferCall
|
itemName: JamiStrings.transferCall
|
||||||
iconSource: JamiResources.phone_forwarded_24dp_svg
|
iconSource: JamiResources.phone_forwarded_24dp_svg
|
||||||
addMenuSeparatorAfter: isSIP
|
addMenuSeparatorAfter: CurrentCall.isSIP
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.transferCallButtonClicked()
|
root.transferCallButtonClicked()
|
||||||
}
|
}
|
||||||
|
@ -80,7 +77,9 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: localRecord
|
id: localRecord
|
||||||
|
|
||||||
itemName: root.isRecording ? JamiStrings.stopRec : JamiStrings.startRec
|
itemName: CurrentCall.isRecordingLocally ?
|
||||||
|
JamiStrings.stopRec :
|
||||||
|
JamiStrings.startRec
|
||||||
iconSource: JamiResources.fiber_manual_record_24dp_svg
|
iconSource: JamiResources.fiber_manual_record_24dp_svg
|
||||||
iconColor: JamiTheme.recordIconColor
|
iconColor: JamiTheme.recordIconColor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -103,8 +102,9 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: stopSharing
|
id: stopSharing
|
||||||
|
|
||||||
canTrigger: AvAdapter.isSharing()
|
canTrigger: CurrentCall.isSharing
|
||||||
&& !isSIP && !isVideoMuted
|
&& !CurrentCall.isSIP
|
||||||
|
&& !CurrentCall.isVideoMuted
|
||||||
itemName: JamiStrings.stopSharing
|
itemName: JamiStrings.stopSharing
|
||||||
iconSource: JamiResources.share_stop_black_24dp_svg
|
iconSource: JamiResources.share_stop_black_24dp_svg
|
||||||
iconColor: JamiTheme.redColor
|
iconColor: JamiTheme.redColor
|
||||||
|
@ -113,8 +113,9 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: shareScreen
|
id: shareScreen
|
||||||
|
|
||||||
canTrigger: CurrentAccount.videoEnabled_Video && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
canTrigger: CurrentAccount.videoEnabled_Video
|
||||||
&& !isSIP
|
&& AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||||
|
&& !CurrentCall.isSIP
|
||||||
itemName: JamiStrings.shareScreen
|
itemName: JamiStrings.shareScreen
|
||||||
iconSource: JamiResources.laptop_black_24dp_svg
|
iconSource: JamiResources.laptop_black_24dp_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -129,8 +130,10 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: shareWindow
|
id: shareWindow
|
||||||
|
|
||||||
canTrigger: Qt.platform.os === "linux" && CurrentAccount.videoEnabled_Video && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
canTrigger: Qt.platform.os === "linux"
|
||||||
&& !isSIP
|
&& CurrentAccount.videoEnabled_Video
|
||||||
|
&& AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||||
|
&& !CurrentCall.isSIP
|
||||||
itemName: JamiStrings.shareWindow
|
itemName: JamiStrings.shareWindow
|
||||||
iconSource: JamiResources.window_black_24dp_svg
|
iconSource: JamiResources.window_black_24dp_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -144,8 +147,9 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: shareScreenArea
|
id: shareScreenArea
|
||||||
|
|
||||||
canTrigger: CurrentAccount.videoEnabled_Video && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
canTrigger: CurrentAccount.videoEnabled_Video
|
||||||
&& !isSIP
|
&& AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||||
|
&& !CurrentCall.isSIP
|
||||||
itemName: JamiStrings.shareScreenArea
|
itemName: JamiStrings.shareScreenArea
|
||||||
iconSource: JamiResources.share_area_black_24dp_svg
|
iconSource: JamiResources.share_area_black_24dp_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -160,7 +164,8 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: shareFile
|
id: shareFile
|
||||||
|
|
||||||
canTrigger: CurrentAccount.videoEnabled_Video && !isSIP
|
canTrigger: CurrentAccount.videoEnabled_Video
|
||||||
|
&& !CurrentCall.isSIP
|
||||||
itemName: JamiStrings.shareFile
|
itemName: JamiStrings.shareFile
|
||||||
iconSource: JamiResources.file_black_24dp_svg
|
iconSource: JamiResources.file_black_24dp_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -170,7 +175,8 @@ ContextMenuAutoLoader {
|
||||||
GeneralMenuItem {
|
GeneralMenuItem {
|
||||||
id: viewPlugin
|
id: viewPlugin
|
||||||
|
|
||||||
canTrigger: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
|
canTrigger: PluginAdapter.isEnabled &&
|
||||||
|
PluginAdapter.callMediaHandlersListCount
|
||||||
itemName: JamiStrings.viewPlugin
|
itemName: JamiStrings.viewPlugin
|
||||||
iconSource: JamiResources.extension_24dp_svg
|
iconSource: JamiResources.extension_24dp_svg
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|
|
@ -31,7 +31,7 @@ Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isIncoming: false
|
property bool isIncoming: false
|
||||||
property bool isAudioOnly: false
|
property bool isAudioOnly: CurrentCall.isAudioOnly
|
||||||
property int callStatus: 0
|
property int callStatus: 0
|
||||||
|
|
||||||
signal callCanceled
|
signal callCanceled
|
||||||
|
|
|
@ -32,7 +32,21 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string timeText: "00:00"
|
property string timeText: "00:00"
|
||||||
property string remoteRecordingLabel: ""
|
property string remoteRecordingLabel
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: CurrentCall
|
||||||
|
|
||||||
|
function onIsRecordingRemotelyChanged() {
|
||||||
|
var label = ""
|
||||||
|
if (CurrentCall.isRecordingRemotely) {
|
||||||
|
label = CurrentCall.remoteRecorderNameList.join(", ") + " "
|
||||||
|
label += (CurrentCall.remoteRecorderNameList.length > 1) ?
|
||||||
|
JamiStrings.areRecording : JamiStrings.isRecording
|
||||||
|
}
|
||||||
|
root.remoteRecordingLabel = label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property alias callActionBar: __callActionBar
|
property alias callActionBar: __callActionBar
|
||||||
|
|
||||||
|
@ -43,8 +57,6 @@ Item {
|
||||||
|
|
||||||
property string muteAlertMessage: ""
|
property string muteAlertMessage: ""
|
||||||
property bool muteAlertActive: false
|
property bool muteAlertActive: false
|
||||||
property bool remoteRecording: false
|
|
||||||
property bool isRecording: false
|
|
||||||
|
|
||||||
onMuteAlertActiveChanged: {
|
onMuteAlertActiveChanged: {
|
||||||
if (muteAlertActive) {
|
if (muteAlertActive) {
|
||||||
|
@ -117,7 +129,7 @@ Item {
|
||||||
root.timeText = CallAdapter.getCallDurationTime(
|
root.timeText = CallAdapter.getCallDurationTime(
|
||||||
LRCInstance.currentAccountId,
|
LRCInstance.currentAccountId,
|
||||||
LRCInstance.selectedConvUid)
|
LRCInstance.selectedConvUid)
|
||||||
if (root.opacity === 0 && !root.remoteRecording)
|
if (root.opacity === 0 && !CurrentCall.isRecordingRemotely)
|
||||||
root.remoteRecordingLabel = ""
|
root.remoteRecordingLabel = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,11 +161,11 @@ Item {
|
||||||
|
|
||||||
font.pointSize: JamiTheme.textFontSize
|
font.pointSize: JamiTheme.textFontSize
|
||||||
text: {
|
text: {
|
||||||
if (!root.isAudioOnly) {
|
if (!CurrentCall.isAudioOnly) {
|
||||||
if (remoteRecordingLabel === "") {
|
if (root.remoteRecordingLabel === "") {
|
||||||
return CurrentConversation.title
|
return CurrentConversation.title
|
||||||
} else {
|
} else {
|
||||||
return remoteRecordingLabel
|
return root.remoteRecordingLabel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
@ -180,7 +192,7 @@ Item {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: recordingRect
|
id: recordingRect
|
||||||
visible: root.isRecording || root.remoteRecording
|
visible: CurrentCall.isRecordingLocally || CurrentCall.isRecordingRemotely
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||||
Layout.rightMargin: JamiTheme.preferredMarginSize
|
Layout.rightMargin: JamiTheme.preferredMarginSize
|
||||||
|
|
|
@ -42,9 +42,8 @@ Rectangle {
|
||||||
property int previewMarginYBottom: previewMargin + 84
|
property int previewMarginYBottom: previewMargin + 84
|
||||||
property int previewToX: 0
|
property int previewToX: 0
|
||||||
property int previewToY: 0
|
property int previewToY: 0
|
||||||
property bool isAudioOnly: false
|
|
||||||
property var linkedWebview: null
|
property var linkedWebview: null
|
||||||
property string callPreviewId: ""
|
property string callPreviewId
|
||||||
|
|
||||||
onCallPreviewIdChanged: {
|
onCallPreviewIdChanged: {
|
||||||
controlPreview.start()
|
controlPreview.start()
|
||||||
|
@ -56,8 +55,6 @@ Rectangle {
|
||||||
if (accountPeerPair[0] === "" || accountPeerPair[1] === "")
|
if (accountPeerPair[0] === "" || accountPeerPair[1] === "")
|
||||||
return
|
return
|
||||||
contactImage.imageId = accountPeerPair[1]
|
contactImage.imageId = accountPeerPair[1]
|
||||||
distantRenderer.rendererId = UtilsAdapter.getCallId(accountPeerPair[0],
|
|
||||||
accountPeerPair[1])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLinkedWebview(webViewId) {
|
function setLinkedWebview(webViewId) {
|
||||||
|
@ -68,7 +65,6 @@ Rectangle {
|
||||||
closeInCallConversation)
|
closeInCallConversation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: UtilsAdapter
|
target: UtilsAdapter
|
||||||
|
|
||||||
|
@ -178,11 +174,12 @@ Rectangle {
|
||||||
VideoView {
|
VideoView {
|
||||||
id: distantRenderer
|
id: distantRenderer
|
||||||
|
|
||||||
|
rendererId: CurrentCall.id
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: -1
|
z: -1
|
||||||
|
|
||||||
visible: participantsLayer.count === 0 && !root.isAudioOnly
|
visible: !CurrentCall.isConference && !CurrentCall.isAudioOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
ParticipantsLayer {
|
ParticipantsLayer {
|
||||||
|
@ -190,17 +187,16 @@ Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.margins: 1
|
anchors.margins: 1
|
||||||
visible: participantsLayer.count !== 0
|
visible: CurrentCall.isConference
|
||||||
participantsSide: callOverlay.participantsSide
|
participantsSide: callOverlay.participantsSide
|
||||||
|
|
||||||
onCountChanged: {
|
|
||||||
callOverlay.isConference = participantsLayer.count > 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalVideo {
|
LocalVideo {
|
||||||
id: previewRenderer
|
id: previewRenderer
|
||||||
|
|
||||||
|
visible: (CurrentCall.isSharing || !CurrentCall.isVideoMuted)
|
||||||
|
&& !CurrentCall.isConference
|
||||||
|
|
||||||
height: width * invAspectRatio
|
height: width * invAspectRatio
|
||||||
width: Math.max(callPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
|
width: Math.max(callPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
|
||||||
x: callPageMainRect.width - previewRenderer.width - previewMargin
|
x: callPageMainRect.width - previewRenderer.width - previewMargin
|
||||||
|
@ -217,6 +213,7 @@ Rectangle {
|
||||||
previewRenderer.startWithId(rendId)
|
previewRenderer.startWithId(rendId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
controlPreview.stop()
|
controlPreview.stop()
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
@ -297,7 +294,6 @@ Rectangle {
|
||||||
id: callOverlay
|
id: callOverlay
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
isConference: participantsLayer.count > 0
|
|
||||||
|
|
||||||
function toggleConversation() {
|
function toggleConversation() {
|
||||||
if (inCallMessageWebViewStack.visible)
|
if (inCallMessageWebViewStack.visible)
|
||||||
|
@ -307,35 +303,19 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: CallAdapter
|
target: CurrentCall
|
||||||
|
|
||||||
function onUpdateOverlay(isPaused, isAudioOnly, isAudioMuted,
|
function onPreviewIdChanged() {
|
||||||
isSIP, isGrid, previewId) {
|
if (CurrentCall.previewId !== "") {
|
||||||
root.callPreviewId = previewId
|
if (root.callPreviewId !== "" &&
|
||||||
callOverlay.showOnHoldImage(isPaused)
|
root.callPreviewId !== CurrentCall.previewId) {
|
||||||
root.isAudioOnly = isAudioOnly
|
VideoDevices.stopDevice(root.callPreviewId)
|
||||||
callOverlay.showOnHoldImage(isPaused)
|
|
||||||
audioCallPageRectCentralRect.visible = !isPaused && root.isAudioOnly && participantsLayer.count === 0
|
|
||||||
callOverlay.updateUI(isPaused, isAudioOnly,
|
|
||||||
isAudioMuted,
|
|
||||||
isSIP,
|
|
||||||
isGrid)
|
|
||||||
callOverlay.isVideoMuted = !AvAdapter.isCapturing()
|
|
||||||
callOverlay.sharingActive = AvAdapter.isSharing()
|
|
||||||
previewRenderer.visible = (AvAdapter.isSharing() || AvAdapter.isCapturing()) && participantsLayer.count == 0
|
|
||||||
}
|
}
|
||||||
|
VideoDevices.startDevice(CurrentCall.previewId)
|
||||||
function onShowOnHoldLabel(isPaused) {
|
} else {
|
||||||
callOverlay.showOnHoldImage(isPaused)
|
VideoDevices.stopDevice(root.callPreviewId)
|
||||||
audioCallPageRectCentralRect.visible = !isPaused && root.isAudioOnly && participantsLayer.count === 0
|
|
||||||
}
|
}
|
||||||
|
root.callPreviewId = CurrentCall.previewId
|
||||||
function onRemoteRecordingChanged(label, state) {
|
|
||||||
callOverlay.showRemoteRecording(label, state)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEraseRemoteRecording() {
|
|
||||||
callOverlay.resetRemoteRecording()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +347,9 @@ Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
visible: root.isAudioOnly
|
visible: !CurrentCall.isPaused &&
|
||||||
|
CurrentCall.isAudioOnly &&
|
||||||
|
!CurrentCall.isConference
|
||||||
|
|
||||||
ConversationAvatar {
|
ConversationAvatar {
|
||||||
id: contactImage
|
id: contactImage
|
||||||
|
|
|
@ -58,7 +58,7 @@ Popup {
|
||||||
function onAboutToShow(visible) {
|
function onAboutToShow(visible) {
|
||||||
// Reset the model on each show.
|
// Reset the model on each show.
|
||||||
if (isCall) {
|
if (isCall) {
|
||||||
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
|
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentCall.id)
|
||||||
} else {
|
} else {
|
||||||
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
||||||
pluginhandlerPickerListView.model = PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
|
pluginhandlerPickerListView.model = PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
|
||||||
|
@ -68,8 +68,8 @@ Popup {
|
||||||
|
|
||||||
function toggleHandlerSlot(handlerId, isLoaded) {
|
function toggleHandlerSlot(handlerId, isLoaded) {
|
||||||
if (isCall) {
|
if (isCall) {
|
||||||
PluginModel.toggleCallMediaHandler(handlerId, CurrentConversation.callId, !isLoaded)
|
PluginModel.toggleCallMediaHandler(handlerId, CurrentCall.id, !isLoaded)
|
||||||
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
|
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentCall.id)
|
||||||
} else {
|
} else {
|
||||||
var accountId = LRCInstance.currentAccountId
|
var accountId = LRCInstance.currentAccountId
|
||||||
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
||||||
|
@ -125,7 +125,7 @@ Popup {
|
||||||
|
|
||||||
model: {
|
model: {
|
||||||
if (isCall) {
|
if (isCall) {
|
||||||
return PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
|
return PluginAdapter.getMediaHandlerSelectableModel(CurrentCall.id)
|
||||||
} else {
|
} else {
|
||||||
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
||||||
return PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
|
return PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "previewengine.h"
|
#include "previewengine.h"
|
||||||
#include "utilsadapter.h"
|
#include "utilsadapter.h"
|
||||||
#include "conversationsadapter.h"
|
#include "conversationsadapter.h"
|
||||||
|
#include "currentcall.h"
|
||||||
#include "currentconversation.h"
|
#include "currentconversation.h"
|
||||||
#include "currentaccount.h"
|
#include "currentaccount.h"
|
||||||
#include "videodevices.h"
|
#include "videodevices.h"
|
||||||
|
@ -118,6 +119,7 @@ registerTypes(QQmlEngine* engine,
|
||||||
auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, parent);
|
auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, parent);
|
||||||
auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, parent);
|
auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, parent);
|
||||||
auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
|
auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
|
||||||
|
auto currentCall = new CurrentCall(lrcInstance, parent);
|
||||||
auto currentConversation = new CurrentConversation(lrcInstance, parent);
|
auto currentConversation = new CurrentConversation(lrcInstance, parent);
|
||||||
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, parent);
|
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, parent);
|
||||||
auto tipsModel = new TipsModel(settingsManager, parent);
|
auto tipsModel = new TipsModel(settingsManager, parent);
|
||||||
|
@ -135,6 +137,7 @@ registerTypes(QQmlEngine* engine,
|
||||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, accountAdapter, "AccountAdapter");
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, accountAdapter, "AccountAdapter");
|
||||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, utilsAdapter, "UtilsAdapter");
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, utilsAdapter, "UtilsAdapter");
|
||||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, pluginAdapter, "PluginAdapter");
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, pluginAdapter, "PluginAdapter");
|
||||||
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentCall, "CurrentCall");
|
||||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentConversation, "CurrentConversation");
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentConversation, "CurrentConversation");
|
||||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentAccount, "CurrentAccount");
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentAccount, "CurrentAccount");
|
||||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, videoDevices, "VideoDevices");
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, videoDevices, "VideoDevices");
|
||||||
|
|
|
@ -139,7 +139,7 @@ struct Info
|
||||||
bool isAudioOnly = false;
|
bool isAudioOnly = false;
|
||||||
Layout layout = Layout::GRID;
|
Layout layout = Layout::GRID;
|
||||||
VectorMapStringString mediaList = {};
|
VectorMapStringString mediaList = {};
|
||||||
QSet<QString> peerRec {};
|
QStringList recordingPeers {};
|
||||||
|
|
||||||
bool hasMediaWithType(const QString& type, const QString& mediaType) const
|
bool hasMediaWithType(const QString& type, const QString& mediaType) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -429,7 +429,7 @@ Q_SIGNALS:
|
||||||
* Emitted when the rendered image changed
|
* Emitted when the rendered image changed
|
||||||
* @param confId
|
* @param confId
|
||||||
*/
|
*/
|
||||||
void onParticipantsChanged(const QString& confId) const;
|
void participantsChanged(const QString& confId) const;
|
||||||
/**
|
/**
|
||||||
* Emitted when a call starts
|
* Emitted when a call starts
|
||||||
* @param callId
|
* @param callId
|
||||||
|
@ -469,15 +469,19 @@ Q_SIGNALS:
|
||||||
int urgentCount) const;
|
int urgentCount) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen from CallbacksHandler when the peer start recording
|
* Provides notification of a new set of recording peers once a change has occured,
|
||||||
|
* in the form of a list, as QSet<QString> is not directly QML compatible.
|
||||||
* @param callId
|
* @param callId
|
||||||
* @param contactId
|
* @param recorders
|
||||||
* @param peerName
|
|
||||||
* @param state the new state
|
|
||||||
*/
|
*/
|
||||||
void remoteRecordingChanged(const QString& callId,
|
void remoteRecordersChanged(const QString& callId, const QStringList& recorders) const;
|
||||||
const QSet<QString>& peerRec,
|
|
||||||
bool state) const;
|
/**
|
||||||
|
* Provides notification of change in the local call recording state.,
|
||||||
|
* @param callId
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
void recordingStateChanged(const QString& callId, bool state) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Emitted before new pending conferences are inserted into the underlying list
|
* Emitted before new pending conferences are inserted into the underlying list
|
||||||
|
@ -504,6 +508,11 @@ Q_SIGNALS:
|
||||||
*/
|
*/
|
||||||
void callInfosChanged(const QString& accountId, const QString& callId) const;
|
void callInfosChanged(const QString& accountId, const QString& callId) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit currentCallChanged
|
||||||
|
*/
|
||||||
|
void currentCallChanged(const QString& callId) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<CallModelPimpl> pimpl_;
|
std::unique_ptr<CallModelPimpl> pimpl_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -201,6 +201,12 @@ CallbacksHandler::CallbacksHandler(const Lrc& parent)
|
||||||
&CallbacksHandler::slotConferenceChanged,
|
&CallbacksHandler::slotConferenceChanged,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect(&CallManager::instance(),
|
||||||
|
&CallManagerInterface::recordingStateChanged,
|
||||||
|
this,
|
||||||
|
&CallbacksHandler::recordingStateChanged,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(&CallManager::instance(),
|
connect(&CallManager::instance(),
|
||||||
&CallManagerInterface::incomingMessage,
|
&CallManagerInterface::incomingMessage,
|
||||||
this,
|
this,
|
||||||
|
@ -572,6 +578,12 @@ CallbacksHandler::slotConferenceCreated(const QString& accountId, const QString&
|
||||||
Q_EMIT conferenceCreated(accountId, callId);
|
Q_EMIT conferenceCreated(accountId, callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallbacksHandler::slotConferenceRemoved(const QString& accountId, const QString& callId)
|
||||||
|
{
|
||||||
|
Q_EMIT conferenceRemoved(accountId, callId);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CallbacksHandler::slotConferenceChanged(const QString& accountId,
|
CallbacksHandler::slotConferenceChanged(const QString& accountId,
|
||||||
const QString& callId,
|
const QString& callId,
|
||||||
|
@ -581,12 +593,6 @@ CallbacksHandler::slotConferenceChanged(const QString& accountId,
|
||||||
slotCallStateChanged(accountId, callId, state, 0);
|
slotCallStateChanged(accountId, callId, state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CallbacksHandler::slotConferenceRemoved(const QString& accountId, const QString& callId)
|
|
||||||
{
|
|
||||||
Q_EMIT conferenceRemoved(accountId, callId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
|
CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
|
||||||
const QString& conversationId,
|
const QString& conversationId,
|
||||||
|
|
|
@ -377,6 +377,7 @@ Q_SIGNALS:
|
||||||
void conversationPreferencesUpdated(const QString& accountId,
|
void conversationPreferencesUpdated(const QString& accountId,
|
||||||
const QString& conversationId,
|
const QString& conversationId,
|
||||||
const MapStringString& preferences);
|
const MapStringString& preferences);
|
||||||
|
void recordingStateChanged(const QString& callId, bool state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when a conversation receives a new position
|
* Emitted when a conversation receives a new position
|
||||||
|
|
|
@ -259,9 +259,16 @@ public Q_SLOTS:
|
||||||
/**
|
/**
|
||||||
* Listen from CallbacksHandler when the peer start recording
|
* Listen from CallbacksHandler when the peer start recording
|
||||||
* @param callId
|
* @param callId
|
||||||
|
* @param peerUri
|
||||||
* @param state the new state
|
* @param state the new state
|
||||||
*/
|
*/
|
||||||
void remoteRecordingChanged(const QString& callId, const QString& peerNumber, bool state);
|
void onRemoteRecordingChanged(const QString& callId, const QString& peerUri, bool state);
|
||||||
|
/**
|
||||||
|
* Listen from CallbacksHandler when we start/stop recording
|
||||||
|
* @param callId
|
||||||
|
* @param state the new state
|
||||||
|
*/
|
||||||
|
void onRecordingStateChanged(const QString& callId, bool state);
|
||||||
};
|
};
|
||||||
|
|
||||||
CallModel::CallModel(const account::Info& owner,
|
CallModel::CallModel(const account::Info& owner,
|
||||||
|
@ -975,7 +982,11 @@ CallModelPimpl::CallModelPimpl(const CallModel& linked,
|
||||||
connect(&callbacksHandler,
|
connect(&callbacksHandler,
|
||||||
&CallbacksHandler::remoteRecordingChanged,
|
&CallbacksHandler::remoteRecordingChanged,
|
||||||
this,
|
this,
|
||||||
&CallModelPimpl::remoteRecordingChanged);
|
&CallModelPimpl::onRemoteRecordingChanged);
|
||||||
|
connect(&callbacksHandler,
|
||||||
|
&CallbacksHandler::recordingStateChanged,
|
||||||
|
this,
|
||||||
|
&CallModelPimpl::onRecordingStateChanged);
|
||||||
|
|
||||||
#ifndef ENABLE_LIBWRAP
|
#ifndef ENABLE_LIBWRAP
|
||||||
// Only necessary with dbus since the daemon runs separately
|
// Only necessary with dbus since the daemon runs separately
|
||||||
|
@ -1140,7 +1151,7 @@ CallModel::setCurrentCall(const QString& callId) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lrc::api::Lrc::holdConferences) {
|
if (!lrc::api::Lrc::holdConferences) {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
// If the account is the host and it is attached to the conference,
|
// If the account is the host and it is attached to the conference,
|
||||||
// then we should hold it.
|
// then we should hold it.
|
||||||
|
@ -1157,6 +1168,8 @@ CallModel::setCurrentCall(const QString& callId) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_EMIT currentCallChanged(callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1599,7 +1612,7 @@ CallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Q_EMIT linked.callInfosChanged(linked.owner.id, confId);
|
Q_EMIT linked.callInfosChanged(linked.owner.id, confId);
|
||||||
Q_EMIT linked.onParticipantsChanged(confId);
|
Q_EMIT linked.participantsChanged(confId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1686,13 +1699,14 @@ CallModelPimpl::sendProfile(const QString& callId)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CallModelPimpl::remoteRecordingChanged(const QString& callId, const QString& peerNumber, bool state)
|
CallModelPimpl::onRemoteRecordingChanged(const QString& callId, const QString& peerUri, bool state)
|
||||||
{
|
{
|
||||||
auto it = calls.find(callId);
|
auto it = calls.find(callId);
|
||||||
if (it == calls.end() or not it->second)
|
if (it == calls.end() or !it->second) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto uri = peerNumber;
|
auto uri = peerUri;
|
||||||
|
|
||||||
if (uri.contains("ring:"))
|
if (uri.contains("ring:"))
|
||||||
uri.remove("ring:");
|
uri.remove("ring:");
|
||||||
|
@ -1701,15 +1715,19 @@ CallModelPimpl::remoteRecordingChanged(const QString& callId, const QString& pee
|
||||||
if (uri.contains("@ring.dht"))
|
if (uri.contains("@ring.dht"))
|
||||||
uri.remove("@ring.dht");
|
uri.remove("@ring.dht");
|
||||||
|
|
||||||
// Add peer to peerRec set
|
// Add/remove peer to recordingPeers, preventing duplicates.
|
||||||
if (state && not it->second->peerRec.contains(uri))
|
if (state && !it->second->recordingPeers.contains(uri))
|
||||||
it->second->peerRec.insert(uri);
|
it->second->recordingPeers.append(uri);
|
||||||
|
else if (!state && it->second->recordingPeers.contains(uri))
|
||||||
|
it->second->recordingPeers.removeAll(uri);
|
||||||
|
|
||||||
// remove peer from peerRec set
|
Q_EMIT linked.remoteRecordersChanged(callId, it->second->recordingPeers);
|
||||||
if (!state && it->second->peerRec.contains(uri))
|
}
|
||||||
it->second->peerRec.remove(uri);
|
|
||||||
|
|
||||||
Q_EMIT linked.remoteRecordingChanged(callId, it->second->peerRec, state);
|
void
|
||||||
|
CallModelPimpl::onRecordingStateChanged(const QString& callId, bool state)
|
||||||
|
{
|
||||||
|
Q_EMIT linked.recordingStateChanged(callId, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lrc
|
} // namespace lrc
|
||||||
|
|
Loading…
Add table
Reference in a new issue