File indexing completed on 2024-09-29 10:14:48

0001 // SPDX-FileCopyrightText: 2021 kaniini <https://git.pleroma.social/kaniini>
0002 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
0003 // SPDX-License-Identifier: GPL-3.0-only
0004 
0005 #pragma once
0006 
0007 #include <KAboutData>
0008 #include <QAbstractListModel>
0009 #include <QSettings>
0010 
0011 #include "timeline/post.h"
0012 
0013 class AbstractAccount;
0014 class QNetworkAccessManager;
0015 
0016 class AccountManager : public QAbstractListModel
0017 {
0018     Q_OBJECT
0019 
0020     /// Whether or not the account manager is completely ready
0021     /// This doesn't mean it has accounts, simply that it's done reading configs and the keychain
0022     Q_PROPERTY(bool isReady READ isReady NOTIFY accountsReady)
0023 
0024     /// If there any valid accounts loaded
0025     Q_PROPERTY(bool hasAccounts READ hasAccounts NOTIFY accountsChanged)
0026 
0027     // If there are any accounts in the config
0028     Q_PROPERTY(bool hasAnyAccounts READ hasAnyAccounts NOTIFY accountsChanged)
0029 
0030     /// The currently selected account
0031     Q_PROPERTY(AbstractAccount *selectedAccount READ selectedAccount WRITE selectAccount NOTIFY accountSelected)
0032 
0033     /// The currently seelcted account's id
0034     Q_PROPERTY(QString selectedAccountId READ selectedAccountId NOTIFY accountSelected)
0035 
0036     /// The index of the seelcted account in the account list
0037     Q_PROPERTY(int selectedIndex READ selectedIndex NOTIFY accountSelected)
0038 
0039     /// The about data of the application
0040     Q_PROPERTY(KAboutData aboutData READ aboutData WRITE setAboutData NOTIFY aboutDataChanged)
0041 public:
0042     enum CustomRoles {
0043         AccountRole = Qt::UserRole + 1,
0044         DisplayNameRole,
0045         DescriptionRole,
0046         InstanceRole,
0047     };
0048 
0049     static AccountManager &instance();
0050 
0051     void loadFromSettings();
0052     void migrateSettings();
0053 
0054     bool isReady() const;
0055     bool hasAccounts() const;
0056     bool hasAnyAccounts() const;
0057     Q_INVOKABLE void addAccount(AbstractAccount *account);
0058     Q_INVOKABLE void removeAccount(AbstractAccount *account);
0059     void reloadAccounts();
0060 
0061     void selectAccount(AbstractAccount *account, bool explicitUserAction = true);
0062     AbstractAccount *selectedAccount() const;
0063     QString selectedAccountId() const;
0064 
0065     int selectedIndex() const;
0066 
0067     void setAboutData(const KAboutData &aboutData);
0068     [[nodiscard]] KAboutData aboutData() const;
0069 
0070     int rowCount(const QModelIndex &index = QModelIndex()) const override;
0071 
0072     QVariant data(const QModelIndex &index, int role) const override;
0073 
0074     QHash<int, QByteArray> roleNames() const override;
0075 
0076     Q_INVOKABLE AbstractAccount *createNewAccount(const QString &instanceUri, bool ignoreSslErrors = false);
0077 
0078     /// Returns the preferred settings group name for an account name and an instance uri.
0079     /// It's preferred to use AbstractAccount::settingsGroupName as it fills in the relevant information.
0080     static QString settingsGroupName(const QString &name, const QString &instanceUri);
0081 
0082     /// Returns the preferred key name for the client secret given a settings group name.
0083     /// It's preferred to use AbstractAccount::clientSecretKey as it fills in the relevant information.
0084     static QString clientSecretKey(const QString &name);
0085 
0086     /// Returns the preferred key name for the access token.
0087     /// It's preferred to use AbstractAccount::accessTokenKey as it fills in the relevant information.
0088     static QString accessTokenKey(const QString &name);
0089 
0090 Q_SIGNALS:
0091 
0092     void accountAdded(AbstractAccount *account);
0093 
0094     void accountRemoved(AbstractAccount *account);
0095 
0096     void accountsChanged();
0097 
0098     void accountsReady();
0099 
0100     void accountsReloaded();
0101 
0102     void accountSelected(AbstractAccount *account);
0103 
0104     void identityChanged(AbstractAccount *account);
0105 
0106     void fetchedTimeline(AbstractAccount *account, QString original_name, QList<Post *> posts);
0107 
0108     void invalidated(AbstractAccount *account);
0109 
0110     void fetchedInstanceMetadata(AbstractAccount *account);
0111 
0112     void invalidatedPost(AbstractAccount *account, Post *post);
0113 
0114     void notification(AbstractAccount *account, std::shared_ptr<Notification> n);
0115 
0116     void aboutDataChanged();
0117 
0118     void webapLink(QString id);
0119 
0120 public Q_SLOTS:
0121 
0122     void childIdentityChanged(AbstractAccount *account);
0123 
0124 private:
0125     explicit AccountManager(QObject *parent = nullptr);
0126 
0127     ~AccountManager() override;
0128 
0129     QList<AbstractAccount *> m_accounts;
0130     AbstractAccount *m_selected_account = nullptr;
0131     KAboutData m_aboutData;
0132     QNetworkAccessManager *m_qnam;
0133 
0134     enum class AccountStatus { NotLoaded, Loaded, InvalidCredentials };
0135 
0136     QList<AccountStatus> m_accountStatus;
0137 
0138     bool m_ready = false;
0139     bool m_hasAnyAccounts = false;
0140 
0141     void checkIfLoadingFinished();
0142 };