mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-04-21 21:52:03 +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}/tipsmodel.cpp
|
||||
${APP_SRC_DIR}/positioning.cpp
|
||||
)
|
||||
${APP_SRC_DIR}/currentcall.cpp)
|
||||
|
||||
set(COMMON_HEADERS
|
||||
${APP_SRC_DIR}/avatarimageprovider.h
|
||||
|
@ -280,7 +280,8 @@ set(COMMON_HEADERS
|
|||
${APP_SRC_DIR}/videoprovider.h
|
||||
${APP_SRC_DIR}/callparticipantsmodel.h
|
||||
${APP_SRC_DIR}/tipsmodel.h
|
||||
${APP_SRC_DIR}/positioning.h)
|
||||
${APP_SRC_DIR}/positioning.h
|
||||
${APP_SRC_DIR}/currentcall.h)
|
||||
|
||||
if(WITH_WEBENGINE)
|
||||
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);
|
||||
if (!convInfo.uid.isEmpty()) {
|
||||
Q_EMIT callStatusChanged(static_cast<int>(call.status), accountId_, convInfo.uid);
|
||||
updateCallOverlay(convInfo);
|
||||
}
|
||||
|
||||
switch (call.status) {
|
||||
|
@ -330,25 +329,11 @@ CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
|
|||
}
|
||||
Q_EMIT callInfosChanged(call.isAudioOnly, accountId, convInfo.uid);
|
||||
participantsModel_->setConferenceLayout(static_cast<int>(call.layout), callId);
|
||||
updateCallOverlay(convInfo);
|
||||
}
|
||||
} 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
|
||||
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_->setConferenceLayout(static_cast<int>(call->layout), call->id);
|
||||
}
|
||||
|
@ -569,7 +552,6 @@ CallAdapter::getConferencesInfos() const
|
|||
.getAccountInfo(accountId_)
|
||||
.callModel.get()
|
||||
->getParticipantsInfos(callId);
|
||||
int index = 0;
|
||||
for (int index = 0; index < participantsModel.getParticipants().size(); index++) {
|
||||
auto participant = participantsModel.toQJsonObject(index);
|
||||
fillParticipantData(participant);
|
||||
|
@ -642,12 +624,6 @@ CallAdapter::connectCallModel(const QString& accountId)
|
|||
QOverload<const QString&, int>::of(&CallAdapter::onCallStatusChanged),
|
||||
Qt::UniqueConnection);
|
||||
|
||||
connect(accInfo.callModel.get(),
|
||||
&CallModel::remoteRecordingChanged,
|
||||
this,
|
||||
&CallAdapter::onRemoteRecordingChanged,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
connect(accInfo.callModel.get(),
|
||||
&CallModel::callAddedToConference,
|
||||
this,
|
||||
|
@ -660,32 +636,6 @@ CallAdapter::connectCallModel(const QString& accountId)
|
|||
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
|
||||
CallAdapter::sipInputPanelPlayDTMF(const QString& key)
|
||||
{
|
||||
|
@ -698,49 +648,6 @@ CallAdapter::sipInputPanelPlayDTMF(const QString& 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
|
||||
CallAdapter::saveConferenceSubcalls()
|
||||
{
|
||||
|
@ -1075,7 +982,6 @@ CallAdapter::holdThisCallToggle()
|
|||
if (callModel->hasCall(callId)) {
|
||||
callModel->togglePause(callId);
|
||||
}
|
||||
Q_EMIT showOnHoldLabel(true);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -100,15 +100,6 @@ Q_SIGNALS:
|
|||
|
||||
// For Call Overlay
|
||||
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:
|
||||
void onShowIncomingCallView(const QString& accountId, const QString& convUid);
|
||||
|
@ -117,18 +108,15 @@ public Q_SLOTS:
|
|||
void onCallStatusChanged(const QString& accountId, const QString& callId);
|
||||
void onCallInfosChanged(const QString& accountId, const QString& callId);
|
||||
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 onParticipantAdded(const QString& callId, int index);
|
||||
void onParticipantRemoved(const QString& callId, int index);
|
||||
void onParticipantUpdated(const QString& callId, int index);
|
||||
|
||||
private:
|
||||
void updateRecordingPeers(bool eraseLabelOnEmpty = false);
|
||||
void showNotification(const QString& accountId, const QString& convUid);
|
||||
void fillParticipantData(QJsonObject& participant) const;
|
||||
void preventScreenSaver(bool state);
|
||||
void updateCallOverlay(const lrc::api::conversation::Info& convInfo);
|
||||
void saveConferenceSubcalls();
|
||||
|
||||
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.responsibleAccountId = LRCInstance.currentAccountId
|
||||
callStackView.responsibleConvUid = convId
|
||||
callStackView.isAudioOnly = item.isAudioOnly
|
||||
currentConvUID = convId
|
||||
|
||||
if (item.callState === Call.Status.IN_PROGRESS ||
|
||||
|
|
|
@ -162,7 +162,7 @@ Control {
|
|||
layoutModel.get(index).ActiveSetting = layoutManager.isCallFullscreen
|
||||
break
|
||||
case JamiStrings.mosaic:
|
||||
if (!isGrid)
|
||||
if (!CurrentCall.isGrid)
|
||||
CallAdapter.showGridConferenceLayout()
|
||||
break
|
||||
case JamiStrings.participantsSide:
|
||||
|
@ -189,10 +189,10 @@ Control {
|
|||
}
|
||||
onTriggered: {
|
||||
layoutModel.clear()
|
||||
if (isConference) {
|
||||
if (CurrentCall.isConference) {
|
||||
layoutModel.append({"Name": JamiStrings.mosaic,
|
||||
"IconSource": JamiResources.mosaic_black_24dp_svg,
|
||||
"ActiveSetting": isGrid,
|
||||
"ActiveSetting": CurrentCall.isGrid,
|
||||
"TopMargin": true,
|
||||
"BottomMargin": true,
|
||||
"SectionEnd": true})
|
||||
|
@ -223,8 +223,8 @@ Control {
|
|||
"ActiveSetting": layoutManager.isCallFullscreen,
|
||||
"TopMargin": true,
|
||||
"BottomMargin": true,
|
||||
"SectionEnd": isConference})
|
||||
if (isConference) {
|
||||
"SectionEnd": CurrentCall.isConference})
|
||||
if (CurrentCall.isConference) {
|
||||
layoutModel.append({"Name": JamiStrings.hideSpectators,
|
||||
"IconSource": JamiResources.videocam_off_24dp_svg,
|
||||
"ActiveSetting": UtilsAdapter.getAppValue(Settings.HideSpectators),
|
||||
|
@ -263,6 +263,7 @@ Control {
|
|||
JamiResources.micro_black_24dp_svg
|
||||
icon.color: checked ? "red" : "white"
|
||||
text: !checked ? JamiStrings.mute : JamiStrings.unmute
|
||||
checked: CurrentCall.isAudioMuted
|
||||
property var menuAction: audioInputMenuAction
|
||||
},
|
||||
Action {
|
||||
|
@ -282,6 +283,7 @@ Control {
|
|||
JamiResources.videocam_24dp_svg
|
||||
icon.color: checked ? "red" : "white"
|
||||
text: !checked ? JamiStrings.muteCamera : JamiStrings.unmuteCamera
|
||||
checked: !CurrentCall.isCapturing
|
||||
property var menuAction: videoInputMenuAction
|
||||
}
|
||||
]
|
||||
|
@ -314,11 +316,13 @@ Control {
|
|||
Action {
|
||||
id: resumePauseCallAction
|
||||
onTriggered: root.resumePauseCallClicked()
|
||||
icon.source: isPaused ?
|
||||
icon.source: CurrentCall.isPaused ?
|
||||
JamiResources.play_circle_outline_24dp_svg :
|
||||
JamiResources.pause_circle_outline_24dp_svg
|
||||
icon.color: "white"
|
||||
text: isPaused ? JamiStrings.resumeCall : JamiStrings.pauseCall
|
||||
text: CurrentCall.isPaused ?
|
||||
JamiStrings.resumeCall :
|
||||
JamiStrings.pauseCall
|
||||
},
|
||||
Action {
|
||||
id: inputPanelSIPAction
|
||||
|
@ -337,17 +341,17 @@ Control {
|
|||
Action {
|
||||
id: shareAction
|
||||
onTriggered: {
|
||||
if (sharingActive)
|
||||
if (CurrentCall.isSharing)
|
||||
root.stopSharingClicked()
|
||||
else
|
||||
root.shareScreenClicked()
|
||||
}
|
||||
icon.source: sharingActive ?
|
||||
icon.source: CurrentCall.isSharing ?
|
||||
JamiResources.share_stop_black_24dp_svg :
|
||||
JamiResources.share_screen_black_24dp_svg
|
||||
icon.color: sharingActive ?
|
||||
icon.color: CurrentCall.isSharing ?
|
||||
"red" : "white"
|
||||
text: sharingActive ?
|
||||
text: CurrentCall.isSharing ?
|
||||
JamiStrings.stopSharing :
|
||||
JamiStrings.shareScreen
|
||||
property real size: 34
|
||||
|
@ -362,12 +366,13 @@ Control {
|
|||
text: checked ?
|
||||
JamiStrings.lowerHand :
|
||||
JamiStrings.raiseHand
|
||||
checked: CurrentCall.isHandRaised
|
||||
property real size: 34
|
||||
},
|
||||
Action {
|
||||
id: layoutAction
|
||||
onTriggered: {
|
||||
if (!isGrid)
|
||||
if (!CurrentCall.isGrid)
|
||||
CallAdapter.showGridConferenceLayout()
|
||||
}
|
||||
checkable: true
|
||||
|
@ -386,6 +391,7 @@ Control {
|
|||
text: !checked ? JamiStrings.startRec : JamiStrings.stopRec
|
||||
property bool blinksWhenChecked: true
|
||||
property real size: 28
|
||||
checked: CurrentCall.isRecordingLocally
|
||||
onCheckedChanged: function(checked) {
|
||||
CallOverlayModel.setUrgentCount(recordAction,
|
||||
checked ? -1 : 0)
|
||||
|
@ -397,27 +403,29 @@ Control {
|
|||
icon.source: JamiResources.plugins_24dp_svg
|
||||
icon.color: "white"
|
||||
text: JamiStrings.viewPlugin
|
||||
enabled: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
|
||||
enabled: PluginAdapter.isEnabled
|
||||
&& PluginAdapter.callMediaHandlersListCount
|
||||
}
|
||||
]
|
||||
|
||||
property var overflowItemCount
|
||||
|
||||
Connections {
|
||||
target: callOverlay
|
||||
target: CurrentCall
|
||||
|
||||
function onIsAudioOnlyChanged() { Qt.callLater(reset) }
|
||||
function onIsSIPChanged() { Qt.callLater(reset) }
|
||||
function onIsActiveChanged() { if (CurrentCall.isActive) reset() }
|
||||
function onIsRecordingLocallyChanged() { Qt.callLater(reset) }
|
||||
function onIsHandRaisedChanged() { Qt.callLater(reset) }
|
||||
function onIsConferenceChanged() { Qt.callLater(reset) }
|
||||
function onIsModeratorChanged() { Qt.callLater(reset) }
|
||||
function onIsSIPChanged() { Qt.callLater(reset) }
|
||||
function onIsAudioOnlyChanged() { Qt.callLater(reset) }
|
||||
function onIsAudioMutedChanged() { Qt.callLater(reset) }
|
||||
function onIsVideoMutedChanged() { Qt.callLater(reset) }
|
||||
function onIsRecordingChanged() { Qt.callLater(reset) }
|
||||
function onLocalHandRaisedChanged() { Qt.callLater(reset) }
|
||||
function onIsConferenceChanged() { Qt.callLater(reset) }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CurrentAccount
|
||||
|
||||
function onVideoEnabledVideoChanged() { reset() }
|
||||
}
|
||||
|
||||
|
@ -433,29 +441,24 @@ Control {
|
|||
|
||||
// overflow controls
|
||||
CallOverlayModel.addSecondaryControl(audioOutputAction)
|
||||
if (isConference) {
|
||||
if (CurrentCall.isConference) {
|
||||
CallOverlayModel.addSecondaryControl(raiseHandAction)
|
||||
raiseHandAction.checked = CallAdapter.isHandRaised()
|
||||
}
|
||||
if (isModerator && !isSIP)
|
||||
if (CurrentCall.isModerator && !CurrentCall.isSIP)
|
||||
CallOverlayModel.addSecondaryControl(addPersonAction)
|
||||
if (isSIP) {
|
||||
if (CurrentCall.isSIP) {
|
||||
CallOverlayModel.addSecondaryControl(resumePauseCallAction)
|
||||
CallOverlayModel.addSecondaryControl(inputPanelSIPAction)
|
||||
CallOverlayModel.addSecondaryControl(callTransferAction)
|
||||
}
|
||||
CallOverlayModel.addSecondaryControl(chatAction)
|
||||
if (CurrentAccount.videoEnabled_Video)
|
||||
if (CurrentAccount.videoEnabled_Video && !CurrentCall.isSIP)
|
||||
CallOverlayModel.addSecondaryControl(shareAction)
|
||||
CallOverlayModel.addSecondaryControl(layoutAction)
|
||||
CallOverlayModel.addSecondaryControl(recordAction)
|
||||
if (pluginsAction.enabled)
|
||||
CallOverlayModel.addSecondaryControl(pluginsAction)
|
||||
overflowItemCount = CallOverlayModel.secondaryModel().rowCount()
|
||||
|
||||
muteAudioAction.checked = isAudioMuted
|
||||
recordAction.checked = CallAdapter.isRecordingThisCall()
|
||||
muteVideoAction.checked = isAudioOnly ? true : isVideoMuted
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
|
@ -39,6 +39,7 @@ ItemDelegate {
|
|||
|
||||
action: ItemAction
|
||||
checkable: ItemAction.checkable
|
||||
hoverEnabled: ItemAction.enabled
|
||||
|
||||
// hide the action's visual elements like the blurry looking icon
|
||||
icon.source: ""
|
||||
|
@ -122,7 +123,11 @@ ItemDelegate {
|
|||
|
||||
anchors.centerIn: parent
|
||||
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 {
|
||||
loops: Animation.Infinite
|
||||
|
@ -172,7 +177,8 @@ ItemDelegate {
|
|||
|
||||
indicator: null
|
||||
|
||||
visible: menuAction !== undefined && !UrgentCount && menuAction.enabled
|
||||
visible: ItemAction.enabled
|
||||
&& menuAction !== undefined && !UrgentCount && menuAction.enabled
|
||||
|
||||
y: isVertical ? 0 : -4
|
||||
x: isVertical ? -4 : 0
|
||||
|
|
|
@ -35,48 +35,11 @@ import "../../commoncomponents"
|
|||
Item {
|
||||
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 localHandRaised
|
||||
property bool sharingActive: AvAdapter.isSharing()
|
||||
property string callId: ""
|
||||
|
||||
signal chatButtonClicked
|
||||
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() {
|
||||
ContactPickerCreation.closeContactPicker()
|
||||
sipInputPanel.close()
|
||||
|
@ -94,29 +57,6 @@ Item {
|
|||
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 {
|
||||
anchors.fill: parent
|
||||
onDropped: function(drop) {
|
||||
|
@ -158,7 +98,7 @@ Item {
|
|||
width: 200
|
||||
height: 200
|
||||
|
||||
visible: false
|
||||
visible: CurrentCall.isPaused
|
||||
|
||||
source: JamiResources.ic_pause_white_100px_svg
|
||||
}
|
||||
|
@ -199,17 +139,10 @@ Item {
|
|||
PluginHandlerPickerCreation.openPluginHandlerPicker()
|
||||
}
|
||||
|
||||
function recordClicked() {
|
||||
CallAdapter.recordThisCallToggle()
|
||||
updateUI()
|
||||
}
|
||||
|
||||
MainOverlay {
|
||||
id: mainOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
isRecording: root.isRecording
|
||||
remoteRecording: root.remoteRecording
|
||||
|
||||
Connections {
|
||||
target: mainOverlay.callActionBar
|
||||
|
@ -222,7 +155,7 @@ Item {
|
|||
function onShareWindowClicked() { openShareWindow() }
|
||||
function onStopSharingClicked() { AvAdapter.stopSharing() }
|
||||
function onShareScreenAreaClicked() { openShareScreenArea() }
|
||||
function onRecordCallClicked() { recordClicked() }
|
||||
function onRecordCallClicked() { CallAdapter.recordThisCallToggle() }
|
||||
function onShareFileClicked() { jamiFileDialog.open() }
|
||||
function onPluginsClicked() { openPluginsMenu() }
|
||||
function onFullScreenClicked() { root.fullScreenClicked() }
|
||||
|
@ -232,13 +165,9 @@ Item {
|
|||
CallViewContextMenu {
|
||||
id: callViewContextMenu
|
||||
|
||||
isSIP: root.isSIP
|
||||
isPaused: root.isPaused
|
||||
isRecording: root.isRecording
|
||||
|
||||
onTransferCallButtonClicked: openContactPicker(ContactList.TRANSFER)
|
||||
onPluginItemClicked: openPluginsMenu()
|
||||
onRecordCallClicked: root.recordClicked()
|
||||
onRecordCallClicked: CallAdapter.recordThisCallToggle()
|
||||
onOpenSelectionWindow: {
|
||||
SelectScreenWindowCreation.createSelectScreenWindowObject(appWindow)
|
||||
SelectScreenWindowCreation.showSelectScreenWindow(callPreviewId, windowSelection)
|
||||
|
|
|
@ -28,7 +28,6 @@ import "../../commoncomponents"
|
|||
Rectangle {
|
||||
id: root
|
||||
|
||||
property bool isAudioOnly: false
|
||||
property var sipKeys: [
|
||||
"1", "2", "3", "A",
|
||||
"4", "5", "6", "B",
|
||||
|
@ -123,13 +122,6 @@ Rectangle {
|
|||
Connections {
|
||||
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) {
|
||||
if (callStackMainView.currentItem.stackNumber === CallStackView.InitialPageStack
|
||||
&& responsibleConvUid === convUid && responsibleAccountId === accountId) {
|
||||
|
@ -143,8 +135,6 @@ Rectangle {
|
|||
|
||||
property int stackNumber: CallStackView.OngoingPageStack
|
||||
|
||||
isAudioOnly: root.isAudioOnly
|
||||
|
||||
visible: callStackMainView.currentItem.stackNumber === stackNumber
|
||||
}
|
||||
|
||||
|
@ -153,8 +143,6 @@ Rectangle {
|
|||
|
||||
property int stackNumber: CallStackView.InitialPageStack
|
||||
|
||||
isAudioOnly: root.isAudioOnly
|
||||
|
||||
onCallAccepted: {
|
||||
CallAdapter.acceptACall(responsibleAccountId, responsibleConvUid)
|
||||
mainViewSidePanel.selectTab(SidePanelTabBar.Conversations)
|
||||
|
|
|
@ -31,11 +31,6 @@ import "../js/screenrubberbandcreation.js" as ScreenRubberBandCreation
|
|||
ContextMenuAutoLoader {
|
||||
id: root
|
||||
|
||||
property bool isSIP: false
|
||||
property bool isPaused: false
|
||||
property bool isVideoMuted: false
|
||||
property bool isRecording: false
|
||||
|
||||
property bool windowSelection: false
|
||||
|
||||
signal pluginItemClicked
|
||||
|
@ -47,9 +42,11 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: resumePauseCall
|
||||
|
||||
canTrigger: isSIP
|
||||
itemName: isPaused ? JamiStrings.resumeCall : JamiStrings.pauseCall
|
||||
iconSource: isPaused ?
|
||||
canTrigger: CurrentCall.isSIP
|
||||
itemName: CurrentCall.isPaused ?
|
||||
JamiStrings.resumeCall :
|
||||
JamiStrings.pauseCall
|
||||
iconSource: CurrentCall.isPaused ?
|
||||
JamiResources.play_circle_outline_24dp_svg :
|
||||
JamiResources.pause_circle_outline_24dp_svg
|
||||
onClicked: {
|
||||
|
@ -59,7 +56,7 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: inputPanelSIP
|
||||
|
||||
canTrigger: isSIP
|
||||
canTrigger: CurrentCall.isSIP
|
||||
itemName: JamiStrings.sipInputPanel
|
||||
iconSource: JamiResources.ic_keypad_svg
|
||||
onClicked: {
|
||||
|
@ -69,10 +66,10 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: callTransfer
|
||||
|
||||
canTrigger: isSIP
|
||||
canTrigger: CurrentCall.isSIP
|
||||
itemName: JamiStrings.transferCall
|
||||
iconSource: JamiResources.phone_forwarded_24dp_svg
|
||||
addMenuSeparatorAfter: isSIP
|
||||
addMenuSeparatorAfter: CurrentCall.isSIP
|
||||
onClicked: {
|
||||
root.transferCallButtonClicked()
|
||||
}
|
||||
|
@ -80,7 +77,9 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: localRecord
|
||||
|
||||
itemName: root.isRecording ? JamiStrings.stopRec : JamiStrings.startRec
|
||||
itemName: CurrentCall.isRecordingLocally ?
|
||||
JamiStrings.stopRec :
|
||||
JamiStrings.startRec
|
||||
iconSource: JamiResources.fiber_manual_record_24dp_svg
|
||||
iconColor: JamiTheme.recordIconColor
|
||||
onClicked: {
|
||||
|
@ -103,8 +102,9 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: stopSharing
|
||||
|
||||
canTrigger: AvAdapter.isSharing()
|
||||
&& !isSIP && !isVideoMuted
|
||||
canTrigger: CurrentCall.isSharing
|
||||
&& !CurrentCall.isSIP
|
||||
&& !CurrentCall.isVideoMuted
|
||||
itemName: JamiStrings.stopSharing
|
||||
iconSource: JamiResources.share_stop_black_24dp_svg
|
||||
iconColor: JamiTheme.redColor
|
||||
|
@ -113,8 +113,9 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: shareScreen
|
||||
|
||||
canTrigger: CurrentAccount.videoEnabled_Video && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||
&& !isSIP
|
||||
canTrigger: CurrentAccount.videoEnabled_Video
|
||||
&& AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||
&& !CurrentCall.isSIP
|
||||
itemName: JamiStrings.shareScreen
|
||||
iconSource: JamiResources.laptop_black_24dp_svg
|
||||
onClicked: {
|
||||
|
@ -129,8 +130,10 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: shareWindow
|
||||
|
||||
canTrigger: Qt.platform.os === "linux" && CurrentAccount.videoEnabled_Video && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||
&& !isSIP
|
||||
canTrigger: Qt.platform.os === "linux"
|
||||
&& CurrentAccount.videoEnabled_Video
|
||||
&& AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||
&& !CurrentCall.isSIP
|
||||
itemName: JamiStrings.shareWindow
|
||||
iconSource: JamiResources.window_black_24dp_svg
|
||||
onClicked: {
|
||||
|
@ -144,8 +147,9 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: shareScreenArea
|
||||
|
||||
canTrigger: CurrentAccount.videoEnabled_Video && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||
&& !isSIP
|
||||
canTrigger: CurrentAccount.videoEnabled_Video
|
||||
&& AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
|
||||
&& !CurrentCall.isSIP
|
||||
itemName: JamiStrings.shareScreenArea
|
||||
iconSource: JamiResources.share_area_black_24dp_svg
|
||||
onClicked: {
|
||||
|
@ -160,7 +164,8 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: shareFile
|
||||
|
||||
canTrigger: CurrentAccount.videoEnabled_Video && !isSIP
|
||||
canTrigger: CurrentAccount.videoEnabled_Video
|
||||
&& !CurrentCall.isSIP
|
||||
itemName: JamiStrings.shareFile
|
||||
iconSource: JamiResources.file_black_24dp_svg
|
||||
onClicked: {
|
||||
|
@ -170,7 +175,8 @@ ContextMenuAutoLoader {
|
|||
GeneralMenuItem {
|
||||
id: viewPlugin
|
||||
|
||||
canTrigger: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
|
||||
canTrigger: PluginAdapter.isEnabled &&
|
||||
PluginAdapter.callMediaHandlersListCount
|
||||
itemName: JamiStrings.viewPlugin
|
||||
iconSource: JamiResources.extension_24dp_svg
|
||||
onClicked: {
|
||||
|
|
|
@ -31,7 +31,7 @@ Rectangle {
|
|||
id: root
|
||||
|
||||
property bool isIncoming: false
|
||||
property bool isAudioOnly: false
|
||||
property bool isAudioOnly: CurrentCall.isAudioOnly
|
||||
property int callStatus: 0
|
||||
|
||||
signal callCanceled
|
||||
|
|
|
@ -32,7 +32,21 @@ Item {
|
|||
id: root
|
||||
|
||||
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
|
||||
|
||||
|
@ -43,8 +57,6 @@ Item {
|
|||
|
||||
property string muteAlertMessage: ""
|
||||
property bool muteAlertActive: false
|
||||
property bool remoteRecording: false
|
||||
property bool isRecording: false
|
||||
|
||||
onMuteAlertActiveChanged: {
|
||||
if (muteAlertActive) {
|
||||
|
@ -117,7 +129,7 @@ Item {
|
|||
root.timeText = CallAdapter.getCallDurationTime(
|
||||
LRCInstance.currentAccountId,
|
||||
LRCInstance.selectedConvUid)
|
||||
if (root.opacity === 0 && !root.remoteRecording)
|
||||
if (root.opacity === 0 && !CurrentCall.isRecordingRemotely)
|
||||
root.remoteRecordingLabel = ""
|
||||
}
|
||||
}
|
||||
|
@ -149,11 +161,11 @@ Item {
|
|||
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
text: {
|
||||
if (!root.isAudioOnly) {
|
||||
if (remoteRecordingLabel === "") {
|
||||
if (!CurrentCall.isAudioOnly) {
|
||||
if (root.remoteRecordingLabel === "") {
|
||||
return CurrentConversation.title
|
||||
} else {
|
||||
return remoteRecordingLabel
|
||||
return root.remoteRecordingLabel
|
||||
}
|
||||
}
|
||||
return ""
|
||||
|
@ -180,7 +192,7 @@ Item {
|
|||
|
||||
Rectangle {
|
||||
id: recordingRect
|
||||
visible: root.isRecording || root.remoteRecording
|
||||
visible: CurrentCall.isRecordingLocally || CurrentCall.isRecordingRemotely
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
Layout.rightMargin: JamiTheme.preferredMarginSize
|
||||
|
|
|
@ -42,9 +42,8 @@ Rectangle {
|
|||
property int previewMarginYBottom: previewMargin + 84
|
||||
property int previewToX: 0
|
||||
property int previewToY: 0
|
||||
property bool isAudioOnly: false
|
||||
property var linkedWebview: null
|
||||
property string callPreviewId: ""
|
||||
property string callPreviewId
|
||||
|
||||
onCallPreviewIdChanged: {
|
||||
controlPreview.start()
|
||||
|
@ -56,8 +55,6 @@ Rectangle {
|
|||
if (accountPeerPair[0] === "" || accountPeerPair[1] === "")
|
||||
return
|
||||
contactImage.imageId = accountPeerPair[1]
|
||||
distantRenderer.rendererId = UtilsAdapter.getCallId(accountPeerPair[0],
|
||||
accountPeerPair[1])
|
||||
}
|
||||
|
||||
function setLinkedWebview(webViewId) {
|
||||
|
@ -68,7 +65,6 @@ Rectangle {
|
|||
closeInCallConversation)
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: UtilsAdapter
|
||||
|
||||
|
@ -178,11 +174,12 @@ Rectangle {
|
|||
VideoView {
|
||||
id: distantRenderer
|
||||
|
||||
rendererId: CurrentCall.id
|
||||
anchors.centerIn: parent
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
|
||||
visible: participantsLayer.count === 0 && !root.isAudioOnly
|
||||
visible: !CurrentCall.isConference && !CurrentCall.isAudioOnly
|
||||
}
|
||||
|
||||
ParticipantsLayer {
|
||||
|
@ -190,17 +187,16 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
anchors.margins: 1
|
||||
visible: participantsLayer.count !== 0
|
||||
visible: CurrentCall.isConference
|
||||
participantsSide: callOverlay.participantsSide
|
||||
|
||||
onCountChanged: {
|
||||
callOverlay.isConference = participantsLayer.count > 0
|
||||
}
|
||||
}
|
||||
|
||||
LocalVideo {
|
||||
id: previewRenderer
|
||||
|
||||
visible: (CurrentCall.isSharing || !CurrentCall.isVideoMuted)
|
||||
&& !CurrentCall.isConference
|
||||
|
||||
height: width * invAspectRatio
|
||||
width: Math.max(callPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
|
||||
x: callPageMainRect.width - previewRenderer.width - previewMargin
|
||||
|
@ -217,6 +213,7 @@ Rectangle {
|
|||
previewRenderer.startWithId(rendId)
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
controlPreview.stop()
|
||||
if (visible) {
|
||||
|
@ -297,7 +294,6 @@ Rectangle {
|
|||
id: callOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
isConference: participantsLayer.count > 0
|
||||
|
||||
function toggleConversation() {
|
||||
if (inCallMessageWebViewStack.visible)
|
||||
|
@ -307,35 +303,19 @@ Rectangle {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
target: CurrentCall
|
||||
|
||||
function onUpdateOverlay(isPaused, isAudioOnly, isAudioMuted,
|
||||
isSIP, isGrid, previewId) {
|
||||
root.callPreviewId = previewId
|
||||
callOverlay.showOnHoldImage(isPaused)
|
||||
root.isAudioOnly = isAudioOnly
|
||||
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
|
||||
}
|
||||
|
||||
function onShowOnHoldLabel(isPaused) {
|
||||
callOverlay.showOnHoldImage(isPaused)
|
||||
audioCallPageRectCentralRect.visible = !isPaused && root.isAudioOnly && participantsLayer.count === 0
|
||||
}
|
||||
|
||||
function onRemoteRecordingChanged(label, state) {
|
||||
callOverlay.showRemoteRecording(label, state)
|
||||
}
|
||||
|
||||
function onEraseRemoteRecording() {
|
||||
callOverlay.resetRemoteRecording()
|
||||
function onPreviewIdChanged() {
|
||||
if (CurrentCall.previewId !== "") {
|
||||
if (root.callPreviewId !== "" &&
|
||||
root.callPreviewId !== CurrentCall.previewId) {
|
||||
VideoDevices.stopDevice(root.callPreviewId)
|
||||
}
|
||||
VideoDevices.startDevice(CurrentCall.previewId)
|
||||
} else {
|
||||
VideoDevices.stopDevice(root.callPreviewId)
|
||||
}
|
||||
root.callPreviewId = CurrentCall.previewId
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +347,9 @@ Rectangle {
|
|||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
visible: root.isAudioOnly
|
||||
visible: !CurrentCall.isPaused &&
|
||||
CurrentCall.isAudioOnly &&
|
||||
!CurrentCall.isConference
|
||||
|
||||
ConversationAvatar {
|
||||
id: contactImage
|
||||
|
|
|
@ -58,7 +58,7 @@ Popup {
|
|||
function onAboutToShow(visible) {
|
||||
// Reset the model on each show.
|
||||
if (isCall) {
|
||||
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
|
||||
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentCall.id)
|
||||
} else {
|
||||
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
||||
pluginhandlerPickerListView.model = PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
|
||||
|
@ -68,8 +68,8 @@ Popup {
|
|||
|
||||
function toggleHandlerSlot(handlerId, isLoaded) {
|
||||
if (isCall) {
|
||||
PluginModel.toggleCallMediaHandler(handlerId, CurrentConversation.callId, !isLoaded)
|
||||
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
|
||||
PluginModel.toggleCallMediaHandler(handlerId, CurrentCall.id, !isLoaded)
|
||||
pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentCall.id)
|
||||
} else {
|
||||
var accountId = LRCInstance.currentAccountId
|
||||
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
||||
|
@ -125,7 +125,7 @@ Popup {
|
|||
|
||||
model: {
|
||||
if (isCall) {
|
||||
return PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
|
||||
return PluginAdapter.getMediaHandlerSelectableModel(CurrentCall.id)
|
||||
} else {
|
||||
var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
|
||||
return PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "previewengine.h"
|
||||
#include "utilsadapter.h"
|
||||
#include "conversationsadapter.h"
|
||||
#include "currentcall.h"
|
||||
#include "currentconversation.h"
|
||||
#include "currentaccount.h"
|
||||
#include "videodevices.h"
|
||||
|
@ -118,6 +119,7 @@ registerTypes(QQmlEngine* engine,
|
|||
auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, parent);
|
||||
auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, parent);
|
||||
auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
|
||||
auto currentCall = new CurrentCall(lrcInstance, parent);
|
||||
auto currentConversation = new CurrentConversation(lrcInstance, parent);
|
||||
auto currentAccount = new CurrentAccount(lrcInstance, 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, utilsAdapter, "UtilsAdapter");
|
||||
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, currentAccount, "CurrentAccount");
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, videoDevices, "VideoDevices");
|
||||
|
|
|
@ -139,7 +139,7 @@ struct Info
|
|||
bool isAudioOnly = false;
|
||||
Layout layout = Layout::GRID;
|
||||
VectorMapStringString mediaList = {};
|
||||
QSet<QString> peerRec {};
|
||||
QStringList recordingPeers {};
|
||||
|
||||
bool hasMediaWithType(const QString& type, const QString& mediaType) const
|
||||
{
|
||||
|
|
|
@ -429,7 +429,7 @@ Q_SIGNALS:
|
|||
* Emitted when the rendered image changed
|
||||
* @param confId
|
||||
*/
|
||||
void onParticipantsChanged(const QString& confId) const;
|
||||
void participantsChanged(const QString& confId) const;
|
||||
/**
|
||||
* Emitted when a call starts
|
||||
* @param callId
|
||||
|
@ -469,15 +469,19 @@ Q_SIGNALS:
|
|||
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 contactId
|
||||
* @param peerName
|
||||
* @param state the new state
|
||||
* @param recorders
|
||||
*/
|
||||
void remoteRecordingChanged(const QString& callId,
|
||||
const QSet<QString>& peerRec,
|
||||
bool state) const;
|
||||
void remoteRecordersChanged(const QString& callId, const QStringList& recorders) 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
|
||||
|
@ -504,6 +508,11 @@ Q_SIGNALS:
|
|||
*/
|
||||
void callInfosChanged(const QString& accountId, const QString& callId) const;
|
||||
|
||||
/**
|
||||
* Emit currentCallChanged
|
||||
*/
|
||||
void currentCallChanged(const QString& callId) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<CallModelPimpl> pimpl_;
|
||||
};
|
||||
|
|
|
@ -201,6 +201,12 @@ CallbacksHandler::CallbacksHandler(const Lrc& parent)
|
|||
&CallbacksHandler::slotConferenceChanged,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(&CallManager::instance(),
|
||||
&CallManagerInterface::recordingStateChanged,
|
||||
this,
|
||||
&CallbacksHandler::recordingStateChanged,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(&CallManager::instance(),
|
||||
&CallManagerInterface::incomingMessage,
|
||||
this,
|
||||
|
@ -572,6 +578,12 @@ CallbacksHandler::slotConferenceCreated(const QString& accountId, const QString&
|
|||
Q_EMIT conferenceCreated(accountId, callId);
|
||||
}
|
||||
|
||||
void
|
||||
CallbacksHandler::slotConferenceRemoved(const QString& accountId, const QString& callId)
|
||||
{
|
||||
Q_EMIT conferenceRemoved(accountId, callId);
|
||||
}
|
||||
|
||||
void
|
||||
CallbacksHandler::slotConferenceChanged(const QString& accountId,
|
||||
const QString& callId,
|
||||
|
@ -581,12 +593,6 @@ CallbacksHandler::slotConferenceChanged(const QString& accountId,
|
|||
slotCallStateChanged(accountId, callId, state, 0);
|
||||
}
|
||||
|
||||
void
|
||||
CallbacksHandler::slotConferenceRemoved(const QString& accountId, const QString& callId)
|
||||
{
|
||||
Q_EMIT conferenceRemoved(accountId, callId);
|
||||
}
|
||||
|
||||
void
|
||||
CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
|
||||
const QString& conversationId,
|
||||
|
|
|
@ -377,6 +377,7 @@ Q_SIGNALS:
|
|||
void conversationPreferencesUpdated(const QString& accountId,
|
||||
const QString& conversationId,
|
||||
const MapStringString& preferences);
|
||||
void recordingStateChanged(const QString& callId, bool state);
|
||||
|
||||
/**
|
||||
* Emitted when a conversation receives a new position
|
||||
|
|
|
@ -259,9 +259,16 @@ public Q_SLOTS:
|
|||
/**
|
||||
* Listen from CallbacksHandler when the peer start recording
|
||||
* @param callId
|
||||
* @param peerUri
|
||||
* @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,
|
||||
|
@ -382,7 +389,7 @@ CallModel::createCall(const QString& uri, bool isAudioOnly, VectorMapStringStrin
|
|||
}
|
||||
#ifdef ENABLE_LIBWRAP
|
||||
auto callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList);
|
||||
#else // dbus
|
||||
#else // dbus
|
||||
// do not use auto here (QDBusPendingReply<QString>)
|
||||
QString callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList);
|
||||
#endif // ENABLE_LIBWRAP
|
||||
|
@ -975,7 +982,11 @@ CallModelPimpl::CallModelPimpl(const CallModel& linked,
|
|||
connect(&callbacksHandler,
|
||||
&CallbacksHandler::remoteRecordingChanged,
|
||||
this,
|
||||
&CallModelPimpl::remoteRecordingChanged);
|
||||
&CallModelPimpl::onRemoteRecordingChanged);
|
||||
connect(&callbacksHandler,
|
||||
&CallbacksHandler::recordingStateChanged,
|
||||
this,
|
||||
&CallModelPimpl::onRecordingStateChanged);
|
||||
|
||||
#ifndef ENABLE_LIBWRAP
|
||||
// Only necessary with dbus since the daemon runs separately
|
||||
|
@ -1140,7 +1151,7 @@ CallModel::setCurrentCall(const QString& callId) const
|
|||
}
|
||||
|
||||
if (!lrc::api::Lrc::holdConferences) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
// If the account is the host and it is attached to the conference,
|
||||
// then we should hold it.
|
||||
|
@ -1157,6 +1168,8 @@ CallModel::setCurrentCall(const QString& callId) const
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT currentCallChanged(callId);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1599,7 +1612,7 @@ CallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId,
|
|||
}
|
||||
}
|
||||
Q_EMIT linked.callInfosChanged(linked.owner.id, confId);
|
||||
Q_EMIT linked.onParticipantsChanged(confId);
|
||||
Q_EMIT linked.participantsChanged(confId);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1686,13 +1699,14 @@ CallModelPimpl::sendProfile(const QString& callId)
|
|||
}
|
||||
|
||||
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);
|
||||
if (it == calls.end() or not it->second)
|
||||
if (it == calls.end() or !it->second) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto uri = peerNumber;
|
||||
auto uri = peerUri;
|
||||
|
||||
if (uri.contains("ring:"))
|
||||
uri.remove("ring:");
|
||||
|
@ -1701,15 +1715,19 @@ CallModelPimpl::remoteRecordingChanged(const QString& callId, const QString& pee
|
|||
if (uri.contains("@ring.dht"))
|
||||
uri.remove("@ring.dht");
|
||||
|
||||
// Add peer to peerRec set
|
||||
if (state && not it->second->peerRec.contains(uri))
|
||||
it->second->peerRec.insert(uri);
|
||||
// Add/remove peer to recordingPeers, preventing duplicates.
|
||||
if (state && !it->second->recordingPeers.contains(uri))
|
||||
it->second->recordingPeers.append(uri);
|
||||
else if (!state && it->second->recordingPeers.contains(uri))
|
||||
it->second->recordingPeers.removeAll(uri);
|
||||
|
||||
// remove peer from peerRec set
|
||||
if (!state && it->second->peerRec.contains(uri))
|
||||
it->second->peerRec.remove(uri);
|
||||
Q_EMIT linked.remoteRecordersChanged(callId, it->second->recordingPeers);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue