File indexing completed on 2024-10-06 07:36:00
0001 // SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org> 0002 // SPDX-License-Identifier: GPL-3.0-only 0003 0004 #pragma once 0005 0006 #include <QObject> 0007 #include <QQmlEngine> 0008 #include <QQuickItem> 0009 0010 #include "neochatconnection.h" 0011 #include <Quotient/accountregistry.h> 0012 #include <Quotient/settings.h> 0013 0014 #ifdef HAVE_KUNIFIEDPUSH 0015 #include <kunifiedpush/connector.h> 0016 #endif 0017 0018 class TrayIcon; 0019 class QQuickTextDocument; 0020 0021 namespace QKeychain 0022 { 0023 class ReadPasswordJob; 0024 } 0025 0026 /** 0027 * @class Controller 0028 * 0029 * A singleton class designed to help manage the application. 0030 * 0031 * There are also a bunch of helper functions that currently don't fit anywhere 0032 * else. 0033 */ 0034 class Controller : public QObject 0035 { 0036 Q_OBJECT 0037 QML_ELEMENT 0038 QML_SINGLETON 0039 0040 /** 0041 * @brief The current connection for the rest of NeoChat to use. 0042 */ 0043 Q_PROPERTY(NeoChatConnection *activeConnection READ activeConnection WRITE setActiveConnection NOTIFY activeConnectionChanged) 0044 0045 /** 0046 * @brief Whether the OS NeoChat is running on supports sytem tray icons. 0047 */ 0048 Q_PROPERTY(bool supportSystemTray READ supportSystemTray CONSTANT) 0049 0050 /** 0051 * @brief Whether NeoChat is running as a flatpak. 0052 * 0053 * This is the only way to gate NeoChat features in flatpaks in QML. 0054 */ 0055 Q_PROPERTY(bool isFlatpak READ isFlatpak CONSTANT) 0056 0057 Q_PROPERTY(QStringList accountsLoading MEMBER m_accountsLoading NOTIFY accountsLoadingChanged) 0058 0059 public: 0060 static Controller &instance(); 0061 static Controller *create(QQmlEngine *engine, QJSEngine *) 0062 { 0063 engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); 0064 return &instance(); 0065 } 0066 0067 void setActiveConnection(NeoChatConnection *connection); 0068 [[nodiscard]] NeoChatConnection *activeConnection() const; 0069 0070 /** 0071 * @brief Add a new connection to the account registry. 0072 */ 0073 void addConnection(NeoChatConnection *c); 0074 0075 /** 0076 * @brief Drop a connection from the account registry. 0077 */ 0078 void dropConnection(NeoChatConnection *c); 0079 0080 /** 0081 * @brief Save an access token to the keychain for the given account. 0082 */ 0083 bool saveAccessTokenToKeyChain(const Quotient::AccountSettings &account, const QByteArray &accessToken); 0084 0085 [[nodiscard]] bool supportSystemTray() const; 0086 0087 /** 0088 * @brief Sets the QNetworkProxy for the application. 0089 * 0090 * @sa QNetworkProxy::setApplicationProxy 0091 */ 0092 Q_INVOKABLE void setApplicationProxy(); 0093 0094 bool isFlatpak() const; 0095 0096 /** 0097 * @brief Force a QQuickTextDocument to refresh when images are loaded. 0098 * 0099 * HACK: This is a workaround for QTBUG 93281. 0100 */ 0101 Q_INVOKABLE void forceRefreshTextDocument(QQuickTextDocument *textDocument, QQuickItem *item); 0102 0103 /** 0104 * @brief Start listening for notifications in dbus-activated mode. 0105 * These notifications will quit the application when closed. 0106 */ 0107 static void listenForNotifications(); 0108 0109 Quotient::AccountRegistry &accounts(); 0110 0111 static void setTestMode(bool testMode); 0112 0113 private: 0114 explicit Controller(QObject *parent = nullptr); 0115 0116 QPointer<NeoChatConnection> m_connection; 0117 TrayIcon *m_trayIcon = nullptr; 0118 0119 QKeychain::ReadPasswordJob *loadAccessTokenFromKeyChain(const Quotient::AccountSettings &account); 0120 0121 void loadSettings(); 0122 void saveSettings() const; 0123 0124 Quotient::AccountRegistry m_accountRegistry; 0125 QStringList m_accountsLoading; 0126 QString m_endpoint; 0127 0128 private Q_SLOTS: 0129 void invokeLogin(); 0130 void setQuitOnLastWindowClosed(); 0131 0132 Q_SIGNALS: 0133 void errorOccured(const QString &error, const QString &detail); 0134 void connectionAdded(NeoChatConnection *connection); 0135 void connectionDropped(NeoChatConnection *connection); 0136 void activeConnectionChanged(); 0137 void accountsLoadingChanged(); 0138 };