File indexing completed on 2024-04-14 04:54:10

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     bool isFlatpak() const;
0088 
0089     /**
0090      * @brief Start listening for notifications in dbus-activated mode.
0091      * These notifications will quit the application when closed.
0092      */
0093     static void listenForNotifications();
0094 
0095     Quotient::AccountRegistry &accounts();
0096 
0097     static void setTestMode(bool testMode);
0098 
0099 private:
0100     explicit Controller(QObject *parent = nullptr);
0101 
0102     QPointer<NeoChatConnection> m_connection;
0103     TrayIcon *m_trayIcon = nullptr;
0104 
0105     QKeychain::ReadPasswordJob *loadAccessTokenFromKeyChain(const Quotient::AccountSettings &account);
0106 
0107     void loadSettings();
0108     void saveSettings() const;
0109 
0110     Quotient::AccountRegistry m_accountRegistry;
0111     QStringList m_accountsLoading;
0112     QString m_endpoint;
0113 
0114 private Q_SLOTS:
0115     void invokeLogin();
0116     void setQuitOnLastWindowClosed();
0117 
0118 Q_SIGNALS:
0119     void errorOccured(const QString &error, const QString &detail);
0120     void connectionAdded(NeoChatConnection *connection);
0121     void connectionDropped(NeoChatConnection *connection);
0122     void activeConnectionChanged();
0123     void accountsLoadingChanged();
0124 };