Allow participant device list model to get 'me' device.

Display the ActiveSpeaker even if alone.
Display preview rules :
- Hide if alone or if paused.
- Display at bottom-right if 2 participants.
- Display at top-right and make it persistent if more participants.
Put other participants at the bottom of the preview.
This commit is contained in:
Julien Wadel 2022-08-24 17:29:14 +02:00
parent 50e398c667
commit ab2c01ade7
6 changed files with 76 additions and 27 deletions

View file

@ -73,16 +73,22 @@ void ParticipantDeviceListModel::initConferenceModel(){
void ParticipantDeviceListModel::updateDevices(std::shared_ptr<linphone::Participant> participant){
std::list<std::shared_ptr<linphone::ParticipantDevice>> devices = participant->getDevices() ;
bool meAdded = false;
beginResetModel();
qDebug() << "Update devices from participant";
mList.clear();
for(auto device : devices){
auto deviceModel = ParticipantDeviceModel::create(mCallModel, device, isMe(device));
bool addMe = isMe(device);
auto deviceModel = ParticipantDeviceModel::create(mCallModel, device, addMe);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
connect(deviceModel.get(), &ParticipantDeviceModel::isSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceSpeaking);
mList << deviceModel;
if( addMe)
meAdded = true;
}
endResetModel();
if( meAdded)
emit meChanged();
}
void ParticipantDeviceListModel::updateDevices(const std::list<std::shared_ptr<linphone::ParticipantDevice>>& devices, const bool& isMe){
@ -101,12 +107,16 @@ bool ParticipantDeviceListModel::add(std::shared_ptr<linphone::ParticipantDevice
return false;
}
}
auto deviceModel = ParticipantDeviceModel::create(mCallModel, deviceToAdd, isMe(deviceToAdd));
bool addMe = isMe(deviceToAdd);
auto deviceModel = ParticipantDeviceModel::create(mCallModel, deviceToAdd, addMe);
connect(this, &ParticipantDeviceListModel::securityLevelChanged, deviceModel.get(), &ParticipantDeviceModel::onSecurityLevelChanged);
connect(deviceModel.get(), &ParticipantDeviceModel::isSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceSpeaking);
ProxyListModel::add<ParticipantDeviceModel>(deviceModel);
qDebug() << "Device added. Count=" << mList.count();
if( addMe){
qDebug() << "Added a me device";
emit meChanged();
}
return true;
}

View file

@ -69,6 +69,7 @@ signals:
void securityLevelChanged(std::shared_ptr<const linphone::Address> device);
void participantSpeaking(ParticipantDeviceModel *speakingDevice);
void conferenceCreated();
void meChanged();
private:
CallModel * mCallModel = nullptr;

View file

@ -68,6 +68,11 @@ CallModel * ParticipantDeviceProxyModel::getCallModel() const{
return mCallModel;
}
ParticipantDeviceModel * ParticipantDeviceProxyModel::getMe() const{
auto listModel = qobject_cast<ParticipantDeviceListModel*>(sourceModel());
return listModel ? listModel->getMe().get() : nullptr;
}
bool ParticipantDeviceProxyModel::isShowMe() const{
return mShowMe;
}
@ -79,6 +84,7 @@ void ParticipantDeviceProxyModel::setCallModel(CallModel * callModel){
connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::onCountChanged);
connect(sourceModel, &ParticipantDeviceListModel::participantSpeaking, this, &ParticipantDeviceProxyModel::onParticipantSpeaking);
connect(sourceModel, &ParticipantDeviceListModel::conferenceCreated, this, &ParticipantDeviceProxyModel::conferenceCreated);
connect(sourceModel, &ParticipantDeviceListModel::meChanged, this, &ParticipantDeviceProxyModel::meChanged);
setSourceModel(sourceModel);
emit countChanged();
}
@ -89,6 +95,7 @@ void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant)
connect(sourceModel, &ParticipantDeviceListModel::countChanged, this, &ParticipantDeviceProxyModel::countChanged);
connect(sourceModel, &ParticipantDeviceListModel::participantSpeaking, this, &ParticipantDeviceProxyModel::onParticipantSpeaking);
connect(sourceModel, &ParticipantDeviceListModel::conferenceCreated, this, &ParticipantDeviceProxyModel::conferenceCreated);
connect(sourceModel, &ParticipantDeviceListModel::meChanged, this, &ParticipantDeviceProxyModel::meChanged);
setSourceModel(sourceModel);
emit countChanged();
}

View file

@ -41,11 +41,13 @@ class ParticipantDeviceProxyModel : public SortFilterProxyModel {
public:
Q_PROPERTY(CallModel * callModel READ getCallModel WRITE setCallModel NOTIFY callModelChanged)
Q_PROPERTY(bool showMe READ isShowMe WRITE setShowMe NOTIFY showMeChanged)
Q_PROPERTY(ParticipantDeviceModel * me READ getMe NOTIFY meChanged)
ParticipantDeviceProxyModel (QObject *parent = nullptr);
Q_INVOKABLE ParticipantDeviceModel* getAt(int row);
Q_INVOKABLE ParticipantDeviceModel* getLastActiveSpeaking();
ParticipantDeviceModel * getMe() const;
CallModel * getCallModel() const;
bool isShowMe() const;
@ -61,6 +63,7 @@ public slots:
signals:
void callModelChanged();
void showMeChanged();
void meChanged();
void participantSpeaking(ParticipantDeviceModel * speakingDevice);
void conferenceCreated();

View file

@ -296,7 +296,7 @@ Rectangle {
&& (!conference.conferenceModel
|| (conference.conferenceModel && !conference.conferenceModel.isReady))
)
|| !conferenceLayout.item || conferenceLayout.item.participantCount == 0
|| !conferenceLayout.item
|| (conferenceLayout.sourceComponent == gridComponent && !conference.callModel.videoEnabled && conferenceLayout.item.participantCount <= 1)
ColumnLayout {
anchors.fill: parent

View file

@ -25,25 +25,18 @@ Item {
property bool isRightReducedLayout: false
property bool isLeftReducedLayout: false
property bool cameraEnabled: true
property alias showMe : allDevices.showMe
property bool showMe : !(callModel && callModel.pausedByUser)
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
function updateShowMe(){
showMe = cameraEnabled && !isPausedByUser
}
showMe: false
onParticipantSpeaking: updateCurrentDevice()
// Do it on changed to ignore hard bindings (that can be override)
property bool cameraEnabled: callModel && callModel.cameraEnabled
onCameraEnabledChanged:updateShowMe()
property bool isPausedByUser: callModel && callModel.pausedByUser
onIsPausedByUserChanged: updateShowMe()
//-----
onConferenceCreated: cameraView.resetCamera()
function updateCurrentDevice(){
@ -77,27 +70,63 @@ Item {
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor
}
Item{// Need an item to not override Sticker internal states. States are needed for changing anchors.
id: preview
anchors.right: parent.right
anchors.rightMargin: 30
anchors.topMargin: 30
anchors.bottomMargin: 30
height: miniViews.cellHeight
width: 16 * height / 9
Sticker{
anchors.fill: parent
visible: mainItem.showMe && allDevices.count >= 1
anchors.margins: 3
deactivateCamera: !mainItem.callModel || !mainItem.showMe || !mainItem.callModel.localVideoEnabled
currentDevice: allDevices.me
isPreview: true
callModel: mainItem.callModel
isCameraFromDevice: true
showCloseButton: false
showCustomButton: false
showAvatarBorder: true
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor
}
state: allDevices.count < 2 ? 'bottom' : 'top'
states: [State {
name: "bottom"
AnchorChanges {
target: preview
anchors.top: undefined
anchors.bottom: mainItem.bottom
}
},
State {
name: "top"
AnchorChanges {
target: preview
anchors.top: mainItem.top
anchors.bottom: undefined
}
}]
}
ScrollableListView{
id: miniViews
anchors.right: parent.right
anchors.top: parent.top
anchors.top: preview.bottom
anchors.bottom: parent.bottom
anchors.rightMargin: 30
anchors.topMargin: 30
anchors.topMargin: 15
anchors.bottomMargin: 30
property int cellHeight: 150
width: 16 * cellHeight / 9
model: mainItem.callModel.isConference
? mainItem.participantDevices.showMe && mainItem.participantDevices.count <= 1
? []
: mainItem.participantDevices
: mainItem.callModel.localVideoEnabled && !callModel.pausedByUser
? [{videoEnabled:true, isPreview:true}]
: []
model: mainItem.callModel.isConference && mainItem.participantDevices.count > 1 ? mainItem.participantDevices : []
onModelChanged: console.log( mainItem.callModel.isConference+"/"+mainItem.callModel.localVideoEnabled + "/" +mainItem.callModel.cameraEnabled + " / " +count)
spacing: 15
verticalLayoutDirection: ItemView.BottomToTop
delegate:Item{
height: miniViews.cellHeight
width: miniViews.width
@ -116,7 +145,6 @@ Item {
showAvatarBorder: true
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor
//onCloseRequested: mainItem.showMe = false
}
}
}