wait for core is on before displaying ui

Use directly accountProxy and react to signals.
This commit is contained in:
Gaelle Braud 2024-10-18 16:33:55 +02:00
parent 0afdc6d6d7
commit 075937aa00
9 changed files with 104 additions and 27 deletions

View file

@ -341,6 +341,13 @@ void App::setSelf(QSharedPointer<App>(me)) {
}
});
});
mCoreModelConnection->makeConnectToModel(
&CoreModel::globalStateChanged,
[this](const std::shared_ptr<linphone::Core> &core, linphone::GlobalState gstate, const std::string &message) {
if (gstate == linphone::GlobalState::On) {
mCoreModelConnection->invokeToCore([this] { setCoreStarted(true); });
}
});
mCoreModelConnection->makeConnectToModel(
&CoreModel::authenticationRequested,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::AuthInfo> &authInfo,
@ -424,9 +431,10 @@ void App::initCore() {
mLinphoneThread->getThreadId(),
[this]() mutable {
CoreModel::getInstance()->start();
auto coreStarted = CoreModel::getInstance()->getCore()->getGlobalState() == linphone::GlobalState::On;
SettingsModel::create();
auto settings = SettingsCore::create();
QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings] {
QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings, coreStarted] {
// QML
mEngine = new QQmlApplicationEngine(this);
assert(mEngine);
@ -473,6 +481,7 @@ void App::initCore() {
mNotifier = new Notifier(mEngine);
mSettings = settings;
mEngine->setObjectOwnership(mSettings.get(), QQmlEngine::CppOwnership);
mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
mAccountList = AccountList::create();
mCallList = CallList::create();
setAutoStart(mSettings->getAutoStart());
@ -484,7 +493,7 @@ void App::initCore() {
const QUrl url(u"qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml"_qs);
QObject::connect(
mEngine, &QQmlApplicationEngine::objectCreated, this,
[this, url](QObject *obj, const QUrl &objUrl) {
[this, url, coreStarted](QObject *obj, const QUrl &objUrl) {
if (url == objUrl) {
if (!obj) {
lCritical() << log().arg("MainWindow.qml couldn't be load. The app will exit");
@ -492,7 +501,7 @@ void App::initCore() {
}
auto window = qobject_cast<QQuickWindow *>(obj);
setMainWindow(window);
QMetaObject::invokeMethod(obj, "initStackViewItem");
setCoreStarted(coreStarted);
#ifndef __APPLE__
// Enable TrayIconSystem.
if (!QSystemTrayIcon::isSystemTrayAvailable())
@ -523,6 +532,8 @@ void App::initCore() {
}
void App::initCppInterfaces() {
qmlRegisterSingletonType<App>(Constants::MainQmlUri, 1, 0, "AppCpp",
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return App::getInstance(); });
qmlRegisterSingletonType<LoginPage>(
Constants::MainQmlUri, 1, 0, "LoginPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
static auto loginPage = new LoginPage();
@ -698,6 +709,17 @@ void App::sendCommand() {
}
}
bool App::getCoreStarted() const {
return mCoreStarted;
}
void App::setCoreStarted(bool started) {
if (mCoreStarted != started) {
mCoreStarted = started;
emit coreStartedChanged(mCoreStarted);
}
}
bool App::notify(QObject *receiver, QEvent *event) {
bool done = true;
try {

View file

@ -38,6 +38,7 @@ class QSystemTrayIcon;
class App : public SingleApplication, public AbstractObject {
Q_OBJECT
Q_PROPERTY(bool coreStarted READ getCoreStarted WRITE setCoreStarted NOTIFY coreStartedChanged)
public:
App(int &argc, char *argv[]);
~App();
@ -113,6 +114,9 @@ public:
void onLoggerInitialized();
void sendCommand();
bool getCoreStarted() const;
void setCoreStarted(bool started);
QQuickWindow *getCallsWindow(QVariant callGui = QVariant());
void setCallsWindowProperty(const char *id, QVariant property);
void closeCallsWindow();
@ -141,6 +145,7 @@ public:
signals:
void mainWindowChanged();
void coreStartedChanged(bool coreStarted);
// void executeCommand(QString command);
private:
@ -160,6 +165,7 @@ private:
QSharedPointer<SafeConnection<App, CoreModel>> mCoreModelConnection;
QSharedPointer<SafeConnection<App, CliModel>> mCliModelConnection;
bool mAutoStart = false;
bool mCoreStarted = false;
QLocale mLocale = QLocale::system();
DECLARE_ABSTRACT_OBJECT

View file

@ -50,8 +50,8 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
mModelConnection = QSharedPointer<SafeConnection<AccountList, CoreModel>>(
new SafeConnection<AccountList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection->makeConnectToCore(&AccountList::lUpdate, [this]() {
mModelConnection->invokeToModel([this]() {
mModelConnection->makeConnectToCore(&AccountList::lUpdate, [this](bool isInitialization) {
mModelConnection->invokeToModel([this, isInitialization]() {
// Avoid copy to lambdas
QList<QSharedPointer<AccountCore>> *accounts = new QList<QSharedPointer<AccountCore>>();
mustBeInLinphoneThread(getClassName());
@ -63,11 +63,12 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
if (it == defaultAccount) defaultAccountCore = AccountCore::create(defaultAccount);
accounts->push_back(model);
}
mModelConnection->invokeToCore([this, accounts, defaultAccountCore]() {
mModelConnection->invokeToCore([this, accounts, defaultAccountCore, isInitialization]() {
mustBeInMainThread(getClassName());
resetData<AccountCore>(*accounts);
setHaveAccount(accounts->size() > 0);
setDefaultAccount(defaultAccountCore);
if (isInitialization) setInitialized(true);
delete accounts;
});
});
@ -80,11 +81,10 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
mModelConnection->invokeToCore([this, model]() { setDefaultAccount(model); });
} else mModelConnection->invokeToCore([this]() { setDefaultAccount(nullptr); });
});
mModelConnection->makeConnectToModel(&CoreModel::accountRemoved, &AccountList::lUpdate);
mModelConnection->makeConnectToModel(&CoreModel::accountAdded, &AccountList::lUpdate);
mModelConnection->makeConnectToModel(&CoreModel::accountRemoved, [this] { emit lUpdate(); });
mModelConnection->makeConnectToModel(&CoreModel::accountAdded, [this] { emit lUpdate(); });
lUpdate();
emit initialized();
lUpdate(true);
}
QSharedPointer<AccountCore> AccountList::getDefaultAccountCore() const {
@ -135,6 +135,17 @@ void AccountList::setHaveAccount(bool haveAccount) {
}
}
bool AccountList::isInitialized() const {
return mIsInitialized;
}
void AccountList::setInitialized(bool init) {
if (mIsInitialized != init) {
mIsInitialized = init;
emit initializedChanged(mIsInitialized);
}
}
QVariant AccountList::data(const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();

View file

@ -49,15 +49,19 @@ public:
bool getHaveAccount() const;
void setHaveAccount(bool haveAccount);
bool isInitialized() const;
void setInitialized(bool init);
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
signals:
void lUpdate();
void lUpdate(bool isInitialization = false);
void haveAccountChanged();
void defaultAccountChanged();
void initialized();
void initializedChanged(bool init);
private:
bool mHaveAccount = false;
bool mIsInitialized = false;
QSharedPointer<AccountCore> mDefaultAccount;
QSharedPointer<SafeConnection<AccountList, CoreModel>> mModelConnection;
DECLARE_ABSTRACT_OBJECT

View file

@ -24,7 +24,7 @@
#include "core/App.hpp"
AccountProxy::AccountProxy(QObject *parent) : LimitProxy(parent) {
setSourceModels(new SortFilterList(App::getInstance()->getAccountList().get(), Qt::AscendingOrder));
setSourceModel(App::getInstance()->getAccountList().get());
}
AccountProxy::~AccountProxy() {
@ -59,6 +59,17 @@ bool AccountProxy::getHaveAccount() const {
return getListModel<AccountList>()->getHaveAccount();
}
bool AccountProxy::isInitialized() const {
return mInitialized;
}
void AccountProxy::setInitialized(bool init) {
if (mInitialized != init) {
mInitialized = init;
emit initializedChanged();
}
}
void AccountProxy::setSourceModel(QAbstractItemModel *model) {
auto oldAccountList = getListModel<AccountList>();
if (oldAccountList) {
@ -66,6 +77,11 @@ void AccountProxy::setSourceModel(QAbstractItemModel *model) {
}
auto newAccountList = dynamic_cast<AccountList *>(model);
if (newAccountList) {
connect(newAccountList, &AccountList::initializedChanged, this, [this](bool init) {
qDebug() << "AccountProxy initialized";
setInitialized(init);
});
setInitialized(newAccountList->isInitialized());
connect(newAccountList, &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount,
Qt::QueuedConnection);
connect(newAccountList, &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount,
@ -73,7 +89,7 @@ void AccountProxy::setSourceModel(QAbstractItemModel *model) {
connect(newAccountList, &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged,
Qt::QueuedConnection);
}
QSortFilterProxyModel::setSourceModel(model);
setSourceModels(new SortFilterList(model, Qt::AscendingOrder));
}
//------------------------------------------------------------------------------------------

View file

@ -33,6 +33,7 @@ class AccountProxy : public LimitProxy {
Q_PROPERTY(AccountGui *defaultAccount READ getDefaultAccount WRITE setDefaultAccount NOTIFY defaultAccountChanged)
Q_PROPERTY(bool haveAccount READ getHaveAccount NOTIFY haveAccountChanged)
Q_PROPERTY(bool isInitialized READ isInitialized NOTIFY initializedChanged)
public:
DECLARE_SORTFILTER_CLASS()
@ -48,14 +49,18 @@ public:
bool getHaveAccount() const;
bool isInitialized() const;
void setInitialized(bool init);
void setSourceModel(QAbstractItemModel *sourceModel) override;
signals:
void defaultAccountChanged();
void haveAccountChanged();
void initialized();
void initializedChanged();
protected:
bool mInitialized = false;
QSharedPointer<AccountCore> mDefaultAccount; // When null, a new UI object is build from List
};

View file

@ -38,9 +38,11 @@ bool LimitProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent
void LimitProxy::setSourceModels(SortFilterProxy *firstList) {
auto secondList = firstList->sourceModel();
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::onAdded);
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::onRemoved);
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidateRowsFilter);
if (secondList) {
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::onAdded);
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::onRemoved);
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidateRowsFilter);
}
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
connect(firstList, &SortFilterProxy::filterTypeChanged, this, &LimitProxy::filterTypeChanged);

View file

@ -201,7 +201,7 @@ AbstractMainPage {
spacing: 38 * DefaultStyle.dp
SearchBar {
id: searchBar
visible: contactList.model.sourceModel.count != 0
visible: contactList.count != 0
Layout.leftMargin: leftPanel.leftMargin
Layout.rightMargin: leftPanel.rightMargin
Layout.topMargin: 18 * DefaultStyle.dp

View file

@ -17,7 +17,8 @@ AbstractWindow {
color: DefaultStyle.grey_0
signal callCreated()
property var accountProxy: accountProxyLoader.item
// TODO : use this to make the border transparent
// flags: Qt.Window | Qt.FramelessWindowHint | Qt.WindowTitleHint
// menuBar: Rectangle {
@ -25,6 +26,7 @@ AbstractWindow {
// height: 40 * DefaultStyle.dp
// color: DefaultStyle.grey_100
// }
function openMainPage(){
if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate)
}
@ -45,10 +47,12 @@ AbstractWindow {
UtilsCpp.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné"))
}
function initStackViewItem() {
if (accountProxy.haveAccount) openMainPage()
else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate)
else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate)
if(accountProxy && accountProxy.isInitialized) {
if (accountProxy.haveAccount) openMainPage()
else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate)
else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate)
}
}
function goToLogin() {
@ -90,9 +94,16 @@ AbstractWindow {
}
}
AccountProxy {
id: accountProxy
onInitialized: initStackViewItem()
Loader {
id: accountProxyLoader
active: AppCpp.coreStarted
sourceComponent: AccountProxy {
Component.onCompleted: {
mainWindow.accountProxy = this
mainWindow.initStackViewItem()
}
onInitializedChanged: mainWindow.initStackViewItem()
}
}
StackView {