File indexing completed on 2024-05-05 05:01:24

0001 // SPDX-FileCopyrightText: 2022 James Graham <james.h.graham@protonmail.com>
0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 #pragma once
0005 
0006 #include <QAbstractListModel>
0007 #include <QQmlEngine>
0008 
0009 #include <Quotient/csapi/definitions/push_rule.h>
0010 
0011 #include "enums/pushrule.h"
0012 #include "neochatconnection.h"
0013 
0014 /**
0015  * @class PushRuleModel
0016  *
0017  * This class defines the model for managing notification push rule keywords.
0018  */
0019 class PushRuleModel : public QAbstractListModel
0020 {
0021     Q_OBJECT
0022     QML_ELEMENT
0023 
0024     /**
0025      * @brief The default state for any newly created keyword rule.
0026      */
0027     Q_PROPERTY(PushRuleAction::Action defaultState READ defaultState WRITE setDefaultState NOTIFY defaultStateChanged)
0028 
0029     /**
0030      * @brief The global notification state.
0031      *
0032      * If this rule is set to off all push notifications are disabled regardless
0033      * of other settings.
0034      */
0035     Q_PROPERTY(bool globalNotificationsEnabled READ globalNotificationsEnabled WRITE setGlobalNotificationsEnabled NOTIFY globalNotificationsEnabledChanged)
0036 
0037     /**
0038      * @brief Whether the global notification state has been retrieved from the server.
0039      *
0040      * @sa globalNotificationsEnabled, PushRuleAction::Action
0041      */
0042     Q_PROPERTY(bool globalNotificationsSet READ globalNotificationsSet NOTIFY globalNotificationsSetChanged)
0043 
0044     Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
0045 
0046 public:
0047     struct Rule {
0048         QString id;
0049         PushRuleKind::Kind kind;
0050         PushRuleAction::Action action;
0051         PushRuleSection::Section section;
0052         bool enabled;
0053         QString roomId;
0054     };
0055 
0056     /**
0057      * @brief Defines the model roles.
0058      */
0059     enum EventRoles {
0060         NameRole = Qt::DisplayRole, /**< The push rule name. */
0061         IdRole, /**< The push rule ID. */
0062         KindRole, /**< The kind of notification rule; override, content, etc. */
0063         ActionRole, /**< The PushRuleAction for the rule. */
0064         HighlightableRole, /**< Whether the rule can have a highlight action. */
0065         DeletableRole, /**< Whether the rule can be deleted the rule. */
0066         SectionRole, /**< The section to sort into in the settings page. */
0067         RoomIdRole, /**< The room the rule applies to (blank if global). */
0068     };
0069     Q_ENUM(EventRoles)
0070 
0071     explicit PushRuleModel(QObject *parent = nullptr);
0072 
0073     [[nodiscard]] PushRuleAction::Action defaultState() const;
0074     void setDefaultState(PushRuleAction::Action defaultState);
0075 
0076     [[nodiscard]] bool globalNotificationsEnabled() const;
0077     void setGlobalNotificationsEnabled(bool enabled);
0078 
0079     [[nodiscard]] bool globalNotificationsSet() const;
0080 
0081     /**
0082      * @brief Get the given role value at the given index.
0083      *
0084      * @sa QAbstractItemModel::data
0085      */
0086     [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0087 
0088     /**
0089      * @brief Number of rows in the model.
0090      *
0091      * @sa QAbstractItemModel::rowCount
0092      */
0093     [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0094 
0095     /**
0096      * @brief Returns a mapping from Role enum values to role names.
0097      *
0098      * @sa EventRoles, QAbstractItemModel::roleNames()
0099      */
0100     [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
0101 
0102     Q_INVOKABLE void setPushRuleAction(const QString &id, PushRuleAction::Action action);
0103 
0104     /**
0105      * @brief Add a new keyword to the model.
0106      */
0107     Q_INVOKABLE void addKeyword(const QString &keyword, const QString &roomId = {});
0108 
0109     /**
0110      * @brief Remove a keyword from the model.
0111      */
0112     Q_INVOKABLE void removeKeyword(const QString &keyword);
0113 
0114     void setConnection(NeoChatConnection *connection);
0115     NeoChatConnection *connection() const;
0116 
0117 Q_SIGNALS:
0118     void defaultStateChanged();
0119     void globalNotificationsEnabledChanged();
0120     void globalNotificationsSetChanged();
0121     void connectionChanged();
0122 
0123 private Q_SLOTS:
0124     void updateNotificationRules(const QString &type);
0125 
0126 private:
0127     PushRuleAction::Action m_defaultKeywordAction;
0128     QList<Rule> m_rules;
0129     NeoChatConnection *m_connection;
0130 
0131     void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind);
0132 
0133     int getRuleIndex(const QString &ruleId) const;
0134     PushRuleSection::Section getSection(Quotient::PushRule rule);
0135 
0136     void setNotificationRuleEnabled(const QString &kind, const QString &ruleId, bool enabled);
0137     void setNotificationRuleActions(const QString &kind, const QString &ruleId, PushRuleAction::Action action);
0138     PushRuleAction::Action variantToAction(const QList<QVariant> &actions, bool enabled);
0139     QList<QVariant> actionToVariant(PushRuleAction::Action action, const QString &sound = QStringLiteral("default"));
0140 };
0141 Q_DECLARE_METATYPE(PushRuleModel *)