diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee7b67822..05fb27785 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -154,7 +154,6 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN qml/SpaceListContextMenu.qml qml/UserInfo.qml qml/UserInfoDesktop.qml - qml/LoadingPage.qml qml/RoomPage.qml qml/RoomWindow.qml qml/JoinRoomPage.qml diff --git a/src/controller.cpp b/src/controller.cpp index ab6d6676e..9b10bab33 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -167,6 +167,8 @@ void Controller::invokeLogin() QString id = NeoChatConfig::self()->activeConnection(); for (const auto &accountId : accounts) { AccountSettings account{accountId}; + m_accountsLoading += accountId; + Q_EMIT accountsLoadingChanged(); if (id.isEmpty()) { // handle case where the account config is empty id = accountId; @@ -186,6 +188,8 @@ void Controller::invokeLogin() connect(connection, &NeoChatConnection::connected, this, [this, connection, id] { connection->loadState(); addConnection(connection); + m_accountsLoading.removeAll(connection->userId()); + Q_EMIT accountsLoadingChanged(); if (connection->userId() == id) { setActiveConnection(connection); connectSingleShot(connection, &NeoChatConnection::syncDone, this, &Controller::initiated); diff --git a/src/controller.h b/src/controller.h index 63ee1a6c6..9572b8bb0 100644 --- a/src/controller.h +++ b/src/controller.h @@ -63,6 +63,8 @@ class Controller : public QObject */ Q_PROPERTY(bool isFlatpak READ isFlatpak CONSTANT) + Q_PROPERTY(QStringList accountsLoading MEMBER m_accountsLoading NOTIFY accountsLoadingChanged) + public: /** * @brief Defines the status after an attempt to change the password on an account. @@ -140,6 +142,7 @@ private: QMap m_notificationCounts; Quotient::AccountRegistry m_accountRegistry; + QStringList m_accountsLoading; private Q_SLOTS: void invokeLogin(); @@ -162,6 +165,7 @@ Q_SIGNALS: void passwordStatus(Controller::PasswordStatus status); void userConsentRequired(QUrl url); void isOnlineChanged(bool isOnline); + void accountsLoadingChanged(); public Q_SLOTS: void saveWindowGeometry(); diff --git a/src/login.cpp b/src/login.cpp index 96678678a..853fb53cd 100644 --- a/src/login.cpp +++ b/src/login.cpp @@ -100,7 +100,8 @@ void LoginHelper::init() Q_EMIT Controller::instance().globalErrorOccured(i18n("Network Error"), std::move(error)); }); - connectSingleShot(m_connection, &Connection::syncDone, this, []() { + connectSingleShot(m_connection, &Connection::syncDone, this, [this]() { + Q_EMIT loaded(); Q_EMIT Controller::instance().initiated(); }); } diff --git a/src/login.h b/src/login.h index 8155fea62..fd8f3fee6 100644 --- a/src/login.h +++ b/src/login.h @@ -79,7 +79,17 @@ class LoginHelper : public QObject Q_PROPERTY(bool isInvalidPassword READ isInvalidPassword NOTIFY isInvalidPasswordChanged) public: - explicit LoginHelper(QObject *parent = nullptr); + static LoginHelper &instance() + { + static LoginHelper _instance; + return _instance; + } + + static LoginHelper *create(QQmlEngine *engine, QJSEngine *) + { + engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); + return &instance(); + } Q_INVOKABLE void init(); @@ -125,6 +135,7 @@ Q_SIGNALS: void isLoggingInChanged(); void isLoggedInChanged(); void isInvalidPasswordChanged(); + void loaded(); private: void setHomeserverReachable(bool reachable); @@ -141,4 +152,5 @@ private: bool m_isLoggingIn = false; bool m_isLoggedIn = false; bool m_invalidPassword = false; + explicit LoginHelper(QObject *parent = nullptr); }; diff --git a/src/qml/LoadingPage.qml b/src/qml/LoadingPage.qml deleted file mode 100644 index b54ab4c53..000000000 --- a/src/qml/LoadingPage.qml +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Carl Schwan -// SPDX-License-Identifier: GPL-2.0-or-later - -import QtQuick.Layouts -import org.kde.kirigami as Kirigami - -Kirigami.Page { - title: i18n("Loading…") - Kirigami.LoadingPlaceholder { - id: loadingIndicator - anchors.centerIn: parent - } -} diff --git a/src/qml/WelcomePage.qml b/src/qml/WelcomePage.qml index 230b24feb..915e66245 100644 --- a/src/qml/WelcomePage.qml +++ b/src/qml/WelcomePage.qml @@ -14,7 +14,12 @@ import org.kde.neochat.accounts FormCard.FormCardPage { id: root + property bool showExisting: false + property bool _showExisting: showExisting && module.source == root.initialStep property alias currentStep: module.item + property string initialStep: "qrc:/org/kde/neochat/qml/LoginRegister.qml" + + signal connectionChosen title: i18n("Welcome") @@ -42,17 +47,47 @@ FormCard.FormCardPage { FormCard.FormTextDelegate { id: welcomeMessage - text: AccountRegistry.accountCount > 0 ? i18n("Log in to a different account or create a new account.") : i18n("Welcome to NeoChat! Continue by logging in or creating a new account.") + text: i18n("Welcome to NeoChat") } + } - FormCard.FormDelegateSeparator { - above: welcomeMessage + FormCard.FormHeader { + id: existingAccountsHeader + title: i18nc("@title", "Continue with an existing account") + visible: (loadedAccounts.count > 0 || loadingAccounts.count > 0) && root._showExisting + } + + FormCard.FormCard { + visible: existingAccountsHeader.visible + Repeater { + id: loadedAccounts + model: AccountRegistry + delegate: FormCard.FormButtonDelegate { + text: model.userId + onClicked: { + Controller.activeConnection = model.connection + root.connectionChosen() + } + } } + Repeater { + id: loadingAccounts + model: Controller.accountsLoading + delegate: FormCard.FormButtonDelegate { + text: i18nc("As in 'this account is still loading'", "%1 (loading)", modelData) + enabled: false + } + } + } + FormCard.FormHeader { + title: i18nc("@title", "Log in or Create a New Account") + } + FormCard.FormCard { Loader { id: module Layout.fillWidth: true - source: "qrc:/org/kde/neochat/qml/LoginRegister.qml" + source: root.initialStep Connections { id: stepConnections diff --git a/src/qml/main.qml b/src/qml/main.qml index c1e5303f9..cddddd5cb 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -31,7 +31,15 @@ Kirigami.ApplicationWindow { wideScreen: width > columnWidth * 5 pageStack { - initialPage: LoadingPage {} + initialPage: WelcomePage { + showExisting: true + onConnectionChosen: { + pageStack.replace(roomListComponent); + roomListLoaded = true; + roomListPage = pageStack.currentItem + RoomManager.loadInitialRoom(); + } + } globalToolBar.canContainHandles: true defaultColumnWidth: roomListPage ? roomListPage.currentWidth : 0 globalToolBar { @@ -47,6 +55,16 @@ Kirigami.ApplicationWindow { SpaceHierarchyCache.connection = root.connection } + Connections { + target: LoginHelper + function onLoaded() { + pageStack.replace(roomListComponent); + roomListLoaded = true; + roomListPage = pageStack.currentItem + RoomManager.loadInitialRoom(); + } + } + Connections { target: root.quitAction function onTriggered() { @@ -279,17 +297,6 @@ Kirigami.ApplicationWindow { Connections { target: Controller - function onInitiated() { - if (AccountRegistry.accountCount === 0) { - pageStack.replace("qrc:/org/kde/neochat/qml/WelcomePage.qml", {}); - } else if (!roomListLoaded) { - pageStack.replace(roomListComponent); - roomListLoaded = true; - roomListPage = pageStack.currentItem - RoomManager.loadInitialRoom(); - } - } - function onGlobalErrorOccured(error, detail) { showPassiveNotification(i18n("%1: %2", error, detail)); } diff --git a/src/registration.cpp b/src/registration.cpp index 5fe7fa50d..4fba1a86b 100644 --- a/src/registration.cpp +++ b/src/registration.cpp @@ -12,6 +12,7 @@ #include #include "controller.h" +#include "login.h" #include @@ -113,6 +114,7 @@ void Registration::registerAccount() Controller::instance().setActiveConnection(connection); connectSingleShot(connection, &Connection::syncDone, this, []() { Q_EMIT Controller::instance().initiated(); + Q_EMIT LoginHelper::instance().loaded(); }); m_connection = nullptr; });