loading ui meeting list

This commit is contained in:
Gaelle Braud 2025-08-25 10:34:45 +02:00
parent d3360cdbf8
commit 54eac3ddc1
7 changed files with 94 additions and 14 deletions

View file

@ -63,9 +63,13 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
QList<QSharedPointer<ConferenceInfoCore>> *items = new QList<QSharedPointer<ConferenceInfoCore>>(); QList<QSharedPointer<ConferenceInfoCore>> *items = new QList<QSharedPointer<ConferenceInfoCore>>();
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
if (!defaultAccount) return; setAccountConnected(defaultAccount && defaultAccount->getState() == linphone::RegistrationState::Ok);
if (!defaultAccount || !mAccountConnected) {
return;
}
std::list<std::shared_ptr<linphone::ConferenceInfo>> conferenceInfos = std::list<std::shared_ptr<linphone::ConferenceInfo>> conferenceInfos =
defaultAccount->getConferenceInformationList(); defaultAccount->getConferenceInformationList();
if (conferenceInfos.empty()) return;
items->push_back(nullptr); // Add Dummy conference for today items->push_back(nullptr); // Add Dummy conference for today
for (auto conferenceInfo : conferenceInfos) { for (auto conferenceInfo : conferenceInfos) {
if (conferenceInfo->getState() == linphone::ConferenceInfo::State::Cancelled) { if (conferenceInfo->getState() == linphone::ConferenceInfo::State::Cancelled) {
@ -75,8 +79,6 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
auto confInfoCore = build(conferenceInfo); auto confInfoCore = build(conferenceInfo);
// Cancelled conference organized ourself me must be hidden // Cancelled conference organized ourself me must be hidden
if (confInfoCore) { if (confInfoCore) {
// qDebug() << log().arg("Add conf") << confInfoCore->getSubject() << "with state"
// << confInfoCore->getConferenceInfoState();
items->push_back(confInfoCore); items->push_back(confInfoCore);
} }
} }
@ -94,11 +96,6 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
}); });
}); });
// This is needed because account does not have a contact address until
// it is connected, so we can't verify if it is the organizer of a deleted
// conference (which must hidden)
mCoreModelConnection->makeConnectToModel(&CoreModel::defaultAccountChanged, [this]() { emit lUpdate(true); });
mCoreModelConnection->makeConnectToModel( mCoreModelConnection->makeConnectToModel(
&CoreModel::conferenceInfoReceived, &CoreModel::conferenceInfoReceived,
[this](const std::shared_ptr<linphone::Core> &core, [this](const std::shared_ptr<linphone::Core> &core,
@ -106,9 +103,48 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
lDebug() << log().arg("conference info received") << conferenceInfo->getSubject(); lDebug() << log().arg("conference info received") << conferenceInfo->getSubject();
addConference(conferenceInfo->clone()); addConference(conferenceInfo->clone());
}); });
// This is needed because account does not have a contact address until
// it is connected, so we can't verify if it is the organizer of a deleted
// conference (which must hidden)
mCoreModelConnection->makeConnectToModel(
&CoreModel::defaultAccountChanged,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::Account> &account) {
auto accountCore = account ? AccountCore::create(account) : nullptr;
mCoreModelConnection->invokeToCore([this, accountCore] {
if (mCurrentAccountCore)
disconnect(mCurrentAccountCore.get(), &AccountCore::registrationStateChanged, this, nullptr);
mCurrentAccountCore = accountCore;
if (mCurrentAccountCore)
connect(mCurrentAccountCore.get(), &AccountCore::registrationStateChanged, this,
[this] { emit lUpdate(); });
emit lUpdate(true);
});
});
mCoreModelConnection->invokeToModel([this] {
auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
auto accountCore = defaultAccount ? AccountCore::create(defaultAccount) : nullptr;
mCoreModelConnection->invokeToCore([this, accountCore] {
mCurrentAccountCore = accountCore;
if (mCurrentAccountCore)
connect(mCurrentAccountCore.get(), &AccountCore::registrationStateChanged, this,
[this] { emit lUpdate(); });
});
});
emit lUpdate(true); emit lUpdate(true);
} }
void ConferenceInfoList::setAccountConnected(bool connected) {
if (mAccountConnected != connected) {
mAccountConnected = connected;
emit accountConnectedChanged(mAccountConnected);
}
}
bool ConferenceInfoList::getAccountConnected() const {
return mAccountConnected;
}
void ConferenceInfoList::resetData(QList<QSharedPointer<ConferenceInfoCore>> data) { void ConferenceInfoList::resetData(QList<QSharedPointer<ConferenceInfoCore>> data) {
beginResetModel(); beginResetModel();
mList.clear(); mList.clear();

View file

@ -55,6 +55,9 @@ public:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
void setAccountConnected(bool connected);
bool getAccountConnected() const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
signals: signals:
@ -65,11 +68,13 @@ signals:
void currentDateIndexChanged(int index); void currentDateIndexChanged(int index);
void confInfoInserted(QSharedPointer<ConferenceInfoCore> data); void confInfoInserted(QSharedPointer<ConferenceInfoCore> data);
void confInfoUpdated(QSharedPointer<ConferenceInfoCore> data); void confInfoUpdated(QSharedPointer<ConferenceInfoCore> data);
void accountConnectedChanged(bool connected);
private: private:
QSharedPointer<SafeConnection<ConferenceInfoList, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<ConferenceInfoList, CoreModel>> mCoreModelConnection;
QSharedPointer<AccountCore> mCurrentAccountCore; QSharedPointer<AccountCore> mCurrentAccountCore;
bool mHaveCurrentDate = false; bool mHaveCurrentDate = false;
bool mAccountConnected = false;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
}; };
#endif // CONFERENCE_INFO_LIST_H_ #endif // CONFERENCE_INFO_LIST_H_

View file

@ -58,13 +58,19 @@ ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : LimitProxy(parent) {
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
connect(mList.get(), &ConferenceInfoList::initialized, this, &ConferenceInfoProxy::initialized); connect(mList.get(), &ConferenceInfoList::initialized, this, &ConferenceInfoProxy::initialized);
connect(mList.get(), &ConferenceInfoList::accountConnectedChanged, this,
&ConferenceInfoProxy::accountConnectedChanged);
} }
ConferenceInfoProxy::~ConferenceInfoProxy() { ConferenceInfoProxy::~ConferenceInfoProxy() {
} }
bool ConferenceInfoProxy::haveCurrentDate() const { bool ConferenceInfoProxy::haveCurrentDate() const {
return mList->haveCurrentDate(); return mList && mList->haveCurrentDate();
}
bool ConferenceInfoProxy::getAccountConnected() const {
return mList && mList->getAccountConnected();
} }
bool ConferenceInfoProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool ConferenceInfoProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {

View file

@ -32,6 +32,7 @@ class ConferenceInfoProxy : public LimitProxy, public AbstractObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool haveCurrentDate READ haveCurrentDate NOTIFY haveCurrentDateChanged) Q_PROPERTY(bool haveCurrentDate READ haveCurrentDate NOTIFY haveCurrentDateChanged)
Q_PROPERTY(bool accountConnected READ getAccountConnected NOTIFY accountConnectedChanged)
public: public:
enum ConferenceInfoFiltering { None = 0, Future = 1 }; enum ConferenceInfoFiltering { None = 0, Future = 1 };
@ -43,6 +44,7 @@ public:
~ConferenceInfoProxy(); ~ConferenceInfoProxy();
bool haveCurrentDate() const; bool haveCurrentDate() const;
bool getAccountConnected() const;
Q_INVOKABLE void clear(); Q_INVOKABLE void clear();
Q_INVOKABLE int loadUntil(ConferenceInfoGui *confInfo); Q_INVOKABLE int loadUntil(ConferenceInfoGui *confInfo);
@ -52,6 +54,7 @@ signals:
void haveCurrentDateChanged(); void haveCurrentDateChanged();
void conferenceInfoCreated(ConferenceInfoGui *confInfo); void conferenceInfoCreated(ConferenceInfoGui *confInfo);
void conferenceInfoUpdated(ConferenceInfoGui *confInfo); void conferenceInfoUpdated(ConferenceInfoGui *confInfo);
void accountConnectedChanged(bool connected);
private: private:
QSharedPointer<ConferenceInfoList> mList; QSharedPointer<ConferenceInfoList> mList;

View file

@ -157,7 +157,6 @@ Item {
} }
Text { Text {
z: parent.z + 1 z: parent.z + 1
RectangleTest{anchors.fill: parent}
property int timeDisplayed: videoThumbnail.playbackState === MediaPlayer.PlayingState ? videoThumbnail.position : videoThumbnail.duration property int timeDisplayed: videoThumbnail.playbackState === MediaPlayer.PlayingState ? videoThumbnail.position : videoThumbnail.duration
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left

View file

@ -16,8 +16,9 @@ ListView {
property var delegateButtons property var delegateButtons
property ConferenceInfoGui selectedConference property ConferenceInfoGui selectedConference
property bool _moveToIndex: false property bool _moveToIndex: false
property bool loading: false
property real busyIndicatorSize: Math.round(60 * DefaultStyle.dp)
visible: count > 0
clip: true clip: true
cacheBuffer: height/2 cacheBuffer: height/2
@ -88,8 +89,21 @@ ListView {
filterType: ConferenceInfoProxy.None filterType: ConferenceInfoProxy.None
initialDisplayItems: Math.max(20, 2 * mainItem.height / (Math.round(63 * DefaultStyle.dp))) initialDisplayItems: Math.max(20, 2 * mainItem.height / (Math.round(63 * DefaultStyle.dp)))
displayItemsStep: initialDisplayItems/2 displayItemsStep: initialDisplayItems/2
Component.onCompleted: {
mainItem.loading = !confInfoProxy.accountConnected
}
onModelAboutToBeReset: {
mainItem.loading = true
}
onModelReset: {
mainItem.loading = !confInfoProxy.accountConnected
}
onAccountConnectedChanged: (connected) => {
mainItem.loading = !connected
}
function selectData(confInfoGui){ function selectData(confInfoGui){
mainItem.currentIndex = loadUntil(confInfoGui) mainItem.currentIndex = loadUntil(confInfoGui)
mainItem.positionViewAtIndex(mainItem.currentIndex, ListView.Contain)
} }
onConferenceInfoCreated: (confInfoGui) => { onConferenceInfoCreated: (confInfoGui) => {
selectData(confInfoGui) selectData(confInfoGui)
@ -102,6 +116,16 @@ ListView {
selectData(null) selectData(null)
} }
} }
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
id: scrollbar id: scrollbar

View file

@ -55,7 +55,6 @@ AbstractMainPage {
onVisibleChanged: if (!visible) { onVisibleChanged: if (!visible) {
leftPanelStackView.clear() leftPanelStackView.clear()
leftPanelStackView.push(leftPanelStackView.initialItem) leftPanelStackView.push(leftPanelStackView.initialItem)
} }
onSelectedConferenceChanged: { onSelectedConferenceChanged: {
@ -193,7 +192,7 @@ AbstractMainPage {
} }
} }
Text { Text {
visible: conferenceList.count === 0 visible: conferenceList.count === 0 && !conferenceList.loading
Layout.topMargin: Math.round(137 * DefaultStyle.dp) Layout.topMargin: Math.round(137 * DefaultStyle.dp)
Layout.fillHeight: true Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -215,7 +214,15 @@ AbstractMainPage {
searchBarText: searchBar.text searchBarText: searchBar.text
onCountChanged: mainItem.meetingListCount = count onCountChanged: {
mainItem.meetingListCount = count === 0
}
Binding {
target: mainItem
property: "showDefaultItem"
when: conferenceList.loading
value: false
}
onSelectedConferenceChanged: { onSelectedConferenceChanged: {
mainItem.selectedConference = selectedConference mainItem.selectedConference = selectedConference
} }