diff --git a/qml/Setting.qml b/qml/Setting.qml index 367d3fb..84c07ae 100644 --- a/qml/Setting.qml +++ b/qml/Setting.qml @@ -2,70 +2,37 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Controls.Material 2.2 import QtQuick.Layouts 1.3 +import Matrique 0.1 import Matrique.Settings 0.1 import "component" import "form" Page { -// Page { -// id: accountForm -// parent: null - -// padding: 64 - -// ColumnLayout { -// RowLayout { -// Layout.preferredHeight: 60 - -// ImageStatus { -// Layout.preferredWidth: height -// Layout.fillHeight: true - -// source: matriqueController.isLogin ? connection.localUser && connection.localUser.avatarUrl ? "image://mxc/" + connection.localUser.avatarUrl : "" : "qrc:/asset/img/avatar.png" -// displayText: matriqueController.isLogin && connection.localUser.displayName ? connection.localUser.displayName : "" -// } - -// ColumnLayout { -// Layout.fillWidth: true -// Layout.fillHeight: true - -// Label { -// font.pointSize: 18 -// text: matriqueController.isLogin ? connection.localUser.displayName : "" -// } - -// Label { -// font.pointSize: 12 -// text: matriqueController.isLogin ? connection.localUser.id : "" -// } -// } -// } - -// Button { -// text: "Logout" -// highlighted: true - -// onClicked: { -// matriqueController.logout() -// Qt.quit() -// } -// } -// } -// } - - Page{ + property alias listModel: accountSettingsListView.model + Page { id: accountForm - parent: null -// Button { -// flat: true -// highlighted: true -// text: "Login" + padding: 64 -// onClicked: stackView.push(loginPage) -// } + ListView { + anchors.fill: parent + + id: accountSettingsListView + + spacing: 0 + + delegate: RowLayout{ + Label { + text: accountID + } + ItemDelegate { + text: "Logout" + onClicked: matriqueController.logout(connection); + } + } + } } Page { diff --git a/qml/main.qml b/qml/main.qml index 419e898..2f0babc 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -11,7 +11,7 @@ import "component" import "form" ApplicationWindow { - readonly property var connection: matriqueController.connection + readonly property var currentConnection: accountListView.currentConnection ? accountListView.currentConnection : null width: 960 height: 640 @@ -42,6 +42,11 @@ ApplicationWindow { } } + AccountListModel { + id: accountListModel + controller: matriqueController + } + Popup { property bool busy: matriqueController.busy @@ -71,13 +76,15 @@ ApplicationWindow { parent: null - connection: accountListView.currentConnection + connection: currentConnection } Setting { id: settingPage parent: null + + listModel: accountListModel } RowLayout { @@ -104,7 +111,7 @@ ApplicationWindow { id: accountListView - model: AccountListModel { controller: matriqueController } + model: accountListModel spacing: 0 @@ -176,7 +183,7 @@ ApplicationWindow { } } - onAccepted: matriqueController.createRoom(addRoomDialogNameTextField.text, addRoomDialogTopicTextField.text) + onAccepted: matriqueController.createRoom(currentConnection, addRoomDialogNameTextField.text, addRoomDialogTopicTextField.text) } } MenuItem { @@ -202,7 +209,7 @@ ApplicationWindow { placeholderText: "#matrix:matrix.org" } - onAccepted: matriqueController.joinRoom(joinRoomDialogTextField.text) + onAccepted: matriqueController.joinRoom(currentConnection, joinRoomDialogTextField.text) } } @@ -229,7 +236,7 @@ ApplicationWindow { placeholderText: "@bot:matrix.org" } - onAccepted: matriqueController.createDirectChat(directChatDialogTextField.text) + onAccepted: currentConnection.createDirectChat(directChatDialogTextField.text) } } } @@ -283,13 +290,13 @@ ApplicationWindow { id: stackView - initialItem: roomPage + // initialItem: roomPage } } Binding { target: imageProvider property: "connection" - value: accountListView.currentConnection + value: currentConnection } } diff --git a/src/accountlistmodel.cpp b/src/accountlistmodel.cpp index 35ba133..70f7d5f 100644 --- a/src/accountlistmodel.cpp +++ b/src/accountlistmodel.cpp @@ -27,6 +27,8 @@ void AccountListModel::setController(Controller* value) { connect(m_controller, &Controller::connectionAdded, this, [=](Connection* conn) { + if (!conn) { + } beginInsertRows(QModelIndex(), m_connections.count(), m_connections.count()); m_connections.append(conn); @@ -34,6 +36,12 @@ void AccountListModel::setController(Controller* value) { }); connect(m_controller, &Controller::connectionDropped, this, [=](Connection* conn) { + qDebug() << "Dropping connection" << conn->userId(); + if (!conn) { + qDebug() << "Trying to remove null connection"; + return; + } + conn->disconnect(this); const auto it = std::find(m_connections.begin(), m_connections.end(), conn); if (it == m_connections.end()) @@ -50,15 +58,18 @@ void AccountListModel::setController(Controller* value) { QVariant AccountListModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); - if (index.row() >= m_controller->connections().count()) { - qDebug() - << "UserListModel, something's wrong: index.row() >= m_users.count()"; + if (index.row() >= m_connections.count()) { + qDebug() << "AccountListModel, something's wrong: index.row() >= " + "m_users.count()"; return QVariant(); } - auto m_connection = m_controller->connections().at(index.row()); + auto m_connection = m_connections.at(index.row()); if (role == NameRole) { return m_connection->user()->displayname(); } + if (role == AccountIDRole) { + return m_connection->user()->id(); + } if (role == AvatarRole) { return m_connection->user()->avatar(64); } @@ -78,6 +89,7 @@ int AccountListModel::rowCount(const QModelIndex& parent) const { QHash AccountListModel::roleNames() const { QHash roles; roles[NameRole] = "name"; + roles[AccountIDRole] = "accountID"; roles[AvatarRole] = "avatar"; roles[ConnectionRole] = "connection"; return roles; diff --git a/src/accountlistmodel.h b/src/accountlistmodel.h index 300d742..ddf7fb4 100644 --- a/src/accountlistmodel.h +++ b/src/accountlistmodel.h @@ -11,7 +11,12 @@ class AccountListModel : public QAbstractListModel { Q_PROPERTY(Controller* controller READ controller WRITE setController NOTIFY controllerChanged) public: - enum EventRoles { NameRole = Qt::UserRole + 1, AvatarRole, ConnectionRole }; + enum EventRoles { + NameRole = Qt::UserRole + 1, + AccountIDRole, + AvatarRole, + ConnectionRole + }; AccountListModel(QObject* parent = nullptr); diff --git a/src/controller.cpp b/src/controller.cpp index f031ec7..8b64f3b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -40,13 +40,17 @@ Controller::Controller(QObject* parent) : QObject(parent) { Connection::setRoomType(); - invokeLogin(); + QTimer::singleShot(0, this, SLOT(invokeLogin())); } -Controller::~Controller() { - // m_connection->saveState(); - // m_connection->stopSync(); - // m_connection->deleteLater(); +Controller::~Controller() {} + +inline QString accessTokenFileName(const AccountSettings& account) { + QString fileName = account.userId(); + fileName.replace(':', '_'); + return QStandardPaths::writableLocation( + QStandardPaths::AppLocalDataLocation) + + '/' + fileName; } void Controller::loginWithCredentials(QString serverAddr, QString user, @@ -70,18 +74,24 @@ void Controller::loginWithCredentials(QString serverAddr, QString user, } } +void Controller::logout(Connection* conn) { + if (!conn) { + qCritical() << "Attempt to logout null connection"; + return; + } + + SettingsGroup("Accounts").remove(conn->userId()); + QFile(accessTokenFileName(AccountSettings(conn->userId()))).remove(); + + conn->logout(); +} + void Controller::addConnection(Connection* c) { Q_ASSERT_X(c, __FUNCTION__, "Attempt to add a null connection"); m_connections.push_back(c); connect(c, &Connection::syncDone, this, [=] { - // gotEvents(c); - - // Borrowed the logic from Quiark's code in Tensor to cache not too - // aggressively and not on the first sync. The static variable instance - // is created per-closure, meaning per-connection (which is why this - // code is not in gotEvents() ). static int counter = 0; if (++counter % 17 == 2) c->saveState(); }); @@ -98,23 +108,13 @@ void Controller::dropConnection(Connection* c) { Q_ASSERT_X(c, __FUNCTION__, "Attempt to drop a null connection"); m_connections.removeOne(c); - Q_ASSERT(!m_connections.contains(c) && !c->syncJob()); - emit connectionAdded(c); + emit connectionDropped(c); c->deleteLater(); } -inline QString accessTokenFileName(const AccountSettings& account) { - QString fileName = account.userId(); - fileName.replace(':', '_'); - return QStandardPaths::writableLocation( - QStandardPaths::AppLocalDataLocation) + - '/' + fileName; -} - void Controller::invokeLogin() { using namespace QMatrixClient; const auto accounts = SettingsGroup("Accounts").childGroups(); - bool autoLoggedIn = false; for (const auto& accountId : accounts) { AccountSettings account{accountId}; if (!account.homeserver().isEmpty()) { @@ -130,7 +130,6 @@ void Controller::invokeLogin() { account.clearAccessToken(); // Clean the old place } - autoLoggedIn = true; auto c = new Connection(account.homeserver(), this); auto deviceName = account.deviceName(); connect(c, &Connection::connected, this, [=] { @@ -185,42 +184,20 @@ bool Controller::saveAccessToken(const AccountSettings& account, return false; } -void Controller::connected() { - // setHomeserver(m_connection->homeserver().toString()); - // setUserID(m_connection->userId()); - // setToken(m_connection->accessToken()); - // m_connection->loadState(); - // resync(); - // setIsLogin(true); +void Controller::joinRoom(Connection* c, const QString& alias) { + JoinRoomJob* joinRoomJob = c->joinRoom(alias); + setBusy(true); + joinRoomJob->connect(joinRoomJob, &JoinRoomJob::finished, + [=] { setBusy(false); }); } -void Controller::resync() { /*m_connection->sync(30000);*/ -} - -void Controller::reconnect() { - // qDebug() << "Connection lost. Reconnecting..."; - // m_connection->connectWithToken(m_userID, m_token, ""); -} - -void Controller::joinRoom(const QString& alias) { - // JoinRoomJob* joinRoomJob = m_connection->joinRoom(alias); - // setBusy(true); - // joinRoomJob->connect(joinRoomJob, &JoinRoomJob::finished, - // [=] { setBusy(false); }); -} - -void Controller::createRoom(const QString& name, const QString& topic) { - // CreateRoomJob* createRoomJob = - // ((Connection*)m_connection) - // ->createRoom(Connection::PublishRoom, "", name, topic, - // QStringList()); - // setBusy(true); - // createRoomJob->connect(createRoomJob, &CreateRoomJob::finished, - // [=] { setBusy(false); }); -} - -void Controller::createDirectChat(const QString& userID) { - // m_connection->requestDirectChat(userID); +void Controller::createRoom(Connection* c, const QString& name, + const QString& topic) { + CreateRoomJob* createRoomJob = + c->createRoom(Connection::PublishRoom, "", name, topic, QStringList()); + setBusy(true); + createRoomJob->connect(createRoomJob, &CreateRoomJob::finished, + [=] { setBusy(false); }); } void Controller::copyToClipboard(const QString& text) { diff --git a/src/controller.h b/src/controller.h index 55cbd20..46ae4f5 100644 --- a/src/controller.h +++ b/src/controller.h @@ -49,9 +49,6 @@ class Controller : public QObject { bool m_busy = false; - void connected(); - void resync(); - void reconnect(); QByteArray loadAccessToken(const AccountSettings& account); bool saveAccessToken(const AccountSettings& account, const QByteArray& accessToken); @@ -69,9 +66,9 @@ class Controller : public QObject { void connectionDropped(Connection* conn); public slots: - void joinRoom(const QString& alias); - void createRoom(const QString& name, const QString& topic); - void createDirectChat(const QString& userID); + void logout(Connection* conn); + void joinRoom(Connection* c, const QString& alias); + void createRoom(Connection* c, const QString& name, const QString& topic); void copyToClipboard(const QString& text); void playAudio(QUrl localFile); void showMessage(const QString& title, const QString& msg, const QIcon& icon); diff --git a/src/messageeventmodel.cpp b/src/messageeventmodel.cpp index d7d1446..f512249 100644 --- a/src/messageeventmodel.cpp +++ b/src/messageeventmodel.cpp @@ -51,7 +51,6 @@ void MessageEventModel::setRoom(MatriqueRoom* room) { beginResetModel(); if (m_currentRoom) { m_currentRoom->disconnect(this); - qDebug() << "Disconnected from" << m_currentRoom->id(); } m_currentRoom = room; diff --git a/src/roomlistmodel.cpp b/src/roomlistmodel.cpp index 7623d9b..6959bad 100644 --- a/src/roomlistmodel.cpp +++ b/src/roomlistmodel.cpp @@ -14,7 +14,16 @@ RoomListModel::RoomListModel(QObject* parent) : QAbstractListModel(parent) {} RoomListModel::~RoomListModel() {} void RoomListModel::setConnection(Connection* connection) { - if (!connection && connection == m_connection) return; + if (connection == m_connection) return; + if (!connection) { + qDebug() << "Removing current connection..."; + m_connection->disconnect(this); + m_connection = nullptr; + beginResetModel(); + m_rooms.clear(); + endResetModel(); + return; + } using QMatrixClient::Room; m_connection = connection;