Fix camera/video activations when changing conference layout.

Fix missing camera button in one-one when video has been deactivated.
Test video enabled state on params instead of currentParams in order to know if we are in audio only mode.
Add a loading page when conference is not ready or if we are alone in the conference in audio only mode.
Remove outgoing call when calling a conference.
Fix crash on shutdown.
Fix closing window request after calling a conference from smart search bar.
This commit is contained in:
Julien Wadel 2022-08-23 17:56:32 +02:00
parent 5d39c913a7
commit 50e398c667
19 changed files with 183 additions and 89 deletions

View file

@ -33,7 +33,7 @@ public:
ProxyAbstractListModel (QObject *parent = Q_NULLPTR) : ProxyAbstractObject(parent) {}
virtual ~ProxyAbstractListModel(){
resetData();
clearData();
}
virtual int rowCount (const QModelIndex &index = QModelIndex()) const override{
@ -100,9 +100,13 @@ public:
return true;
}
virtual void clearData(){
mList.clear();
}
virtual void resetData(){
beginResetModel();
mList.clear();
clearData();
endResetModel();
}

View file

@ -32,7 +32,7 @@ public:
ProxyAbstractMapModel (QObject *parent = Q_NULLPTR) : ProxyAbstractObject(parent) {}
virtual ~ProxyAbstractMapModel(){
resetData();
clearData();
}
virtual int rowCount (const QModelIndex &index = QModelIndex()) const override{
@ -58,10 +58,8 @@ public:
return QVariant();
}
virtual void resetData() override{
beginResetModel();
virtual void clearData() override{
mMappedList.clear();
endResetModel();
}
protected:

View file

@ -38,6 +38,7 @@ public:
return rowCount();
}
Q_INVOKABLE virtual bool remove(QObject *itemToRemove){return false;}
Q_INVOKABLE virtual void clearData(){}
Q_INVOKABLE virtual void resetData(){}
signals:

View file

@ -237,7 +237,7 @@ QSharedPointer<ConferenceModel> CallModel::getConferenceSharedModel(){
bool CallModel::isConference () const{
// Check status to avoid crash when requesting a conference on an ended call.
return Utils::coreStringToAppString(mCall->getRemoteAddress()->asString()).toLower().contains("conf-id") || (getStatus() != CallStatusEnded && mCall->getConference() != nullptr);
return mCall && (Utils::coreStringToAppString(mCall->getRemoteAddress()->asString()).toLower().contains("conf-id") || (getStatus() != CallStatusEnded && mCall->getConference() != nullptr));
}
// -----------------------------------------------------------------------------
@ -471,6 +471,7 @@ void CallModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call,
break;
case linphone::Call::State::StreamsRunning: {
if (!mWasConnected && CoreManager::getInstance()->getSettingsModel()->getAutomaticallyRecordCalls()) {
startRecording();
mWasConnected = true;
@ -480,7 +481,7 @@ void CallModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call,
setCallId(QString::fromStdString(mCall->getCallLog()->getCallId()));
break;
}
case linphone::Call::State::Connected:
case linphone::Call::State::Connected: getConferenceSharedModel();
case linphone::Call::State::Referred:
case linphone::Call::State::Released:
mPausedByRemote = false;
@ -749,8 +750,8 @@ void CallModel::setCameraEnabled (bool status){
return;
shared_ptr<linphone::CallParams> params = core->createCallParams(mCall);
params->setVideoDirection(status ? linphone::MediaDirection::SendRecv : linphone::MediaDirection::RecvOnly);
params->enableVideo(true);
params->setVideoDirection(status ? linphone::MediaDirection::SendRecv : linphone::MediaDirection::RecvOnly);
mCall->update(params);
}
}
@ -788,6 +789,14 @@ bool CallModel::getRemoteVideoEnabled () const {
return params && params->videoEnabled();
}
bool CallModel::getLocalVideoEnabled () const {
if(mCall){
shared_ptr<const linphone::CallParams> params = mCall->getParams();
return params && params->videoEnabled();
}else
return true;
}
bool CallModel::getVideoEnabled () const {
if(mCall){
shared_ptr<const linphone::CallParams> params = mCall->getCurrentParams();
@ -979,7 +988,7 @@ std::shared_ptr<linphone::Address> CallModel::getRemoteAddress()const{
}
LinphoneEnums::ConferenceLayout CallModel::getConferenceVideoLayout() const{
return LinphoneEnums::fromLinphone(mCall->getParams()->getConferenceVideoLayout());
return mCall ? LinphoneEnums::fromLinphone(mCall->getParams()->getConferenceVideoLayout()) : LinphoneEnums::ConferenceLayoutGrid;
}
void CallModel::changeConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout){

View file

@ -70,6 +70,7 @@ class CallModel : public QObject {
Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged)
Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged)
Q_PROPERTY(bool localVideoEnabled READ getLocalVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged)
Q_PROPERTY(bool cameraEnabled READ getCameraEnabled WRITE setCameraEnabled NOTIFY statusChanged)
Q_PROPERTY(bool updating READ getUpdating NOTIFY statusChanged)
@ -264,6 +265,8 @@ public:
bool getPausedByUser () const;
void setPausedByUser (bool status);
bool getLocalVideoEnabled () const;
bool getVideoEnabled () const;
void setVideoEnabled (bool status);

View file

@ -222,7 +222,10 @@ ParticipantDeviceModel * Camera::getParticipantDeviceModel() const{
void Camera::setCallModel (CallModel *callModel) {
if (mCallModel != callModel) {
if( mCallModel)
disconnect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged);
mCallModel = callModel;
connect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged);
updateWindowIdLocation();
update();
@ -286,3 +289,10 @@ void Camera::deactivatePreview(){
mPreviewCounterMutex.unlock();
}
}
void Camera::onCallStateChanged(){
if( mCallModel->getStatus() == CallModel::CallStatusEnded){
resetWindowId();
mCallModel = nullptr;
}
}

View file

@ -68,6 +68,8 @@ public:
void isReady();
void isNotReady();
public slots:
void onCallStateChanged();
signals:
void callChanged (CallModel *callModel);

View file

@ -122,6 +122,13 @@ std::list<std::shared_ptr<linphone::Participant>> ConferenceModel::getParticipan
participantList.push_front(me);
return participantList;
}
void ConferenceModel::setIsReady(bool state){
if( mIsReady != state){
mIsReady = state;
emit isReadyChanged();
}
}
//-----------------------------------------------------------------------------------------------------------------------
// LINPHONE LISTENERS
//-----------------------------------------------------------------------------------------------------------------------
@ -169,6 +176,8 @@ void ConferenceModel::onParticipantDeviceIsSpeakingChanged(const std::shared_ptr
emit participantDeviceIsSpeakingChanged(participantDevice, isSpeaking);
}
void ConferenceModel::onConferenceStateChanged(linphone::Conference::State newState){
if(newState == linphone::Conference::State::Created)
setIsReady(true);
updateLocalParticipant();
emit conferenceStateChanged(newState);
}

View file

@ -41,6 +41,7 @@ public:
Q_PROPERTY(QDateTime startDate READ getStartDate CONSTANT)
Q_PROPERTY(ParticipantListModel* participants READ getParticipantListModel CONSTANT)
Q_PROPERTY(ParticipantModel* localParticipant READ getLocalParticipant NOTIFY localParticipantChanged)
Q_PROPERTY(bool isReady MEMBER mIsReady WRITE setIsReady NOTIFY isReadyChanged)
static QSharedPointer<ConferenceModel> create(std::shared_ptr<linphone::Conference> chatRoom, QObject *parent = Q_NULLPTR);
@ -56,6 +57,9 @@ public:
Q_INVOKABLE ParticipantModel* getLocalParticipant() const;
ParticipantListModel* getParticipantListModel() const;
std::list<std::shared_ptr<linphone::Participant>> getParticipantList() const; // SDK exclude me. We want to get ALL participants.
void setIsReady(bool state);
virtual void onParticipantAdded(const std::shared_ptr<const linphone::Participant> & participant);
virtual void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
@ -83,6 +87,7 @@ signals:
void participantDeviceStateChanged(const std::shared_ptr<const linphone::ParticipantDevice> & device, linphone::ParticipantDeviceState state);
void conferenceStateChanged(linphone::Conference::State newState);
void subjectChanged();
void isReadyChanged();
private:
void connectTo(ConferenceListener * listener);
@ -92,6 +97,7 @@ private:
QSharedPointer<ParticipantModel> mLocalParticipant;
QSharedPointer<ParticipantListModel> mParticipantListModel;
bool mIsReady = false;
};
Q_DECLARE_METATYPE(QSharedPointer<ConferenceModel>)

View file

@ -49,7 +49,7 @@ ConferenceProxyModel::ConferenceProxyModel (QObject *parent) : SortFilterProxyMo
bool ConferenceProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
const CallModel *callModel = index.data().value<CallModel *>();
return callModel->getCall()->getParams()->getLocalConferenceMode() || callModel->getCall()->getCurrentParams()->getLocalConferenceMode();
return callModel->getCall() && (callModel->getCall()->getParams()->getLocalConferenceMode() || callModel->getCall()->getCurrentParams()->getLocalConferenceMode());
}
// -----------------------------------------------------------------------------

View file

@ -39,25 +39,35 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (std::shared_ptr<linphone
connect(deviceModel.get(), &ParticipantDeviceModel::isSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceSpeaking);
mList << deviceModel;
}
mInitialized = true;
}
ParticipantDeviceListModel::ParticipantDeviceListModel (CallModel * callModel, QObject *parent) : ProxyListModel(parent) {
if(callModel && callModel->isConference()) {
mCallModel = callModel;
auto conferenceModel = callModel->getConferenceSharedModel();
updateDevices(conferenceModel->getConference()->getMe()->getDevices(), true);
updateDevices(conferenceModel->getConference()->getParticipantDeviceList(), false);
qDebug() << "Conference have " << mList.size() << " devices";
connect(conferenceModel.get(), &ConferenceModel::participantAdded, this, &ParticipantDeviceListModel::onParticipantAdded);
connect(conferenceModel.get(), &ConferenceModel::participantRemoved, this, &ParticipantDeviceListModel::onParticipantRemoved);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceAdded, this, &ParticipantDeviceListModel::onParticipantDeviceAdded);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceRemoved, this, &ParticipantDeviceListModel::onParticipantDeviceRemoved);
connect(conferenceModel.get(), &ConferenceModel::conferenceStateChanged, this, &ParticipantDeviceListModel::onConferenceStateChanged);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaCapabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaCapabilityChanged);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaAvailabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceIsSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged);
connect(mCallModel, &CallModel::conferenceModelChanged, this, &ParticipantDeviceListModel::onConferenceModelChanged);
initConferenceModel();
}
}
void ParticipantDeviceListModel::initConferenceModel(){
if(!mInitialized && mCallModel){
auto conferenceModel = mCallModel->getConferenceSharedModel();
if(conferenceModel){
updateDevices(conferenceModel->getConference()->getMe()->getDevices(), true);
updateDevices(conferenceModel->getConference()->getParticipantDeviceList(), false);
qDebug() << "Conference have " << mList.size() << " devices";
connect(conferenceModel.get(), &ConferenceModel::participantAdded, this, &ParticipantDeviceListModel::onParticipantAdded);
connect(conferenceModel.get(), &ConferenceModel::participantRemoved, this, &ParticipantDeviceListModel::onParticipantRemoved);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceAdded, this, &ParticipantDeviceListModel::onParticipantDeviceAdded);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceRemoved, this, &ParticipantDeviceListModel::onParticipantDeviceRemoved);
connect(conferenceModel.get(), &ConferenceModel::conferenceStateChanged, this, &ParticipantDeviceListModel::onConferenceStateChanged);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaCapabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaCapabilityChanged);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaAvailabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged);
connect(conferenceModel.get(), &ConferenceModel::participantDeviceIsSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged);
mInitialized = true;
}
}
}
@ -171,6 +181,12 @@ bool ParticipantDeviceListModel::isMeAlone() const{
return true;
}
void ParticipantDeviceListModel::onConferenceModelChanged (){
if(!mInitialized){
initConferenceModel();
}
}
void ParticipantDeviceListModel::onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device){
emit securityLevelChanged(device);
}

View file

@ -28,8 +28,8 @@
#include <QDateTime>
#include <QString>
#include "app/proxyModel/ProxyListModel.hpp"
#include "components/call/CallModel.hpp"
class CallModel;
class ParticipantDeviceModel;
class ParticipantDeviceListModel : public ProxyListModel {
@ -39,6 +39,7 @@ public:
ParticipantDeviceListModel (std::shared_ptr<linphone::Participant> participant, QObject *parent = nullptr);
ParticipantDeviceListModel (CallModel * callModel, QObject *parent = nullptr);
void initConferenceModel();
void updateDevices(std::shared_ptr<linphone::Participant> participant);
void updateDevices(const std::list<std::shared_ptr<linphone::ParticipantDevice>>& devices, const bool& isMe);
@ -52,6 +53,7 @@ public:
bool isMeAlone() const;
public slots:
void onConferenceModelChanged ();
void onSecurityLevelChanged(std::shared_ptr<const linphone::Address> device);
void onParticipantAdded(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
@ -71,6 +73,7 @@ signals:
private:
CallModel * mCallModel = nullptr;
QList<ParticipantDeviceModel*> mActiveSpeakers;// First item is last speaker
bool mInitialized = false;
};

View file

@ -33,10 +33,13 @@ Item {
property bool d : callModel && callModel.cameraEnabled
property bool isReady: cameraLoader.item && cameraLoader.item.isReady
property bool hadCall : false
onCallModelChanged: if(callModel) hadCall = true
signal videoDefinitionChanged()
onCurrentDeviceChanged: {if(container.isCameraFromDevice) resetActive()}
Component.onDestruction: isVideoEnabled=false
Component.onDestruction: if(!hadCall || (hadCall && callModel) ){isVideoEnabled=false}
function resetActive(){
resetTimer.resetActive()
}

View file

@ -113,7 +113,7 @@ Rectangle{
, visible: true},
{titleIndex: 1
, icon: (mainItem.callModel && mainItem.callModel.videoEnabled ?
, icon: (mainItem.callModel && mainItem.callModel.localVideoEnabled ?
(mainItem.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid ? IncallMenuStyle.settingsIcons.gridIcon : IncallMenuStyle.settingsIcons.activeSpeakerIcon)
: IncallMenuStyle.settingsIcons.audioOnlyIcon)
, nextPage:layoutMenu
@ -236,21 +236,24 @@ Rectangle{
text: modelData.text
// break bind. Radiobutton checked itself without taking care of custom binding. This workaound works as long as we don't really need the binding.
Component.onCompleted: checked = mainItem.callModel ? (mainItem.callModel.videoEnabled && modelData.value == mainItem.callModel.conferenceVideoLayout)
|| (!mainItem.callModel.videoEnabled && modelData.value == 2)
Component.onCompleted: checked = mainItem.callModel ? (mainItem.callModel.localVideoEnabled && modelData.value == mainItem.callModel.conferenceVideoLayout)
|| (!mainItem.callModel.localVideoEnabled && modelData.value == 2)
: false
Timer{
id: changingLayoutDelay
interval: 100
onTriggered: {if(modelData.value == 2) mainItem.callModel.videoEnabled = false
else mainItem.callModel.conferenceVideoLayout = modelData.value
else {
mainItem.callModel.conferenceVideoLayout = modelData.value
mainItem.callModel.videoEnabled = true
}
mainItem.enabled = true
}
}
onClicked:{
// Do changes only if we choose a different layout.
if(! ( mainItem.callModel ? (mainItem.callModel.videoEnabled && modelData.value == mainItem.callModel.conferenceVideoLayout)
|| (!mainItem.callModel.videoEnabled && modelData.value == 2)
if(! ( mainItem.callModel ? (mainItem.callModel.localVideoEnabled && modelData.value == mainItem.callModel.conferenceVideoLayout)
|| (!mainItem.callModel.localVideoEnabled && modelData.value == 2)
: false)){
mainItem.enabled = false
mainItem.layoutChanging(modelData.value)// Let time to clear cameras

View file

@ -89,19 +89,23 @@ function getContent (call, conferenceInfoModel) {
console.log("incomingCall")
return incomingCall
}
window.conferenceInfoModel = call.conferenceInfoModel;
if (status === CallModel.CallStatusOutgoing || status === CallModel.CallStatusEnded) {
console.log("Is conference ? "+call.isConference)
return waitingRoom
}
if(call.isConference){
console.log("incall")
if( window.conferenceInfoModel != call.conferenceInfoModel) {
Qt.callLater(function(){window.conferenceInfoModel = call.conferenceInfoModel})
return middlePane.sourceComponent // unchange. Wait for later decision on conference model (avoid binding loop on sourceComponent)
}else{
if(call.isConference){
console.log("incall")
return incall
}
if (status === CallModel.CallStatusOutgoing || status === CallModel.CallStatusEnded) {
console.log("Is conference ? "+call.isConference)
return waitingRoom
}
console.log("incall")
return incall
}
console.log("incall")
return incall
}
// -----------------------------------------------------------------------------

View file

@ -18,6 +18,7 @@ Window {
// `{}` is a workaround to avoid `TypeError: Cannot read property...` when calls list is empty
property CallModel call: calls.selectedCall
onCallChanged: if(!call && conferenceInfoModel) {conferenceInfoModel = null}
/*
?calls.selectedCall:{
callError: '',
@ -53,7 +54,6 @@ Window {
function endOfProcess(exitValue){
window.detachVirtualWindow();
if(exitValue == 0 && calls.count == 0 && middlePane.sourceComponent != waitingRoom) {
console.log("Closing")
close();
}
}
@ -84,6 +84,7 @@ Window {
id: mainPaned
anchors.fill: parent
defaultChildAWidth: CallsWindowStyle.callsList.defaultWidth
defaultClosed: true
maximumLeftLimit: CallsWindowStyle.callsList.maximumWidth
minimumLeftLimit: CallsWindowStyle.callsList.minimumWidth
@ -264,13 +265,18 @@ Window {
id: middlePane
anchors.fill: parent
sourceComponent: Logic.getContent(window.call, window.conferenceInfoModel)
property var lastComponent: null
onSourceComponentChanged: {
if( sourceComponent == waitingRoom)
mainPaned.close()
rightPaned.childAItem.update()
if(!sourceComponent && calls.count == 0)
window.close()
}// Force update when loading a new Content. It's just to be sure
if(lastComponent != sourceComponent){
if( sourceComponent == waitingRoom)
mainPaned.close()
rightPaned.childAItem.update()
if(!sourceComponent && calls.count == 0)
window.close()
lastComponent = sourceComponent
}
}// Force update when loading a new Content. It's just to be sure
active: window.call || window.conferenceInfoModel
}

View file

@ -183,7 +183,7 @@ Rectangle {
id: address
Layout.fillWidth: true
horizontalAlignment: Qt.AlignHCenter
visible: !conferenceModel && callModel
visible: !conferenceModel && callModel && !callModel.isConference
text: !conferenceModel && callModel
? callModel.peerAddress
: ''
@ -275,34 +275,48 @@ Rectangle {
}
RowLayout{
anchors.fill: parent
Loader{
id: conferenceLayout
Item{
Layout.fillHeight: true
Layout.fillWidth: true
sourceComponent: conference.conferenceModel
? conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid || !conference.callModel.videoEnabled? gridComponent : activeSpeakerComponent
: activeSpeakerComponent
onSourceComponentChanged: console.log("conferenceLayout: "+conference.callModel.conferenceVideoLayout)
active: conference.callModel
ColumnLayout {
Loader{
id: conferenceLayout
anchors.fill: parent
sourceComponent: conference.conferenceModel
? conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid || !conference.callModel.videoEnabled
? gridComponent
: activeSpeakerComponent
: activeSpeakerComponent
onSourceComponentChanged: console.log("conferenceLayout: "+conference.callModel.conferenceVideoLayout)
active: conference.callModel
}
Rectangle{
anchors.fill: parent
visible: !conference.callModel || !conferenceLayout.item || conferenceLayout.item.participantCount == 0
BusyIndicator{
Layout.preferredHeight: 50
Layout.preferredWidth: 50
Layout.alignment: Qt.AlignCenter
running: parent.visible
color: IncallStyle.buzyColor
}
Text{
Layout.alignment: Qt.AlignCenter
text: conference.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid && !conference.callModel.videoEnabled
//: 'Waiting for another participant...' : Waiting message for more participant.
? qsTr('incallWaitParticipantMessage')
//: 'Video conference is not ready. Please Wait...' : Waiting message for starting conference.
: qsTr('incallWaitMessage')
color: IncallStyle.buzyColor
color: conference.color
visible: !conference.callModel || (conference.callModel.isConference
&& (!conference.conferenceModel
|| (conference.conferenceModel && !conference.conferenceModel.isReady))
)
|| !conferenceLayout.item || conferenceLayout.item.participantCount == 0
|| (conferenceLayout.sourceComponent == gridComponent && !conference.callModel.videoEnabled && conferenceLayout.item.participantCount <= 1)
ColumnLayout {
anchors.fill: parent
BusyIndicator{
Layout.preferredHeight: 40
Layout.preferredWidth: 40
Layout.alignment: Qt.AlignCenter
running: parent.visible
color: IncallStyle.buzyColor
}
Text{
Layout.alignment: Qt.AlignCenter
text: conferenceLayout.sourceComponent == gridComponent && !conference.callModel.videoEnabled
//: 'Waiting for another participant...' : Waiting message for more participant.
? qsTr('incallWaitParticipantMessage')
//: 'Video conference is not ready. Please Wait...' : Waiting message for starting conference.
: qsTr('incallWaitMessage')
color: IncallStyle.buzyColor
}
}
}
}
@ -438,12 +452,13 @@ Rectangle {
backgroundRadius: 90
colorSet: callModel && callModel.cameraEnabled ? IncallStyle.buttons.cameraOn : IncallStyle.buttons.cameraOff
updating: callModel.videoEnabled && callModel.updating
visible: callModel && ( !callModel.isConference || callModel.videoEnabled)
visible: callModel && (!callModel.isConference || callModel.localVideoEnabled)
onClicked: if(callModel){
if( callModel.isConference)// Only deactivate camera in conference.
callModel.cameraEnabled = !callModel.cameraEnabled
else// In one-one, we deactivate all videos.
callModel.videoEnabled = !callModel.videoEnabled
if( callModel.isConference){// Only deactivate camera in conference.
callModel.cameraEnabled = !callModel.cameraEnabled
}else{// In one-one, we deactivate all videos.
callModel.videoEnabled = !callModel.videoEnabled
}
}
}

View file

@ -89,11 +89,13 @@ Item {
width: 16 * cellHeight / 9
model: mainItem.callModel.isConference
? mainItem.participantDevices
: mainItem.callModel.videoEnabled && !callModel.pausedByUser
? mainItem.participantDevices.showMe && mainItem.participantDevices.count <= 1
? []
: mainItem.participantDevices
: mainItem.callModel.localVideoEnabled && !callModel.pausedByUser
? [{videoEnabled:true, isPreview:true}]
: []
onModelChanged: console.log( mainItem.callModel.isConference+"/"+mainItem.callModel.videoEnabled + "/" +mainItem.callModel.cameraEnabled + " / " +count)
onModelChanged: console.log( mainItem.callModel.isConference+"/"+mainItem.callModel.localVideoEnabled + "/" +mainItem.callModel.cameraEnabled + " / " +count)
spacing: 15
verticalLayoutDirection: ItemView.BottomToTop
delegate:Item{

View file

@ -80,7 +80,7 @@ Rectangle {
font.pointSize: WaitingRoomStyle.elapsedTime.pointSize
horizontalAlignment: Text.AlignHCenter
width: parent.width
visible: mainItem.callModel
visible: mainItem.callModel && mainItem.isEnding
Timer {
interval: 1000
repeat: true
@ -139,10 +139,10 @@ Rectangle {
anchors.centerIn: parent
height: cameraHeight
width : cameraWidth
deactivateCamera: !mainItem.previewLoaderEnabled
callModel: mainItem.callModel
callModel: mainItem.callModel
conferenceInfoModel: mainItem.conferenceInfoModel
deactivateCamera: !mainItem.previewLoaderEnabled || mainItem.isEnding
/*
image: mainItem._sipAddressObserver && mainItem._sipAddressObserver.contact && mainItem._sipAddressObserver.contact.vcard.avatar