From 6325f6885cf87bb0036a3698ce4a1f88d3945851 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 8 Jul 2022 22:21:25 +0200 Subject: [PATCH] - Update to new API on participant joined/left. - Move active speaker managment to list instead of proxy (to be next to the new API state changes). - Update participants on conference created event to avoid losing me and other devices (SDK callbakcs are not usable before create event). - Fix selected active speaker when being in conference without participants. - Fix active speaker on new/left participants. - Protect mosaic transitions from deletion. - Username selection from IncallAvatar. - Deletion protection on camera when changing layouts by introducing a minor delay. - Shutdown preview when going out from waiting room. - Update design of waiting room. - Change flipping transition to opacity. - Update SDK (fix the camera reset of Active speaker when new participant) - Fix blanks lines in chat menu. --- .../conference/ConferenceListener.cpp | 10 --- .../conference/ConferenceListener.hpp | 4 - .../components/conference/ConferenceModel.cpp | 10 --- .../components/conference/ConferenceModel.hpp | 4 - .../ParticipantDeviceListModel.cpp | 86 +++++++++++-------- .../ParticipantDeviceListModel.hpp | 6 +- .../participant/ParticipantDeviceListener.cpp | 10 +-- .../participant/ParticipantDeviceListener.hpp | 6 +- .../participant/ParticipantDeviceModel.cpp | 20 +++-- .../participant/ParticipantDeviceModel.hpp | 3 +- .../ParticipantDeviceProxyModel.cpp | 16 ++-- .../ParticipantDeviceProxyModel.hpp | 2 +- .../participant/ParticipantListModel.cpp | 18 ---- .../participant/ParticipantListModel.hpp | 3 - .../ui/modules/Common/Form/Mosaic.qml | 2 + .../modules/Linphone/Calls/IncallAvatar.qml | 76 +++++++++------- .../ui/modules/Linphone/Camera/CameraItem.qml | 6 +- .../Linphone/Menus/VideoConferenceMenu.qml | 29 +++++-- .../Linphone/Sticker/AvatarSticker.qml | 7 +- .../Linphone/Sticker/CameraSticker.qml | 9 +- .../Linphone/Sticker/DecorationSticker.qml | 5 +- .../ui/modules/Linphone/Sticker/Sticker.qml | 72 ++++++++++------ .../ui/views/App/Calls/VideoConference.qml | 1 + .../Calls/VideoConferenceActiveSpeaker.qml | 28 ++++-- .../views/App/Calls/VideoConferenceGrid.qml | 10 ++- .../ui/views/App/Calls/WaitingRoom.qml | 15 ++-- .../ui/views/App/Main/Conversation.qml | 10 +-- linphone-sdk | 2 +- 28 files changed, 261 insertions(+), 209 deletions(-) diff --git a/linphone-app/src/components/conference/ConferenceListener.cpp b/linphone-app/src/components/conference/ConferenceListener.cpp index 07b2b633c..612821117 100644 --- a/linphone-app/src/components/conference/ConferenceListener.cpp +++ b/linphone-app/src/components/conference/ConferenceListener.cpp @@ -66,16 +66,6 @@ void ConferenceListener::onParticipantAdminStatusChanged(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){ - qDebug() << "onParticipantDeviceLeft"; - qDebug() << "Me devices : " << conference->getMe()->getDevices().size(); - emit participantDeviceLeft(participantDevice); -} -void ConferenceListener::onParticipantDeviceJoined(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){ - qDebug() << "onParticipantDeviceJoined"; - qDebug() << "Me devices : " << conference->getMe()->getDevices().size(); - emit participantDeviceJoined(participantDevice); -} void ConferenceListener::onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){ qDebug() << "onParticipantDeviceMediaCapabilityChanged: " << (int)participantDevice->getStreamCapability(linphone::StreamType::Video) << ". Device: " << participantDevice->getAddress()->asString().c_str(); emit participantDeviceMediaCapabilityChanged(participantDevice); diff --git a/linphone-app/src/components/conference/ConferenceListener.hpp b/linphone-app/src/components/conference/ConferenceListener.hpp index f7f744394..25b9f06c0 100644 --- a/linphone-app/src/components/conference/ConferenceListener.hpp +++ b/linphone-app/src/components/conference/ConferenceListener.hpp @@ -40,8 +40,6 @@ public: virtual void onParticipantAdminStatusChanged(const std::shared_ptr & conference, const std::shared_ptr & participant) override; virtual void onParticipantDeviceAdded(const std::shared_ptr & conference, const std::shared_ptr & participantDevice) override; virtual void onParticipantDeviceRemoved(const std::shared_ptr & conference, const std::shared_ptr & participantDevice) override; - virtual void onParticipantDeviceLeft(const std::shared_ptr & conference, const std::shared_ptr & device) override; - virtual void onParticipantDeviceJoined(const std::shared_ptr & conference, const std::shared_ptr & device) override; virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & conference, const std::shared_ptr & device) override; virtual void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr & conference, const std::shared_ptr & device) override; virtual void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & conference, const std::shared_ptr & participantDevice, bool isSpeaking) override; @@ -56,8 +54,6 @@ signals: void participantAdminStatusChanged(const std::shared_ptr & participant); void participantDeviceAdded(const std::shared_ptr & participantDevice); void participantDeviceRemoved(const std::shared_ptr & participantDevice); - void participantDeviceLeft(const std::shared_ptr & participantDevice); - void participantDeviceJoined(const std::shared_ptr & participantDevice); void participantDeviceMediaCapabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceMediaAvailabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking); diff --git a/linphone-app/src/components/conference/ConferenceModel.cpp b/linphone-app/src/components/conference/ConferenceModel.cpp index 8ab7c2c07..5f7dfc2d1 100644 --- a/linphone-app/src/components/conference/ConferenceModel.cpp +++ b/linphone-app/src/components/conference/ConferenceModel.cpp @@ -42,8 +42,6 @@ void ConferenceModel::connectTo(ConferenceListener * listener){ connect(listener, &ConferenceListener::participantAdminStatusChanged, this, &ConferenceModel::onParticipantAdminStatusChanged); connect(listener, &ConferenceListener::participantDeviceAdded, this, &ConferenceModel::onParticipantDeviceAdded); connect(listener, &ConferenceListener::participantDeviceRemoved, this, &ConferenceModel::onParticipantDeviceRemoved); - connect(listener, &ConferenceListener::participantDeviceLeft, this, &ConferenceModel::onParticipantDeviceLeft); - connect(listener, &ConferenceListener::participantDeviceJoined, this, &ConferenceModel::onParticipantDeviceJoined); connect(listener, &ConferenceListener::participantDeviceMediaCapabilityChanged, this, &ConferenceModel::onParticipantDeviceMediaCapabilityChanged); connect(listener, &ConferenceListener::participantDeviceMediaAvailabilityChanged, this, &ConferenceModel::onParticipantDeviceMediaAvailabilityChanged); connect(listener, &ConferenceListener::participantDeviceIsSpeakingChanged, this, &ConferenceModel::onParticipantDeviceIsSpeakingChanged); @@ -149,14 +147,6 @@ void ConferenceModel::onParticipantDeviceRemoved(const std::shared_ptrgetMe()->getDevices().size(); emit participantDeviceRemoved(participantDevice); } -void ConferenceModel::onParticipantDeviceLeft(const std::shared_ptr & participantDevice){ - qDebug() << "Me devices : " << mConference->getMe()->getDevices().size(); - emit participantDeviceLeft(participantDevice); -} -void ConferenceModel::onParticipantDeviceJoined(const std::shared_ptr & participantDevice){ - qDebug() << "Me devices : " << mConference->getMe()->getDevices().size(); - emit participantDeviceJoined(participantDevice); -} void ConferenceModel::onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & participantDevice){ qDebug() << "ConferenceModel::onParticipantDeviceMediaCapabilityChanged: " << (int)participantDevice->getStreamCapability(linphone::StreamType::Video) << ". Me devices : " << mConference->getMe()->getDevices().size(); emit participantDeviceMediaCapabilityChanged(participantDevice); diff --git a/linphone-app/src/components/conference/ConferenceModel.hpp b/linphone-app/src/components/conference/ConferenceModel.hpp index afa9d5d4c..86197a43e 100644 --- a/linphone-app/src/components/conference/ConferenceModel.hpp +++ b/linphone-app/src/components/conference/ConferenceModel.hpp @@ -62,8 +62,6 @@ public: virtual void onParticipantAdminStatusChanged(const std::shared_ptr & participant); virtual void onParticipantDeviceAdded(const std::shared_ptr & participantDevice); virtual void onParticipantDeviceRemoved(const std::shared_ptr & participantDevice); - virtual void onParticipantDeviceLeft(const std::shared_ptr & device); - virtual void onParticipantDeviceJoined(const std::shared_ptr & device); virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & device); virtual void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr & device); virtual void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & device, bool isSpeaking); @@ -78,8 +76,6 @@ signals: void participantAdminStatusChanged(const std::shared_ptr & participant); void participantDeviceAdded(const std::shared_ptr & participantDevice); void participantDeviceRemoved(const std::shared_ptr & participantDevice); - void participantDeviceLeft(const std::shared_ptr & participantDevice); - void participantDeviceJoined(const std::shared_ptr & participantDevice); void participantDeviceMediaCapabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceMediaAvailabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceIsSpeakingChanged(const std::shared_ptr & device, bool isSpeaking); diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp index e311b4f0d..51ff3b844 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp @@ -45,19 +45,15 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (CallModel * callModel, Q if(callModel && callModel->isConference()) { mCallModel = callModel; auto conferenceModel = callModel->getConferenceSharedModel(); - std::list> devices = conferenceModel->getConference()->getParticipantDeviceList(); - for(auto device : devices){ - auto deviceModel = ParticipantDeviceModel::create(mCallModel, device, isMe(device)); - connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged); - connect(deviceModel.get(), &ParticipantDeviceModel::isSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceSpeaking); - mList << deviceModel; - } + + 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::participantDeviceJoined, this, &ParticipantDeviceListModel::onParticipantDeviceJoined); - connect(conferenceModel.get(), &ConferenceModel::participantDeviceLeft, this, &ParticipantDeviceListModel::onParticipantDeviceLeft); connect(conferenceModel.get(), &ConferenceModel::conferenceStateChanged, this, &ParticipantDeviceListModel::onConferenceStateChanged); connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaCapabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaCapabilityChanged); connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaAvailabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged); @@ -80,6 +76,9 @@ void ParticipantDeviceListModel::updateDevices(std::shared_ptr>& devices, const bool& isMe){ + for(auto device : devices){ + add(device); + } } bool ParticipantDeviceListModel::add(std::shared_ptr deviceToAdd){ @@ -107,6 +106,7 @@ bool ParticipantDeviceListModel::remove(std::shared_ptr(); if( device->getDevice() == deviceToRemove){ device->updateVideoEnabled(); + mActiveSpeakers.removeAll(device.get()); removeRow(row); return true; }else @@ -129,6 +129,27 @@ QSharedPointer ParticipantDeviceListModel::get(std::shar return nullptr; } +QSharedPointer ParticipantDeviceListModel::getMe(int * index)const{ + int row = 0; + for(auto item : mList){ + auto device = item.objectCast(); + if( device->isMe()){ + if(index) + *index = row; + return device; + }else + ++row; + } + return nullptr; +} + +ParticipantDeviceModel* ParticipantDeviceListModel::getLastActiveSpeaking() const{ + if( mActiveSpeakers.size() == 0){ + return getMe().get(); + }else + return mActiveSpeakers.first(); +} + bool ParticipantDeviceListModel::isMe(std::shared_ptr deviceToCheck)const{ if(mCallModel){ auto devices = mCallModel->getConferenceSharedModel()->getConference()->getMe()->getDevices(); @@ -173,13 +194,20 @@ void ParticipantDeviceListModel::onParticipantRemoved(const std::shared_ptr & participantDevice){ qDebug() << "Adding new device : " << mList.count(); auto conferenceModel = mCallModel->getConferenceSharedModel(); - std::list> devices = conferenceModel->getConference()->getParticipantDeviceList(); - for(auto realParticipantDevice : devices){ - if( realParticipantDevice == participantDevice){ - add(realParticipantDevice); - return; + std::list> devices; + for(int i = 0 ; i < 2 ; ++i){ + if( i == 0) + devices = conferenceModel->getConference()->getParticipantDeviceList();// Active devices. + else + devices = conferenceModel->getConference()->getMe()->getDevices(); + for(auto realParticipantDevice : devices){ + if( realParticipantDevice == participantDevice){ + add(realParticipantDevice); + return; + } } } + qWarning() << "No participant device found from linphone::ParticipantDevice at onParticipantDeviceAdded"; } @@ -189,27 +217,6 @@ void ParticipantDeviceListModel::onParticipantDeviceRemoved(const std::shared_pt qWarning() << "No participant device found from linphone::ParticipantDevice at onParticipantDeviceRemoved"; } -void ParticipantDeviceListModel::onParticipantDeviceJoined(const std::shared_ptr & participantDevice){ - for(auto item : mList) { - auto device = item.objectCast(); - if(device->getDevice() == participantDevice) { - device->setPaused(false); - return; - } - } - onParticipantDeviceAdded(participantDevice); -} - -void ParticipantDeviceListModel::onParticipantDeviceLeft(const std::shared_ptr & participantDevice){ - for(auto item : mList) { - auto device = item.objectCast(); - if(device->getDevice() == participantDevice) { - device->setPaused(true); - return; - } - } -} - void ParticipantDeviceListModel::onConferenceStateChanged(linphone::Conference::State newState){ if(newState == linphone::Conference::State::Created){ if(mCallModel && mCallModel->isConference()) { @@ -217,6 +224,7 @@ void ParticipantDeviceListModel::onConferenceStateChanged(linphone::Conference:: updateDevices(conferenceModel->getConference()->getMe()->getDevices(), true); updateDevices(conferenceModel->getConference()->getParticipantDeviceList(), false); } + emit conferenceCreated(); } } @@ -252,5 +260,11 @@ void ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged(const std: void ParticipantDeviceListModel::onParticipantDeviceSpeaking(){ auto deviceModel = qobject_cast(sender()); - emit participantSpeaking(deviceModel); + bool changed = (mActiveSpeakers.removeAll(deviceModel) > 0); + if( mActiveSpeakers.size() == 0 || deviceModel->getIsSpeaking()) {// Ensure to have at least one last active speaker + mActiveSpeakers.push_front(deviceModel); + changed = true; + } + if(changed) + emit participantSpeaking(deviceModel); } diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp index 23e0940a8..55a510d19 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp @@ -45,6 +45,8 @@ public: bool add(std::shared_ptr deviceToAdd); bool remove(std::shared_ptr deviceToAdd); QSharedPointer get(std::shared_ptr deviceToGet, int * index = nullptr); + QSharedPointer getMe(int * index = nullptr)const; + ParticipantDeviceModel* getLastActiveSpeaking() const; bool isMe(std::shared_ptr device)const; bool isMeAlone() const; @@ -55,8 +57,6 @@ public slots: void onParticipantRemoved(const std::shared_ptr & participant); void onParticipantDeviceAdded(const std::shared_ptr & participantDevice); void onParticipantDeviceRemoved(const std::shared_ptr & participantDevice); - void onParticipantDeviceJoined(const std::shared_ptr & participantDevice); - void onParticipantDeviceLeft(const std::shared_ptr & participantDevice); void onConferenceStateChanged(linphone::Conference::State newState); void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & participantDevice); void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr & participantDevice); @@ -66,9 +66,11 @@ public slots: signals: void securityLevelChanged(std::shared_ptr device); void participantSpeaking(ParticipantDeviceModel *speakingDevice); + void conferenceCreated(); private: CallModel * mCallModel = nullptr; + QList mActiveSpeakers;// First item is last speaker }; diff --git a/linphone-app/src/components/participant/ParticipantDeviceListener.cpp b/linphone-app/src/components/participant/ParticipantDeviceListener.cpp index 4a04b54b3..512e8269e 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListener.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListener.cpp @@ -37,15 +37,11 @@ void ParticipantDeviceListener::onIsMuted(const std::shared_ptr & participantDevice) { - qDebug() << "onConferenceJoined: " << participantDevice->getAddress()->asString().c_str() << " isInConf?[" << participantDevice->isInConference() << "]"; - emit conferenceJoined(participantDevice); +void ParticipantDeviceListener::onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDeviceState state){ + qDebug() << "onStateChanged: " << participantDevice->getAddress()->asString().c_str() << " " << (int)state; + emit stateChanged(participantDevice, state); } -void ParticipantDeviceListener::onConferenceLeft(const std::shared_ptr & participantDevice) { - qDebug() << "onConferenceLeft: " << participantDevice->getAddress()->asString().c_str() << " isInConf?[" << participantDevice->isInConference() << "]"; - emit conferenceLeft(participantDevice); -} void ParticipantDeviceListener::onStreamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) { qDebug() << "onStreamCapabilityChanged: " << participantDevice->getAddress()->asString().c_str() << " " << (int)direction << " / " << (int)streamType; emit streamCapabilityChanged(participantDevice, direction, streamType); diff --git a/linphone-app/src/components/participant/ParticipantDeviceListener.hpp b/linphone-app/src/components/participant/ParticipantDeviceListener.hpp index f1f300048..4e6150947 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListener.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListener.hpp @@ -38,15 +38,13 @@ public: virtual void onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking) override; virtual void onIsMuted(const std::shared_ptr & participantDevice, bool isMuted) override; - virtual void onConferenceJoined(const std::shared_ptr & participantDevice) override; - virtual void onConferenceLeft(const std::shared_ptr & participantDevice) override; + virtual void onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDeviceState state) override; virtual void onStreamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) override; virtual void onStreamAvailabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType) override; signals: void isSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking); void isMuted(const std::shared_ptr & participantDevice, bool isMuted); - void conferenceJoined(const std::shared_ptr & participantDevice); - void conferenceLeft(const std::shared_ptr & participantDevice); + void stateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDeviceState state); void streamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType); void streamAvailabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType); }; diff --git a/linphone-app/src/components/participant/ParticipantDeviceModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceModel.cpp index 1c80b2046..1d8983b19 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceModel.cpp @@ -29,8 +29,7 @@ void ParticipantDeviceModel::connectTo(ParticipantDeviceListener * listener){ connect(listener, &ParticipantDeviceListener::isSpeakingChanged, this, &ParticipantDeviceModel::onIsSpeakingChanged); connect(listener, &ParticipantDeviceListener::isMuted, this, &ParticipantDeviceModel::onIsMuted); - connect(listener, &ParticipantDeviceListener::conferenceJoined, this, &ParticipantDeviceModel::onConferenceJoined); - connect(listener, &ParticipantDeviceListener::conferenceLeft, this, &ParticipantDeviceModel::onConferenceLeft); + connect(listener, &ParticipantDeviceListener::stateChanged, this, &ParticipantDeviceModel::onStateChanged); connect(listener, &ParticipantDeviceListener::streamCapabilityChanged, this, &ParticipantDeviceModel::onStreamCapabilityChanged); connect(listener, &ParticipantDeviceListener::streamAvailabilityChanged, this, &ParticipantDeviceModel::onStreamAvailabilityChanged); } @@ -163,10 +162,19 @@ void ParticipantDeviceModel::onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isMuted) { emit isMutedChanged(); } -void ParticipantDeviceModel::onConferenceJoined(const std::shared_ptr & participantDevice) { - updateVideoEnabled(); -} -void ParticipantDeviceModel::onConferenceLeft(const std::shared_ptr & participantDevice) { +void ParticipantDeviceModel::onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDeviceState state){ + switch(state){ + case linphone::ParticipantDeviceState::Joining: break; + case linphone::ParticipantDeviceState::Present: setPaused(false);break; + case linphone::ParticipantDeviceState::Leaving: break; + case linphone::ParticipantDeviceState::Left: break; + case linphone::ParticipantDeviceState::ScheduledForJoining: break; + case linphone::ParticipantDeviceState::ScheduledForLeaving: break; + case linphone::ParticipantDeviceState::OnHold: setPaused(true);break; + case linphone::ParticipantDeviceState::Alerting: break; + case linphone::ParticipantDeviceState::MutedByFocus: break; + default:{} + } updateVideoEnabled(); } void ParticipantDeviceModel::onStreamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) { diff --git a/linphone-app/src/components/participant/ParticipantDeviceModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceModel.hpp index 85f9a6cff..459c44f07 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceModel.hpp @@ -71,8 +71,7 @@ public: virtual void onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking); virtual void onIsMuted(const std::shared_ptr & participantDevice, bool isMuted); - virtual void onConferenceJoined(const std::shared_ptr & participantDevice); - virtual void onConferenceLeft(const std::shared_ptr & participantDevice); + virtual void onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDeviceState state); virtual void onStreamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType); virtual void onStreamAvailabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType); diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp index 2487afaca..d39fea18c 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp @@ -60,10 +60,8 @@ ParticipantDeviceModel *ParticipantDeviceProxyModel::getAt(int row){ } ParticipantDeviceModel* ParticipantDeviceProxyModel::getLastActiveSpeaking(){ - if( mActiveSpeakers.size() == 0) - return nullptr; - else - return mActiveSpeakers.first(); + auto listModel = qobject_cast(sourceModel()); + return listModel ? listModel->getLastActiveSpeaking() : nullptr; } CallModel * ParticipantDeviceProxyModel::getCallModel() const{ @@ -80,6 +78,7 @@ void ParticipantDeviceProxyModel::setCallModel(CallModel * callModel){ auto sourceModel = new ParticipantDeviceListModel(mCallModel); connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::onCountChanged); connect(sourceModel, &ParticipantDeviceListModel::participantSpeaking, this, &ParticipantDeviceProxyModel::onParticipantSpeaking); + connect(sourceModel, &ParticipantDeviceListModel::conferenceCreated, this, &ParticipantDeviceProxyModel::conferenceCreated); setSourceModel(sourceModel); emit countChanged(); } @@ -89,6 +88,7 @@ void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant) auto sourceModel = participant->getParticipantDevices().get(); connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::countChanged); connect(sourceModel, &ParticipantDeviceListModel::participantSpeaking, this, &ParticipantDeviceProxyModel::onParticipantSpeaking); + connect(sourceModel, &ParticipantDeviceListModel::conferenceCreated, this, &ParticipantDeviceProxyModel::conferenceCreated); setSourceModel(sourceModel); emit countChanged(); } @@ -106,11 +106,5 @@ void ParticipantDeviceProxyModel::onCountChanged(){ } void ParticipantDeviceProxyModel::onParticipantSpeaking(ParticipantDeviceModel * speakingDevice){ - bool changed = (mActiveSpeakers.removeAll(speakingDevice) > 0); - if( speakingDevice->getIsSpeaking()) { - mActiveSpeakers.push_front(speakingDevice); - changed = true; - } - if(changed) - emit participantSpeaking(speakingDevice); + emit participantSpeaking(speakingDevice); } \ No newline at end of file diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp index 59e8b3373..b8c468c4a 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.hpp @@ -62,6 +62,7 @@ signals: void callModelChanged(); void showMeChanged(); void participantSpeaking(ParticipantDeviceModel * speakingDevice); + void conferenceCreated(); protected: virtual bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; @@ -70,7 +71,6 @@ protected: QSharedPointer mDevices; CallModel * mCallModel; bool mShowMe = true; - QList mActiveSpeakers;// First item is last speaker }; #endif diff --git a/linphone-app/src/components/participant/ParticipantListModel.cpp b/linphone-app/src/components/participant/ParticipantListModel.cpp index 71863342c..d90a31daa 100644 --- a/linphone-app/src/components/participant/ParticipantListModel.cpp +++ b/linphone-app/src/components/participant/ParticipantListModel.cpp @@ -55,12 +55,10 @@ ParticipantListModel::ParticipantListModel (ConferenceModel * conferenceModel, Q mConferenceModel = conferenceModel; connect(mConferenceModel, &ConferenceModel::participantAdded, this, QOverload &>::of(&ParticipantListModel::onParticipantAdded)); - connect(mConferenceModel, &ConferenceModel::participantDeviceJoined, this, QOverload &>::of(&ParticipantListModel::onParticipantDeviceJoined)); connect(mConferenceModel, &ConferenceModel::participantRemoved, this, QOverload &>::of(&ParticipantListModel::onParticipantRemoved)); connect(mConferenceModel, &ConferenceModel::participantAdminStatusChanged, this, QOverload &>::of(&ParticipantListModel::onParticipantAdminStatusChanged)); connect(mConferenceModel, &ConferenceModel::conferenceStateChanged, this, &ParticipantListModel::onStateChanged); - updateParticipants(); } } @@ -317,22 +315,6 @@ void ParticipantListModel::onParticipantRemoved(const std::shared_ptr & eventLog){ - qDebug() << "onParticipantDeviceJoined event: " << eventLog->getParticipantAddress()->asString().c_str(); - updateParticipants(); -} - -void ParticipantListModel::onParticipantDeviceJoined(const std::shared_ptr & device){ - qDebug() << "onParticipantDeviceJoined part: " << device->getAddress()->asString().c_str(); - updateParticipants(); -} - -void ParticipantListModel::onParticipantDeviceJoined(const std::shared_ptr& address){ - qDebug() << "onParticipantDeviceJoined addr: " << address->asString().c_str(); - updateParticipants(); -} - - void ParticipantListModel::onParticipantAdminStatusChanged(const std::shared_ptr & eventLog){ onParticipantAdminStatusChanged(eventLog->getParticipantAddress()); } diff --git a/linphone-app/src/components/participant/ParticipantListModel.hpp b/linphone-app/src/components/participant/ParticipantListModel.hpp index d7d156cb2..5d09fab99 100644 --- a/linphone-app/src/components/participant/ParticipantListModel.hpp +++ b/linphone-app/src/components/participant/ParticipantListModel.hpp @@ -76,9 +76,6 @@ public slots: void onParticipantRemoved(const std::shared_ptr & participant); void onParticipantRemoved(const std::shared_ptr & eventLog); void onParticipantRemoved(const std::shared_ptr& address); - void onParticipantDeviceJoined(const std::shared_ptr & device); - void onParticipantDeviceJoined(const std::shared_ptr & eventLog); - void onParticipantDeviceJoined(const std::shared_ptr& address); void onParticipantAdminStatusChanged(const std::shared_ptr & participant); void onParticipantAdminStatusChanged(const std::shared_ptr & eventLog); void onParticipantAdminStatusChanged(const std::shared_ptr& address ); diff --git a/linphone-app/ui/modules/Common/Form/Mosaic.qml b/linphone-app/ui/modules/Common/Form/Mosaic.qml index 0f00cb570..9aba019bf 100644 --- a/linphone-app/ui/modules/Common/Form/Mosaic.qml +++ b/linphone-app/ui/modules/Common/Form/Mosaic.qml @@ -135,6 +135,7 @@ ColumnLayout{ moveDisplaced: defaultTransition remove: Transition { SequentialAnimation { + PropertyAction { target: grid; property: "GridView.delayRemove"; value: true } ScriptAction { script: { mainLayout.startTransition() @@ -144,6 +145,7 @@ ColumnLayout{ NumberAnimation { property: "opacity"; to: 0; duration: mainLayout.maxTransitionTime } NumberAnimation { properties: "x,y"; to: 0; duration: mainLayout.maxTransitionTime } } + PropertyAction { target: grid; property: "GridView.delayRemove"; value: false } } } removeDisplaced: defaultTransition diff --git a/linphone-app/ui/modules/Linphone/Calls/IncallAvatar.qml b/linphone-app/ui/modules/Linphone/Calls/IncallAvatar.qml index 318a90945..232572d19 100644 --- a/linphone-app/ui/modules/Linphone/Calls/IncallAvatar.qml +++ b/linphone-app/ui/modules/Linphone/Calls/IncallAvatar.qml @@ -10,40 +10,52 @@ import App.Styles 1.0 Avatar { id: mainItem - property var call - property var participantDeviceModel - property var _sipAddressObserver: call ? SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress) - : participantDeviceModel ? SipAddressesModel.getSipAddressObserver(participantDeviceModel.address, '') - : null - property var _username: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : '' - property bool isPaused: (call && (call.status === CallModel.CallStatusPaused)) || (participantDeviceModel && participantDeviceModel.isPaused) || false - - Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not. - - backgroundColor: CallStyle.container.avatar.backgroundColor - foregroundColor: mainItem.isPaused ? CallStyle.container.pause.color : 'transparent' - - image: { + property var call + property var participantDeviceModel + property ConferenceInfoModel conferenceInfoModel + property bool isPreview: false + property var _sipAddressObserver: participantDeviceModel + ? SipAddressesModel.getSipAddressObserver(participantDeviceModel.address, '') + : isPreview + ? SipAddressesModel.getSipAddressObserver( AccountSettingsModel.fullSipAddress, AccountSettingsModel.fullSipAddress) + : call + ? SipAddressesModel.getSipAddressObserver( call.fullPeerAddress, call.fullLocalAddress) + : null + property var _username: conferenceInfoModel + ? conferenceInfoModel.subject + : call && call.conferenceModel + ? call.conferenceModel.subject + : _sipAddressObserver + ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) + : '' + property bool isPaused: (call && (call.status === CallModel.CallStatusPaused)) || (participantDeviceModel && participantDeviceModel.isPaused) || false + + Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not. + + backgroundColor: CallStyle.container.avatar.backgroundColor + foregroundColor: mainItem.isPaused ? CallStyle.container.pause.color : 'transparent' + + image: { if (_sipAddressObserver) { var contact = _sipAddressObserver.contact - return contact && contact.vcard.avatar + return contact && contact.vcard.avatar }else return null; - } - - username: (mainItem.isPaused || !_username) ? '' : _username - Text { - anchors.fill: parent - color: CallStyle.container.pause.text.color - - // `|| 1` => `pointSize` must be greater than 0. - font.pointSize: (width / CallStyle.container.pause.text.pointSizeFactor) || 1 - - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - - text: '❙❙' - textFormat: Text.RichText - visible: mainItem.isPaused - } + } + + username: (mainItem.isPaused || !_username) ? '' : _username + Text { + anchors.fill: parent + color: CallStyle.container.pause.text.color + + // `|| 1` => `pointSize` must be greater than 0. + font.pointSize: (width / CallStyle.container.pause.text.pointSizeFactor) || 1 + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + text: '❙❙' + textFormat: Text.RichText + visible: mainItem.isPaused + } } diff --git a/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml b/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml index 310b38f17..ca92a8b76 100644 --- a/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml +++ b/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml @@ -18,11 +18,12 @@ Item { property bool isCameraFromDevice: true property ParticipantDeviceModel currentDevice property CallModel callModel - property bool isPreview: !callModel || !container.currentDevice || container.currentDevice.isMe + property bool isPreview: (!callModel && !container.currentDevice) || ( container.currentDevice && container.currentDevice.isMe) property bool isFullscreen: false property bool hideCamera: false property bool isPaused: false - property bool isVideoEnabled: (!callModel || callModel.videoEnabled) + property bool deactivateCamera: true + property bool isVideoEnabled: deactivateCamera && (!callModel || callModel.videoEnabled) && (!container.currentDevice || callModel && (container.currentDevice && (container.currentDevice.videoEnabled || (container.currentDevice.isMe && callModel.cameraEnabled)))) @@ -35,6 +36,7 @@ Item { signal videoDefinitionChanged() onCurrentDeviceChanged: {if(container.isCameraFromDevice) resetActive()} + Component.onDestruction: isVideoEnabled=false function resetActive(){ resetTimer.resetActive() } diff --git a/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml b/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml index 16ccd3e2a..03f99bc33 100644 --- a/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml +++ b/linphone-app/ui/modules/Linphone/Menus/VideoConferenceMenu.qml @@ -24,6 +24,7 @@ Rectangle{ property bool isMeAdmin: me && me.adminStatus property bool isParticipantsMenu: false signal close() + signal layoutChanging(int layoutMode) height: 500 width: 400 @@ -231,13 +232,31 @@ Rectangle{ Layout.leftMargin: 15 Layout.preferredHeight: contentItem.implicitHeight Layout.alignment: Qt.AlignVCenter - ButtonGroup.group: modeGroup - checked: mainItem.callModel ? (mainItem.callModel.videoEnabled && modelData.value == mainItem.callModel.conferenceVideoLayout) + ButtonGroup.group: modeGroup + 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) : false - text: modelData.text - onClicked: if(modelData.value == 2) mainItem.callModel.videoEnabled = false - else mainItem.callModel.conferenceVideoLayout = modelData.value + Timer{ + id: changingLayoutDelay + interval: 100 + onTriggered: {if(modelData.value == 2) mainItem.callModel.videoEnabled = false + else mainItem.callModel.conferenceVideoLayout = modelData.value + 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) + : false)){ + mainItem.enabled = false + mainItem.layoutChanging(modelData.value)// Let time to clear cameras + changingLayoutDelay.start() + } + } } Icon{ id: layoutIcon diff --git a/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml index 1172c9c97..df6e0849b 100644 --- a/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml +++ b/linphone-app/ui/modules/Linphone/Sticker/AvatarSticker.qml @@ -18,15 +18,17 @@ DecorationSticker { property ParticipantDeviceModel currentDevice property CallModel callModel property bool isPaused - property bool isPreview + property bool showCloseButton: false property bool showActiveSpeakerOverlay: true property real avatarRatio : 2/3 property color color : AvatarStickerStyle.stickerBackgroundColor property alias image: avatar.image - property alias username: avatar.username property alias avatarBackgroundColor: avatar.backgroundColor + property alias avatarUsername: avatar.username + property alias conferenceInfoModel: avatar.conferenceInfoModel + property alias isPreview: avatar.isPreview property bool showAvatarBorder: false property alias showCustomButton: mainItem._showCustomButton @@ -39,6 +41,7 @@ DecorationSticker { _isPreview: isPreview _showCloseButton: showCloseButton _showActiveSpeakerOverlay: showActiveSpeakerOverlay + username: avatarUsername clip:false radius: AvatarStickerStyle.radius diff --git a/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml index b121532c2..ac7852927 100644 --- a/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml +++ b/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml @@ -15,7 +15,7 @@ DecorationSticker{ id: mainItem property alias currentDevice: camera.currentDevice property alias callModel: camera.callModel - property bool cameraEnabled: true + property alias deactivateCamera: camera.deactivateCamera property alias hideCamera: camera.hideCamera property alias isPaused: camera.isPaused property alias isPreview: camera.isPreview @@ -32,7 +32,11 @@ DecorationSticker{ signal videoDefinitionChanged() onBackgroundClicked: camera.resetActive() - onCameraEnabledChanged: if( cameraEnabled) camera.resetActive() + onDeactivateCameraChanged: if( deactivateCamera) camera.resetActive() + + function resetCamera(){ + camera.resetActive(); + } _currentDevice: currentDevice _callModel: callModel @@ -59,7 +63,6 @@ DecorationSticker{ } CameraItem{ id: camera - currentDevice: mainItem.currentDevice callModel: mainItem.callModel anchors.centerIn: parent diff --git a/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml index 10f19a878..2e9e4000c 100644 --- a/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml +++ b/linphone-app/ui/modules/Linphone/Sticker/DecorationSticker.qml @@ -18,6 +18,8 @@ Item{ id: mainItem default property alias _content: content.data property alias speakingOverlayDisplayed: effect.visible + property alias username: username.text + property bool showUsername: true property ParticipantDeviceModel _currentDevice property CallModel _callModel @@ -76,7 +78,7 @@ Item{ } Text{ id: username - visible: mainItem._currentDevice + visible: mainItem.showUsername && mainItem._currentDevice anchors.right: parent.right anchors.left: parent.left anchors.bottom: parent.bottom @@ -90,6 +92,7 @@ Item{ } Glow { anchors.fill: username + visible: username.visible //spread: 1 radius: 12 samples: 25 diff --git a/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml b/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml index 8ab66e191..b4440ceb0 100644 --- a/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml +++ b/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml @@ -9,19 +9,21 @@ import Linphone 1.0 import Linphone.Styles 1.0 import 'qrc:/ui/scripts/Utils/utils.js' as Utils +import UtilsCpp 1.0 // A sticker display the avatar or its camera view // ============================================================================= -Flipable{ +Item{ id: mainItem - property bool flipped : cameraEnabled && camera.isReady + property bool flipped : deactivateCamera && camera.isReady property bool showCustomButton: false + property bool showUsername: true property bool customButtonToggled: false property QtObject customButtonColorSet: StickerStyle.custom @@ -32,42 +34,55 @@ Flipable{ property alias showCloseButton: camera.showCloseButton property alias showActiveSpeakerOverlay: camera.showActiveSpeakerOverlay property alias isCameraFromDevice: camera.isCameraFromDevice - property alias cameraEnabled: camera.cameraEnabled + property alias deactivateCamera: camera.deactivateCamera property alias image: avatar.image - property alias username: avatar.username property alias avatarBackgroundColor: avatar.avatarBackgroundColor property alias avatarStickerBackgroundColor: avatar.color property alias avatarRatio: avatar.avatarRatio property alias showAvatarBorder: avatar.showAvatarBorder + property alias avatarUsername: avatar.avatarUsername + property alias conferenceInfoModel: avatar.conferenceInfoModel signal videoDefinitionChanged() signal customButtonClicked() - clip:false + property alias username: avatar.username - transform: Rotation { - id: rotation - origin.x: mainItem.width/2 - origin.y: mainItem.height/2 - axis.x: 0; axis.y: 1; axis.z: 0 // set axis.y to 1 to rotate around y-axis - angle: 0 // the default angle - } - - states: State { - name: "back" - PropertyChanges { target: rotation; angle: 180 } - when: mainItem.flipped + function resetCamera(){ + camera.resetCamera() } - property bool quickTransition : flipped - transitions: Transition { - SequentialAnimation { - NumberAnimation { target: rotation; duration: quickTransition || rotation.angle != 0 ? 0 : 300 } - NumberAnimation { target: rotation; property: "angle"; duration: quickTransition ? 200 : 800 } + + clip:false + state: mainItem.flipped ? 'back' : 'front' + states: [State { + name: "front" + }, State { + name: "back" } - } - - front: AvatarSticker{ + ] + property bool quickTransition : false + property alias cameraOpacity: camera.opacity + transitions: [Transition { + from: 'front' + to: 'back' + SequentialAnimation { + NumberAnimation { target: mainItem; duration: quickTransition ? 0 : 400 } + NumberAnimation { target: camera; property: 'opacity'; to:1.0; duration: 100;} + } + }, + Transition { + from: 'back' + to: 'front' + SequentialAnimation { + NumberAnimation { target: mainItem; duration: 0 } + NumberAnimation { target: camera; property: 'opacity'; to:0.0; duration: 100;} + } + } + ] + + + AvatarSticker{ id: avatar currentDevice: mainItem.currentDevice callModel: mainItem.callModel @@ -75,6 +90,7 @@ Flipable{ isPreview: mainItem.isPreview showCloseButton: mainItem.showCloseButton showActiveSpeakerOverlay: mainItem.showActiveSpeakerOverlay + showUsername: mainItem.showUsername showCustomButton: mainItem.showCustomButton customButtonToggled: mainItem.customButtonToggled @@ -85,10 +101,14 @@ Flipable{ onCustomButtonClicked: mainItem.customButtonClicked() } - back: CameraSticker{ + + CameraSticker{ id: camera height: mainItem.height width: mainItem.width + opacity: 0.0 + username: mainItem.username + showUsername: mainItem.showUsername showCustomButton: mainItem.showCustomButton customButtonToggled: mainItem.customButtonToggled diff --git a/linphone-app/ui/views/App/Calls/VideoConference.qml b/linphone-app/ui/views/App/Calls/VideoConference.qml index 7beb9ebd8..12754c422 100644 --- a/linphone-app/ui/views/App/Calls/VideoConference.qml +++ b/linphone-app/ui/views/App/Calls/VideoConference.qml @@ -308,6 +308,7 @@ Rectangle { conferenceModel: conference.conferenceModel visible: false onClose: rightMenu.visible = !rightMenu.visible + onLayoutChanging: conferenceLayout.item.clearAll(layoutMode) } } } diff --git a/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml b/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml index e605eef38..a50f8394a 100644 --- a/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml +++ b/linphone-app/ui/views/App/Calls/VideoConferenceActiveSpeaker.qml @@ -6,6 +6,7 @@ import QtGraphicalEffects 1.12 import Common 1.0 import Common.Styles 1.0 import Linphone 1.0 +import LinphoneEnums 1.0 import UtilsCpp 1.0 @@ -26,29 +27,41 @@ Item { property bool cameraEnabled: true property alias showMe : allDevices.showMe property int participantCount: callModel.isConference ? allDevices.count : 2 + onParticipantCountChanged: {console.log("Conf count: " +participantCount);allDevices.updateCurrentDevice()} property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel { id: allDevices callModel: mainItem.callModel showMe: true - onParticipantSpeaking: { + onParticipantSpeaking: updateCurrentDevice() + property bool cameraEnabled: callModel && callModel.cameraEnabled + onCameraEnabledChanged: showMe = cameraEnabled // Do it on changed to ignore hard bindings (that can be override) + onConferenceCreated: cameraView.resetCamera() + function updateCurrentDevice(){ var device = getLastActiveSpeaking() if(device) // Get cameraView.currentDevice = device } - property bool cameraEnabled: callModel && callModel.cameraEnabled - onCameraEnabledChanged: showMe = cameraEnabled // Do it on changed to ignore hard bindings (that can be override) } + + function clearAll(layoutMode){ + if( layoutMode != LinphoneEnums.ConferenceLayoutActiveSpeaker){ + cameraView.cameraEnabled = false + miniViews.model = [] + } + } + Sticker{ id: cameraView callModel: mainItem.callModel - cameraEnabled: mainItem.cameraEnabled + deactivateCamera: mainItem.cameraEnabled && (!currentDevice || currentDevice.videoEnabled) isCameraFromDevice: false isPreview: false anchors.fill: parent anchors.leftMargin: isRightReducedLayout || isLeftReducedLayout? 30 : 140 anchors.rightMargin: isRightReducedLayout ? 10 : 140 isPaused: (callModel && callModel.pausedByUser) || (currentDevice && currentDevice.isPaused) //callModel.pausedByUser + quickTransition: true showCloseButton: false showActiveSpeakerOverlay: false // This is an active speaker. We don't need to show the indicator. showCustomButton: false @@ -83,11 +96,12 @@ Item { anchors.fill: parent anchors.margins: 3 - cameraEnabled: index >=0 && mainItem.cameraEnabled + deactivateCamera: index >=0 && ( (!modelData && mainItem.cameraEnabled) || modelData.videoEnabled) + //onCameraEnabledChanged: console.log(username +" => " +modelData.videoEnabled) currentDevice: modelData - callModel: mainItem.callModel.isConference ? mainItem.callModel : null + callModel: mainItem.callModel isCameraFromDevice: mainItem.callModel.isConference - isPaused: mainItem.callModel.pausedByUser || currentDevice && currentDevice.isPaused + isPaused: currentDevice && currentDevice.isPaused showCloseButton: false showCustomButton: false showAvatarBorder: true diff --git a/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml b/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml index d2064212f..c2c0ec172 100644 --- a/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml +++ b/linphone-app/ui/views/App/Calls/VideoConferenceGrid.qml @@ -6,6 +6,7 @@ import QtGraphicalEffects 1.12 import Common 1.0 import Common.Styles 1.0 import Linphone 1.0 +import LinphoneEnums 1.0 import UtilsCpp 1.0 @@ -28,7 +29,12 @@ Mosaic { // On grid view, we limit the quality if there are enough participants onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality() - + function clearAll(layoutMode){ + if( layoutMode != 2 && layoutMode != LinphoneEnums.ConferenceLayoutGrid){ + clear() + gridModel.model = [] + } + } delegateModel: DelegateModel{ id: gridModel property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel { @@ -52,7 +58,7 @@ Mosaic { id: cameraView anchors.fill: parent - cameraEnabled: index >=0 && grid.cameraEnabled + deactivateCamera: index >=0 && grid.cameraEnabled currentDevice: gridModel.participantDevices.getAt(index) callModel: participantDevices.callModel isCameraFromDevice: true diff --git a/linphone-app/ui/views/App/Calls/WaitingRoom.qml b/linphone-app/ui/views/App/Calls/WaitingRoom.qml index 0faa9dda1..3a1919b4a 100644 --- a/linphone-app/ui/views/App/Calls/WaitingRoom.qml +++ b/linphone-app/ui/views/App/Calls/WaitingRoom.qml @@ -133,14 +133,19 @@ Rectangle { height: cameraHeight width : cameraWidth - + deactivateCamera: mainItem.previewLoaderEnabled callModel: mainItem.callModel + conferenceInfoModel: mainItem.conferenceInfoModel + /* image: mainItem._sipAddressObserver && mainItem._sipAddressObserver.contact && mainItem._sipAddressObserver.contact.vcard.avatar + username: mainItem.conferenceInfoModel ? mainItem.conferenceInfoModel.subject : (mainItem._sipAddressObserver ? UtilsCpp.getDisplayName(mainItem._sipAddressObserver.peerAddress) : '') + */ avatarRatio: 2/3 - showCustomButton: true + showCustomButton: !mainItem.callModel + showUsername: false customButtonColorSet : WaitingRoomStyle.buttons.options customButtonToggled: mediaMenu.visible @@ -198,8 +203,8 @@ Rectangle { Layout.alignment: Qt.AlignCenter Layout.topMargin: 20 Layout.bottomMargin: 15 - //visible: mainItem.conferenceInfoModel - visible: false + visible: mainItem.conferenceInfoModel + spacing: 30 TextButtonA { //: 'Cancel' : Cancel button. @@ -282,7 +287,7 @@ Rectangle { isCustom: true backgroundRadius: width/2 colorSet: WaitingRoomStyle.buttons.call - visible: !callModel && conferenceInfoModel + visible: false && !callModel && conferenceInfoModel onClicked: {CallsListModel.launchVideoCall(conferenceInfoModel.uri, '', 0, { video: modeChoice.selectedMode != 2 , camera: camera.cameraEnabled diff --git a/linphone-app/ui/views/App/Main/Conversation.qml b/linphone-app/ui/views/App/Main/Conversation.qml index eefad1cb6..5342b9978 100644 --- a/linphone-app/ui/views/App/Main/Conversation.qml +++ b/linphone-app/ui/views/App/Main/Conversation.qml @@ -385,7 +385,7 @@ ColumnLayout { } } Rectangle{ - height:1 + height:visible ? 1 : 0 width:parent.width color: ConversationStyle.menu.separatorColor visible: groupInfoMenu.visible && contactMenu.visible @@ -405,10 +405,10 @@ ColumnLayout { } } Rectangle{ - height:1 + height:visible ? 1 : 0 width:parent.width color: ConversationStyle.menu.separatorColor - visible: groupInfoMenu.visible && (contactMenu.visible || devicesMenuItem.visible) + visible: devicesMenuItem.visible && (contactMenu.visible || groupInfoMenu.visible) } MenuItem{ id: devicesMenuItem @@ -425,7 +425,7 @@ ColumnLayout { } } Rectangle{ - height:1 + height:visible ? 1 : 0 width:parent.width color: ConversationStyle.menu.separatorColor visible: ephemeralMenuItem.visible && (contactMenu.visible || groupInfoMenu.visible || devicesMenuItem.visible) @@ -445,7 +445,7 @@ ColumnLayout { } } Rectangle{ - height:1 + height:visible ? 1 : 0 width:parent.width color: ConversationStyle.menu.separatorColor visible: deleteMenuItem.visible && (contactMenu.visible || groupInfoMenu.visible || devicesMenuItem.visible || ephemeralMenuItem.visible) diff --git a/linphone-sdk b/linphone-sdk index 70e789626..ae41a50f7 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit 70e7896263d7b91e33c03f81c04ad68f07333c84 +Subproject commit ae41a50f72902e6a139ba3a55c84879566848d31