update meeting list on day changed

fix text

fix #LINQT-1432 progress bar ui

try to fix #LINQT-1429 conference focus as active speaker
This commit is contained in:
Gaelle Braud 2024-11-29 11:59:44 +01:00
parent a3221e9d8e
commit 593863b4c2
12 changed files with 127 additions and 54 deletions

View file

@ -21,6 +21,7 @@
#include "ConferenceCore.hpp" #include "ConferenceCore.hpp"
#include "core/App.hpp" #include "core/App.hpp"
#include "model/conference/ConferenceModel.hpp" #include "model/conference/ConferenceModel.hpp"
#include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp" #include "tool/Utils.hpp"
#include "tool/thread/SafeConnection.hpp" #include "tool/thread/SafeConnection.hpp"
@ -39,6 +40,8 @@ ConferenceCore::ConferenceCore(const std::shared_ptr<linphone::Conference> &conf
mConferenceModel = ConferenceModel::create(conference); mConferenceModel = ConferenceModel::create(conference);
mSubject = Utils::coreStringToAppString(conference->getSubject()); mSubject = Utils::coreStringToAppString(conference->getSubject());
mParticipantDeviceCount = conference->getParticipantDeviceList().size(); mParticipantDeviceCount = conference->getParticipantDeviceList().size();
auto activeSpeaker = conference->getActiveSpeakerParticipantDevice();
if (activeSpeaker) mActiveSpeaker = ParticipantDeviceCore::create(activeSpeaker);
mIsLocalScreenSharing = mConferenceModel->isLocalScreenSharing(); mIsLocalScreenSharing = mConferenceModel->isLocalScreenSharing();
mIsScreenSharingEnabled = mConferenceModel->isScreenSharingEnabled(); mIsScreenSharingEnabled = mConferenceModel->isScreenSharingEnabled();
mIsRecording = conference->isRecording(); mIsRecording = conference->isRecording();
@ -67,7 +70,47 @@ void ConferenceCore::setSelf(QSharedPointer<ConferenceCore> me) {
mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); }); mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); });
}); });
mConferenceModelConnection->makeConnectToModel(&ConferenceModel::participantDeviceCountChanged, [this](int count) { mConferenceModelConnection->makeConnectToModel(
&ConferenceModel::conferenceStateChanged,
[this](const std::shared_ptr<linphone::Conference> &conference, linphone::Conference::State newState) {
if (newState != linphone::Conference::State::Created) return;
if (!mActiveSpeaker) {
if (auto participantDevice = conference->getActiveSpeakerParticipantDevice()) {
auto device = ParticipantDeviceCore::create(participantDevice);
mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); });
} else if (conference->getParticipantDeviceList().size() > 1) {
for (auto &device : conference->getParticipantDeviceList()) {
if (!ToolModel::isMe(device->getAddress())) {
auto activeSpeaker = ParticipantDeviceCore::create(device);
mConferenceModelConnection->invokeToCore(
[this, activeSpeaker]() { setActiveSpeaker(activeSpeaker); });
break;
}
}
}
}
int count = mConferenceModel->getParticipantDeviceCount();
mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); });
});
mConferenceModelConnection->makeConnectToModel(
&ConferenceModel::participantDeviceCountChanged,
[this](const std::shared_ptr<linphone::Conference> &conference, int count) {
if (!mActiveSpeaker) {
if (auto participantDevice = conference->getActiveSpeakerParticipantDevice()) {
auto device = ParticipantDeviceCore::create(participantDevice);
mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); });
} else if (conference->getParticipantDeviceList().size() > 1) {
for (auto &device : conference->getParticipantDeviceList()) {
if (!ToolModel::isMe(device->getAddress())) {
auto activeSpeaker = ParticipantDeviceCore::create(device);
mConferenceModelConnection->invokeToCore(
[this, activeSpeaker]() { setActiveSpeaker(activeSpeaker); });
break;
}
}
}
}
mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); }); mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); });
}); });
mConferenceModelConnection->makeConnectToModel(&ConferenceModel::isLocalScreenSharingChanged, [this]() { mConferenceModelConnection->makeConnectToModel(&ConferenceModel::isLocalScreenSharingChanged, [this]() {

View file

@ -42,6 +42,12 @@ QSharedPointer<ConferenceInfoList> ConferenceInfoList::create() {
ConferenceInfoList::ConferenceInfoList(QObject *parent) : ListProxy(parent) { ConferenceInfoList::ConferenceInfoList(QObject *parent) : ListProxy(parent) {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
connect(App::getInstance(), &App::currentDateChanged, this, [this] {
updateHaveCurrentDate();
int dummyIndex = -1;
get(nullptr, &dummyIndex);
if (dummyIndex != -1) emit dataChanged(index(dummyIndex, 0), index(dummyIndex, 0));
});
} }
ConferenceInfoList::~ConferenceInfoList() { ConferenceInfoList::~ConferenceInfoList() {
@ -161,9 +167,15 @@ void ConferenceInfoList::updateHaveCurrentDate() {
} }
int ConferenceInfoList::getCurrentDateIndex() { int ConferenceInfoList::getCurrentDateIndex() {
// Dummy item (nullptr) is QDate::currentDate() auto today = QDate::currentDate();
auto confInfoList = getSharedList<ConferenceInfoCore>(); auto confInfoList = getSharedList<ConferenceInfoCore>();
auto it = std::find(confInfoList.begin(), confInfoList.end(), nullptr); QList<QSharedPointer<ConferenceInfoCore>>::iterator it;
if (mHaveCurrentDate) {
it = std::find_if(confInfoList.begin(), confInfoList.end(),
[today](const QSharedPointer<ConferenceInfoCore> &item) {
return item && item->getDateTimeUtc().date() == today;
});
} else it = std::find(confInfoList.begin(), confInfoList.end(), nullptr);
return it == confInfoList.end() ? -1 : std::distance(confInfoList.begin(), it); return it == confInfoList.end() ? -1 : std::distance(confInfoList.begin(), it);
} }

View file

@ -22,6 +22,7 @@
#include "ConferenceInfoCore.hpp" #include "ConferenceInfoCore.hpp"
#include "ConferenceInfoGui.hpp" #include "ConferenceInfoGui.hpp"
#include "ConferenceInfoList.hpp" #include "ConferenceInfoList.hpp"
#include "core/App.hpp"
DEFINE_ABSTRACT_OBJECT(ConferenceInfoProxy) DEFINE_ABSTRACT_OBJECT(ConferenceInfoProxy)
@ -31,10 +32,14 @@ ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : LimitProxy(parent) {
connect( connect(
mList.get(), &ConferenceInfoList::haveCurrentDateChanged, this, mList.get(), &ConferenceInfoList::haveCurrentDateChanged, this,
[this] { [this] {
setCurrentDateIndex(getCurrentDateIndex());
auto sortModel = dynamic_cast<SortFilterList *>(sourceModel()); auto sortModel = dynamic_cast<SortFilterList *>(sourceModel());
sortModel->invalidate(); sortModel->invalidate();
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
connect(
App::getInstance(), &App::currentDateChanged, this, [this] { setCurrentDateIndex(getCurrentDateIndex()); },
Qt::QueuedConnection);
connect( connect(
mList.get(), &ConferenceInfoList::confInfoInserted, this, mList.get(), &ConferenceInfoList::confInfoInserted, this,
[this](int index, ConferenceInfoGui *data) { [this](int index, ConferenceInfoGui *data) {
@ -46,7 +51,8 @@ ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : LimitProxy(parent) {
} }
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
connect(mList.get(), &ConferenceInfoList::initialized, this, &ConferenceInfoProxy::initialized); connect(mList.get(), &ConferenceInfoList::initialized, this,
[this] { setCurrentDateIndex(getCurrentDateIndex()); });
} }
ConferenceInfoProxy::~ConferenceInfoProxy() { ConferenceInfoProxy::~ConferenceInfoProxy() {
@ -91,6 +97,14 @@ int ConferenceInfoProxy::getCurrentDateIndex() const {
return proxyIndex; return proxyIndex;
} }
void ConferenceInfoProxy::setCurrentDateIndex(int index) {
if (mCurrentDateIndex != index) {
if (index >= mMaxDisplayItems) setMaxDisplayItems(index + 1);
mCurrentDateIndex = index;
emit currentDateIndexChanged(index);
}
}
bool ConferenceInfoProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, bool ConferenceInfoProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft,
const QModelIndex &sourceRight) const { const QModelIndex &sourceRight) const {
auto l = getItemAtSource<ConferenceInfoList, ConferenceInfoCore>(sourceLeft.row()); auto l = getItemAtSource<ConferenceInfoList, ConferenceInfoCore>(sourceLeft.row());

View file

@ -44,11 +44,12 @@ public:
bool haveCurrentDate() const; bool haveCurrentDate() const;
Q_INVOKABLE int getCurrentDateIndex() const; Q_INVOKABLE int getCurrentDateIndex() const;
Q_INVOKABLE void setCurrentDateIndex(int index);
signals: signals:
void haveCurrentDateChanged(); void haveCurrentDateChanged();
void conferenceInfoCreated(int index); void conferenceInfoCreated(int index);
void initialized(); void currentDateIndexChanged(int index);
private: private:
QSharedPointer<ConferenceInfoList> mList; QSharedPointer<ConferenceInfoList> mList;

View file

@ -142,7 +142,8 @@ void ParticipantDeviceList::setSelf(QSharedPointer<ParticipantDeviceList> me) {
}); });
}); });
mConferenceModelConnection->makeConnectToModel( mConferenceModelConnection->makeConnectToModel(
&ConferenceModel::conferenceStateChanged, [this](linphone::Conference::State state) { &ConferenceModel::conferenceStateChanged,
[this](const std::shared_ptr<linphone::Conference> &conference, linphone::Conference::State state) {
lDebug() << "[ParticipantDeviceList] new state = " << (int)state; lDebug() << "[ParticipantDeviceList] new state = " << (int)state;
if (state == linphone::Conference::State::Created) { if (state == linphone::Conference::State::Created) {
lDebug() << "[ParticipantDeviceList] : build devices"; lDebug() << "[ParticipantDeviceList] : build devices";

View file

@ -175,13 +175,13 @@ void ConferenceModel::onParticipantAdded(const std::shared_ptr<linphone::Confere
const std::shared_ptr<linphone::Participant> &participant) { const std::shared_ptr<linphone::Participant> &participant) {
lDebug() << "onParticipant Added" << participant->getAddress()->asStringUriOnly(); lDebug() << "onParticipant Added" << participant->getAddress()->asStringUriOnly();
emit participantAdded(participant); emit participantAdded(participant);
emit participantDeviceCountChanged(getParticipantDeviceCount()); emit participantDeviceCountChanged(conference, getParticipantDeviceCount());
} }
void ConferenceModel::onParticipantRemoved(const std::shared_ptr<linphone::Conference> &conference, void ConferenceModel::onParticipantRemoved(const std::shared_ptr<linphone::Conference> &conference,
const std::shared_ptr<const linphone::Participant> &participant) { const std::shared_ptr<const linphone::Participant> &participant) {
lDebug() << "onParticipant Removed" << participant->getAddress()->asStringUriOnly(); lDebug() << "onParticipant Removed" << participant->getAddress()->asStringUriOnly();
emit participantRemoved(participant); emit participantRemoved(participant);
emit participantDeviceCountChanged(getParticipantDeviceCount()); emit participantDeviceCountChanged(conference, getParticipantDeviceCount());
} }
void ConferenceModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::Conference> &conference, void ConferenceModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::Conference> &conference,
const std::shared_ptr<linphone::ParticipantDevice> &participantDevice) { const std::shared_ptr<linphone::ParticipantDevice> &participantDevice) {
@ -191,7 +191,7 @@ void ConferenceModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::C
for (auto d : conference->getMe()->getDevices()) for (auto d : conference->getMe()->getDevices())
lDebug() << "\t--> " << d->getAddress()->asString().c_str(); lDebug() << "\t--> " << d->getAddress()->asString().c_str();
emit participantDeviceAdded(participantDevice); emit participantDeviceAdded(participantDevice);
emit participantDeviceCountChanged(getParticipantDeviceCount()); emit participantDeviceCountChanged(conference, getParticipantDeviceCount());
} }
void ConferenceModel::onParticipantDeviceRemoved( void ConferenceModel::onParticipantDeviceRemoved(
const std::shared_ptr<linphone::Conference> &conference, const std::shared_ptr<linphone::Conference> &conference,
@ -201,7 +201,7 @@ void ConferenceModel::onParticipantDeviceRemoved(
lDebug() << "Me devices : " << conference->getMe()->getDevices().size(); lDebug() << "Me devices : " << conference->getMe()->getDevices().size();
if (participantDevice->screenSharingEnabled()) emit isScreenSharingEnabledChanged(false); if (participantDevice->screenSharingEnabled()) emit isScreenSharingEnabledChanged(false);
emit participantDeviceRemoved(participantDevice); emit participantDeviceRemoved(participantDevice);
emit participantDeviceCountChanged(getParticipantDeviceCount()); emit participantDeviceCountChanged(conference, getParticipantDeviceCount());
} }
void ConferenceModel::onParticipantDeviceStateChanged(const std::shared_ptr<linphone::Conference> &conference, void ConferenceModel::onParticipantDeviceStateChanged(const std::shared_ptr<linphone::Conference> &conference,
const std::shared_ptr<const linphone::ParticipantDevice> &device, const std::shared_ptr<const linphone::ParticipantDevice> &device,
@ -257,11 +257,11 @@ void ConferenceModel::onStateChanged(const std::shared_ptr<linphone::Conference>
linphone::Conference::State newState) { linphone::Conference::State newState) {
lDebug() << "onStateChanged:" << (int)newState; lDebug() << "onStateChanged:" << (int)newState;
if (newState == linphone::Conference::State::Created) { if (newState == linphone::Conference::State::Created) {
emit participantDeviceCountChanged(mMonitor->getParticipantDeviceList().size()); emit participantDeviceCountChanged(conference, mMonitor->getParticipantDeviceList().size());
if (mMonitor->getScreenSharingParticipant()) emit isScreenSharingEnabledChanged(true); if (mMonitor->getScreenSharingParticipant()) emit isScreenSharingEnabledChanged(true);
} }
// updateLocalParticipant(); // updateLocalParticipant();
emit conferenceStateChanged(newState); emit conferenceStateChanged(conference, newState);
} }
void ConferenceModel::onSubjectChanged(const std::shared_ptr<linphone::Conference> &conference, void ConferenceModel::onSubjectChanged(const std::shared_ptr<linphone::Conference> &conference,
const std::string &subject) { const std::string &subject) {

View file

@ -75,7 +75,7 @@ signals:
void outputAudioDeviceChanged(const std::string &id); void outputAudioDeviceChanged(const std::string &id);
void isLocalScreenSharingChanged(bool enabled); void isLocalScreenSharingChanged(bool enabled);
void isScreenSharingEnabledChanged(bool enabled); void isScreenSharingEnabledChanged(bool enabled);
void participantDeviceCountChanged(int count); void participantDeviceCountChanged(const std::shared_ptr<linphone::Conference> &conference, int count);
private: private:
// LINPHONE LISTENERS // LINPHONE LISTENERS
@ -137,7 +137,8 @@ signals:
bool isSpeaking); bool isSpeaking);
void participantDeviceScreenSharingChanged(const std::shared_ptr<const linphone::ParticipantDevice> &device, void participantDeviceScreenSharingChanged(const std::shared_ptr<const linphone::ParticipantDevice> &device,
bool enabled); bool enabled);
void conferenceStateChanged(linphone::Conference::State newState); void conferenceStateChanged(const std::shared_ptr<linphone::Conference> &conference,
linphone::Conference::State newState);
void subjectChanged(const std::string &subject); void subjectChanged(const std::string &subject);
private: private:

View file

@ -237,6 +237,24 @@ std::shared_ptr<linphone::Account> ToolModel::findAccount(const QString &address
return findAccount(linAddr); return findAccount(linAddr);
} }
bool ToolModel::isLocal(const QString &address) {
auto linAddr = ToolModel::interpretUrl(address);
if (!CoreModel::getInstance()->getCore()->getDefaultAccount()) {
return false;
} else {
auto accountAddr = CoreModel::getInstance()->getCore()->getDefaultAccount()->getContactAddress();
return linAddr && accountAddr ? accountAddr->weakEqual(linAddr) : false;
}
}
bool ToolModel::isLocal(const std::shared_ptr<linphone::Conference> &conference,
const std::shared_ptr<const linphone::ParticipantDevice> &device) {
auto deviceAddress = device->getAddress();
auto callAddress = conference->getMe()->getAddress();
auto gruuAddress = findAccount(callAddress)->getContactAddress();
return deviceAddress->equal(gruuAddress);
}
bool ToolModel::isMe(const QString &address) { bool ToolModel::isMe(const QString &address) {
bool isMe = false; bool isMe = false;
auto linAddr = ToolModel::interpretUrl(address); auto linAddr = ToolModel::interpretUrl(address);
@ -252,16 +270,6 @@ bool ToolModel::isMe(const QString &address) {
return isMe; return isMe;
} }
bool ToolModel::isLocal(const QString &address) {
auto linAddr = ToolModel::interpretUrl(address);
if (!CoreModel::getInstance()->getCore()->getDefaultAccount()) {
return false;
} else {
auto accountAddr = CoreModel::getInstance()->getCore()->getDefaultAccount()->getContactAddress();
return linAddr && accountAddr ? accountAddr->weakEqual(linAddr) : false;
}
}
bool ToolModel::isMe(const std::shared_ptr<const linphone::Address> &address) { bool ToolModel::isMe(const std::shared_ptr<const linphone::Address> &address) {
auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
if (!currentAccount) { // Default account is selected : Me is all local accounts. if (!currentAccount) { // Default account is selected : Me is all local accounts.
@ -269,14 +277,6 @@ bool ToolModel::isMe(const std::shared_ptr<const linphone::Address> &address) {
} else return address ? currentAccount->getContactAddress()->weakEqual(address) : false; } else return address ? currentAccount->getContactAddress()->weakEqual(address) : false;
} }
bool ToolModel::isLocal(const std::shared_ptr<linphone::Conference> &conference,
const std::shared_ptr<const linphone::ParticipantDevice> &device) {
auto deviceAddress = device->getAddress();
auto callAddress = conference->getMe()->getAddress();
auto gruuAddress = findAccount(callAddress)->getContactAddress();
return deviceAddress->equal(gruuAddress);
}
std::shared_ptr<linphone::FriendList> ToolModel::getFriendList(const std::string &listName) { std::shared_ptr<linphone::FriendList> ToolModel::getFriendList(const std::string &listName) {
auto core = CoreModel::getInstance()->getCore(); auto core = CoreModel::getInstance()->getCore();
auto friendList = core->getFriendListByName(listName); auto friendList = core->getFriendListByName(listName);

View file

@ -37,11 +37,7 @@ ListView {
onConferenceInfoCreated: (index) => { onConferenceInfoCreated: (index) => {
mainItem.currentIndex = index mainItem.currentIndex = index
} }
onInitialized: { onCurrentDateIndexChanged: (index) => mainItem.currentIndex = index
var initIndex = confInfoProxy.getCurrentDateIndex()
if (initIndex >= maxDisplayItems) maxDisplayItems = initIndex + 1
mainItem.currentIndex = initIndex
}
} }
section { section {

View file

@ -12,7 +12,6 @@ ProgressBar {
property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0 property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0
property bool innerTextVisible: true property bool innerTextVisible: true
property string innerText: Number.parseFloat(value*100).toFixed(0) + "%" property string innerText: Number.parseFloat(value*100).toFixed(0) + "%"
property int barWidth: mainItem.visualPosition * mainItem.width property int barWidth: mainItem.visualPosition * mainItem.width
property bool centeredText: textSize.width >= barWidth property bool centeredText: textSize.width >= barWidth
@ -33,6 +32,7 @@ ProgressBar {
height: mainItem.height height: mainItem.height
} }
contentItem: Item { contentItem: Item {
id: content
Rectangle { Rectangle {
id: bar id: bar
color: mainItem.innerColor color: mainItem.innerColor
@ -43,13 +43,16 @@ ProgressBar {
Text { Text {
visible: mainItem.innerTextVisible visible: mainItem.innerTextVisible
text: mainItem.innerText text: mainItem.innerText
anchors.centerIn: mainItem.centeredText ? parent : bar parent: mainItem.centeredText ? content : bar
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: mainItem.innerTextColor color: mainItem.innerTextColor
maximumLineCount: 1
font { font {
pixelSize: 10 * DefaultStyle.dp pixelSize: 10 * DefaultStyle.dp
weight: 700 * DefaultStyle.dp weight: 700 * DefaultStyle.dp
} }
width: textSize.advanceWidth
} }
} }
} }

View file

@ -49,6 +49,8 @@ FocusScope{
_address: modelData _address: modelData
} }
Text { Text {
Layout.fillWidth: true
maximumLineCount: 1
property var nameObj: UtilsCpp.getDisplayName(modelData) property var nameObj: UtilsCpp.getDisplayName(modelData)
text: nameObj ? nameObj.value : "" text: nameObj ? nameObj.value : ""
font.pixelSize: 14 * DefaultStyle.dp font.pixelSize: 14 * DefaultStyle.dp