- 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.
This commit is contained in:
Julien Wadel 2022-07-08 22:21:25 +02:00
parent 3c07c91c67
commit 6325f6885c
28 changed files with 261 additions and 209 deletions

View file

@ -66,16 +66,6 @@ void ConferenceListener::onParticipantAdminStatusChanged(const std::shared_ptr<l
qDebug() << "onParticipantAdminStatusChanged";
emit participantAdminStatusChanged(participant);
}
void ConferenceListener::onParticipantDeviceLeft(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "onParticipantDeviceLeft";
qDebug() << "Me devices : " << conference->getMe()->getDevices().size();
emit participantDeviceLeft(participantDevice);
}
void ConferenceListener::onParticipantDeviceJoined(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "onParticipantDeviceJoined";
qDebug() << "Me devices : " << conference->getMe()->getDevices().size();
emit participantDeviceJoined(participantDevice);
}
void ConferenceListener::onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "onParticipantDeviceMediaCapabilityChanged: " << (int)participantDevice->getStreamCapability(linphone::StreamType::Video) << ". Device: " << participantDevice->getAddress()->asString().c_str();
emit participantDeviceMediaCapabilityChanged(participantDevice);

View file

@ -40,8 +40,6 @@ public:
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant) override;
virtual void onParticipantDeviceAdded(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice) override;
virtual void onParticipantDeviceRemoved(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice) override;
virtual void onParticipantDeviceLeft(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
virtual void onParticipantDeviceJoined(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
virtual void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
virtual void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice, bool isSpeaking) override;
@ -56,8 +54,6 @@ signals:
void participantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
void participantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceMediaCapabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceMediaAvailabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceIsSpeakingChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice, bool isSpeaking);

View file

@ -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_ptr<const lin
qDebug() << "Me devices : " << mConference->getMe()->getDevices().size();
emit participantDeviceRemoved(participantDevice);
}
void ConferenceModel::onParticipantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "Me devices : " << mConference->getMe()->getDevices().size();
emit participantDeviceLeft(participantDevice);
}
void ConferenceModel::onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "Me devices : " << mConference->getMe()->getDevices().size();
emit participantDeviceJoined(participantDevice);
}
void ConferenceModel::onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "ConferenceModel::onParticipantDeviceMediaCapabilityChanged: " << (int)participantDevice->getStreamCapability(linphone::StreamType::Video) << ". Me devices : " << mConference->getMe()->getDevices().size();
emit participantDeviceMediaCapabilityChanged(participantDevice);

View file

@ -62,8 +62,6 @@ public:
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
virtual void onParticipantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
virtual void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
virtual void onParticipantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & device);
virtual void onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & device);
virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & device);
virtual void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & device);
virtual void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr<const linphone::ParticipantDevice> & device, bool isSpeaking);
@ -78,8 +76,6 @@ signals:
void participantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
void participantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceMediaCapabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceMediaAvailabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceIsSpeakingChanged(const std::shared_ptr<const linphone::ParticipantDevice> & device, bool isSpeaking);

View file

@ -45,19 +45,15 @@ ParticipantDeviceListModel::ParticipantDeviceListModel (CallModel * callModel, Q
if(callModel && callModel->isConference()) {
mCallModel = callModel;
auto conferenceModel = callModel->getConferenceSharedModel();
std::list<std::shared_ptr<linphone::ParticipantDevice>> 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<linphone::Partici
}
void ParticipantDeviceListModel::updateDevices(const std::list<std::shared_ptr<linphone::ParticipantDevice>>& devices, const bool& isMe){
for(auto device : devices){
add(device);
}
}
bool ParticipantDeviceListModel::add(std::shared_ptr<linphone::ParticipantDevice> deviceToAdd){
@ -107,6 +106,7 @@ bool ParticipantDeviceListModel::remove(std::shared_ptr<const linphone::Particip
auto device = item.objectCast<ParticipantDeviceModel>();
if( device->getDevice() == deviceToRemove){
device->updateVideoEnabled();
mActiveSpeakers.removeAll(device.get());
removeRow(row);
return true;
}else
@ -129,6 +129,27 @@ QSharedPointer<ParticipantDeviceModel> ParticipantDeviceListModel::get(std::shar
return nullptr;
}
QSharedPointer<ParticipantDeviceModel> ParticipantDeviceListModel::getMe(int * index)const{
int row = 0;
for(auto item : mList){
auto device = item.objectCast<ParticipantDeviceModel>();
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<linphone::ParticipantDevice> deviceToCheck)const{
if(mCallModel){
auto devices = mCallModel->getConferenceSharedModel()->getConference()->getMe()->getDevices();
@ -173,13 +194,20 @@ void ParticipantDeviceListModel::onParticipantRemoved(const std::shared_ptr<cons
void ParticipantDeviceListModel::onParticipantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "Adding new device : " << mList.count();
auto conferenceModel = mCallModel->getConferenceSharedModel();
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = conferenceModel->getConference()->getParticipantDeviceList();
for(auto realParticipantDevice : devices){
if( realParticipantDevice == participantDevice){
add(realParticipantDevice);
return;
std::list<std::shared_ptr<linphone::ParticipantDevice>> 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<const linphone::ParticipantDevice> & participantDevice){
for(auto item : mList) {
auto device = item.objectCast<ParticipantDeviceModel>();
if(device->getDevice() == participantDevice) {
device->setPaused(false);
return;
}
}
onParticipantDeviceAdded(participantDevice);
}
void ParticipantDeviceListModel::onParticipantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
for(auto item : mList) {
auto device = item.objectCast<ParticipantDeviceModel>();
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<ParticipantDeviceModel*>(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);
}

View file

@ -45,6 +45,8 @@ public:
bool add(std::shared_ptr<linphone::ParticipantDevice> deviceToAdd);
bool remove(std::shared_ptr<const linphone::ParticipantDevice> deviceToAdd);
QSharedPointer<ParticipantDeviceModel> get(std::shared_ptr<const linphone::ParticipantDevice> deviceToGet, int * index = nullptr);
QSharedPointer<ParticipantDeviceModel> getMe(int * index = nullptr)const;
ParticipantDeviceModel* getLastActiveSpeaking() const;
bool isMe(std::shared_ptr<linphone::ParticipantDevice> device)const;
bool isMeAlone() const;
@ -55,8 +57,6 @@ public slots:
void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onConferenceStateChanged(linphone::Conference::State newState);
void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
@ -66,9 +66,11 @@ public slots:
signals:
void securityLevelChanged(std::shared_ptr<const linphone::Address> device);
void participantSpeaking(ParticipantDeviceModel *speakingDevice);
void conferenceCreated();
private:
CallModel * mCallModel = nullptr;
QList<ParticipantDeviceModel*> mActiveSpeakers;// First item is last speaker
};

View file

@ -37,15 +37,11 @@ void ParticipantDeviceListener::onIsMuted(const std::shared_ptr<linphone::Partic
emit isMuted(participantDevice, isMutedVar);
}
void ParticipantDeviceListener::onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
qDebug() << "onConferenceJoined: " << participantDevice->getAddress()->asString().c_str() << " isInConf?[" << participantDevice->isInConference() << "]";
emit conferenceJoined(participantDevice);
void ParticipantDeviceListener::onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::ParticipantDeviceState state){
qDebug() << "onStateChanged: " << participantDevice->getAddress()->asString().c_str() << " " << (int)state;
emit stateChanged(participantDevice, state);
}
void ParticipantDeviceListener::onConferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
qDebug() << "onConferenceLeft: " << participantDevice->getAddress()->asString().c_str() << " isInConf?[" << participantDevice->isInConference() << "]";
emit conferenceLeft(participantDevice);
}
void ParticipantDeviceListener::onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) {
qDebug() << "onStreamCapabilityChanged: " << participantDevice->getAddress()->asString().c_str() << " " << (int)direction << " / " << (int)streamType;
emit streamCapabilityChanged(participantDevice, direction, streamType);

View file

@ -38,15 +38,13 @@ public:
virtual void onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking) override;
virtual void onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted) override;
virtual void onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) override;
virtual void onConferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) override;
virtual void onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::ParticipantDeviceState state) override;
virtual void onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) override;
virtual void onStreamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool available, linphone::StreamType streamType) override;
signals:
void isSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking);
void isMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted);
void conferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice);
void conferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice);
void stateChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::ParticipantDeviceState state);
void streamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType);
void streamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool available, linphone::StreamType streamType);
};

View file

@ -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<linphone:
void ParticipantDeviceModel::onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted) {
emit isMutedChanged();
}
void ParticipantDeviceModel::onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
updateVideoEnabled();
}
void ParticipantDeviceModel::onConferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice) {
void ParticipantDeviceModel::onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> & 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<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) {

View file

@ -71,8 +71,7 @@ public:
virtual void onIsSpeakingChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isSpeaking);
virtual void onIsMuted(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool isMuted);
virtual void onConferenceJoined(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice);
virtual void onConferenceLeft(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice);
virtual void onStateChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::ParticipantDeviceState state);
virtual void onStreamCapabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType);
virtual void onStreamAvailabilityChanged(const std::shared_ptr<linphone::ParticipantDevice> & participantDevice, bool available, linphone::StreamType streamType);

View file

@ -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<ParticipantDeviceListModel*>(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);
}

View file

@ -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<ParticipantDeviceListModel> mDevices;
CallModel * mCallModel;
bool mShowMe = true;
QList<ParticipantDeviceModel*> mActiveSpeakers;// First item is last speaker
};
#endif

View file

@ -55,12 +55,10 @@ ParticipantListModel::ParticipantListModel (ConferenceModel * conferenceModel, Q
mConferenceModel = conferenceModel;
connect(mConferenceModel, &ConferenceModel::participantAdded, this, QOverload<const std::shared_ptr<const linphone::Participant> &>::of(&ParticipantListModel::onParticipantAdded));
connect(mConferenceModel, &ConferenceModel::participantDeviceJoined, this, QOverload<const std::shared_ptr<const linphone::ParticipantDevice> &>::of(&ParticipantListModel::onParticipantDeviceJoined));
connect(mConferenceModel, &ConferenceModel::participantRemoved, this, QOverload<const std::shared_ptr<const linphone::Participant> &>::of(&ParticipantListModel::onParticipantRemoved));
connect(mConferenceModel, &ConferenceModel::participantAdminStatusChanged, this, QOverload<const std::shared_ptr<const linphone::Participant> &>::of(&ParticipantListModel::onParticipantAdminStatusChanged));
connect(mConferenceModel, &ConferenceModel::conferenceStateChanged, this, &ParticipantListModel::onStateChanged);
updateParticipants();
}
}
@ -317,22 +315,6 @@ void ParticipantListModel::onParticipantRemoved(const std::shared_ptr<const linp
remove(participant.get());
}
void ParticipantListModel::onParticipantDeviceJoined(const std::shared_ptr<const linphone::EventLog> & eventLog){
qDebug() << "onParticipantDeviceJoined event: " << eventLog->getParticipantAddress()->asString().c_str();
updateParticipants();
}
void ParticipantListModel::onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & device){
qDebug() << "onParticipantDeviceJoined part: " << device->getAddress()->asString().c_str();
updateParticipants();
}
void ParticipantListModel::onParticipantDeviceJoined(const std::shared_ptr<const linphone::Address>& address){
qDebug() << "onParticipantDeviceJoined addr: " << address->asString().c_str();
updateParticipants();
}
void ParticipantListModel::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> & eventLog){
onParticipantAdminStatusChanged(eventLog->getParticipantAddress());
}

View file

@ -76,9 +76,6 @@ public slots:
void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantRemoved(const std::shared_ptr<const linphone::Address>& address);
void onParticipantDeviceJoined(const std::shared_ptr<const linphone::ParticipantDevice> & device);
void onParticipantDeviceJoined(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantDeviceJoined(const std::shared_ptr<const linphone::Address>& address);
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Address>& address );

View file

@ -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

View file

@ -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: '&#10073;&#10073;'
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: '&#10073;&#10073;'
textFormat: Text.RichText
visible: mainItem.isPaused
}
}

View file

@ -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()
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -308,6 +308,7 @@ Rectangle {
conferenceModel: conference.conferenceModel
visible: false
onClose: rightMenu.visible = !rightMenu.visible
onLayoutChanging: conferenceLayout.item.clearAll(layoutMode)
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

@ -1 +1 @@
Subproject commit 70e7896263d7b91e33c03f81c04ad68f07333c84
Subproject commit ae41a50f72902e6a139ba3a55c84879566848d31