File indexing completed on 2024-11-17 04:43:13

0001 // SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
0002 // SPDX-License-Identifier: LGPL-2.0-or-later
0003 
0004 #include "matrixmanager.h"
0005 
0006 #include <Quotient/accountregistry.h>
0007 #include <Quotient/room.h>
0008 #include <Quotient/qt_connection_util.h>
0009 #include "Quotient/settings.h"
0010 
0011 #include <KLocalizedString>
0012 #include <QCoreApplication>
0013 
0014 using namespace Quotient;
0015 
0016 MatrixManager::MatrixManager(QObject *parent)
0017     : QObject(parent)
0018 {
0019     Accounts.invokeLogin();
0020     connect(&Accounts, &AccountRegistry::rowsInserted, this, [this](){
0021         Q_EMIT connectedChanged();
0022         Q_EMIT userIdChanged();
0023         Q_EMIT connectionChanged();
0024         setInfoString(i18n("Syncing…"));
0025         connectSingleShot(Accounts.accounts()[0], &Connection::syncDone, this, [this](){
0026             setInfoString({});
0027             Accounts.accounts()[0]->stopSync();
0028         });
0029     });
0030     connect(&Accounts, &AccountRegistry::rowsRemoved, this, [this](){
0031         Q_EMIT connectedChanged();
0032         Q_EMIT userIdChanged();
0033         Q_EMIT connectionChanged();
0034     });
0035 }
0036 
0037 void MatrixManager::login(const QString &matrixId, const QString &password)
0038 {
0039     auto connection = new Connection(this);
0040     connection->resolveServer(matrixId);
0041     connectSingleShot(connection, &Connection::loginFlowsChanged, this, [this, connection, matrixId, password](){
0042         if (!connection->supportsPasswordAuth()) {
0043             setInfoString(i18n("This server does not support logging in using a password"));
0044         }
0045         auto username = matrixId.mid(1, matrixId.indexOf(QLatin1Char(':')) - 1);
0046         connection->loginWithPassword(username, password, qAppName(), {});
0047     });
0048 
0049     connect(connection, &Connection::connected, this, [this, connection] {
0050         AccountSettings account(connection->userId());
0051         account.setKeepLoggedIn(true);
0052         account.setHomeserver(connection->homeserver());
0053         account.setDeviceId(connection->deviceId());
0054         account.setDeviceName(qAppName());
0055         account.sync();
0056         Q_EMIT connectedChanged();
0057 
0058         setInfoString(i18n("Syncing…"));
0059         connectSingleShot(connection, &Connection::syncDone, this, [connection, this](){
0060             connection->stopSync();
0061             setInfoString({});
0062         });
0063     });
0064 
0065     connect(connection, &Connection::loginError, this, [this](const QString &message) {
0066         setInfoString(message);
0067     });
0068 
0069     setInfoString(i18n("Logging in"));
0070 }
0071 
0072 QString MatrixManager::infoString() const
0073 {
0074     return m_infoString;
0075 }
0076 
0077 bool MatrixManager::connected() const
0078 {
0079     return Accounts.count() > 0;
0080 }
0081 
0082 void MatrixManager::setInfoString(const QString &infoString)
0083 {
0084     m_infoString = infoString;
0085     Q_EMIT infoStringChanged();
0086 }
0087 
0088 QString MatrixManager::userId() const
0089 {
0090     return Accounts.count() > 0 ? Accounts.accounts()[0]->userId() : QString();
0091 }
0092 
0093 void MatrixManager::logout()
0094 {
0095     Accounts.accounts()[0]->logout();
0096 }
0097 
0098 Quotient::Connection *MatrixManager::connection() const
0099 {
0100     if (Accounts.count() > 0) {
0101         return Accounts.accounts()[0];
0102     }
0103     return nullptr;
0104 }
0105 
0106 void MatrixManager::sync()
0107 {
0108     auto connection = Accounts.accounts()[0];
0109     connection->sync();
0110     setInfoString(i18n("Syncing…"));
0111     connectSingleShot(connection, &Connection::syncDone, this, [this](){
0112         setInfoString({});
0113     });
0114 }
0115 
0116 void MatrixManager::postEvent(const QString &roomId, const QString &type, const QJsonObject &content)
0117 {
0118     Accounts.accounts()[0]->room(roomId)->postJson(type, content);
0119 }
0120 
0121 void MatrixManager::postLocation(const QString &roomId, float latitude, float longitude, const QString &description)
0122 {
0123     QJsonObject content{
0124             {QLatin1StringView("body"), description},
0125             {QLatin1StringView("msgtype"), QLatin1StringView("m.location")},
0126             {QLatin1StringView("org.matrix.msc3488.asset"), QJsonObject {
0127                     {QLatin1StringView("type"), QLatin1StringView("m.pin")}, // TODO location type (hotel, restaurant, train station, ...) here?
0128                     //{"name", description} // TODO location description ("Volker's Hotel") here?
0129             }},
0130             {QLatin1StringView("org.matrix.msc3488.ts"), QDateTime::currentDateTime().toMSecsSinceEpoch()},
0131             {QLatin1StringView("geo_uri"), QLatin1StringView("geo:%1,%2").arg(QString::number(latitude), QString::number(longitude))},
0132             {QLatin1StringView("org.matrix.msc1767.text"), description},
0133             {QLatin1StringView("org.matrix.msc3488.location"), QJsonObject {
0134                 {QLatin1StringView("uri"), QLatin1StringView("geo:%1,%2").arg(QString::number(latitude), QString::number(longitude))},
0135                 {QLatin1StringView("description"), description}
0136             }}
0137     };
0138 
0139     postEvent(roomId, QLatin1StringView("m.room.message"), content);
0140 }
0141 
0142 #include "moc_matrixmanager.cpp"