File indexing completed on 2024-05-05 16:58:37

0001 // SPDX-FileCopyrightText: 2021 Carson Black <uhhadd@gmail.com>
0002 // SPDX-License-Identifier: GPL-2.0-or-later
0003 
0004 #pragma once
0005 
0006 #include <QAbstractListModel>
0007 #include <QRegularExpression>
0008 #include <memory>
0009 
0010 struct CustomEmoji {
0011     QString name; // with :semicolons:
0012     QString url; // mxc://
0013     QRegularExpression regexp;
0014 
0015     Q_GADGET
0016     Q_PROPERTY(QString unicode MEMBER url)
0017     Q_PROPERTY(QString name MEMBER name)
0018 };
0019 
0020 /**
0021  * @class CustomEmojiModel
0022  *
0023  * This class defines the model for custom user emojis.
0024  *
0025  * This is based upon the im.ponies.user_emotes spec (MSC2545).
0026  */
0027 class CustomEmojiModel : public QAbstractListModel
0028 {
0029     Q_OBJECT
0030 
0031 public:
0032     /**
0033      * @brief Defines the model roles.
0034      */
0035     enum Roles {
0036         Name = Qt::DisplayRole, /**< The name of the emoji. */
0037         ImageURL, /**< The URL for the custom emoji. */
0038         ModelData, /**< for emulating the regular emoji model's usage, otherwise the UI code would get too complicated. */
0039         MxcUrl = 50, /**< The mxc source URL for the custom emoji. */
0040         DisplayRole = 51, /**< The name of the emoji. For compatibility with EmojiModel. */
0041         ReplacedTextRole = 52, /**< The name of the emoji. For compatibility with EmojiModel. */
0042         DescriptionRole = 53, /**< Invalid, reserved. For compatibility with EmojiModel. */
0043     };
0044     Q_ENUM(Roles)
0045 
0046     static CustomEmojiModel &instance()
0047     {
0048         static CustomEmojiModel _instance;
0049         return _instance;
0050     }
0051 
0052     /**
0053      * @brief Get the given role value at the given index.
0054      *
0055      * @sa QAbstractItemModel::data
0056      */
0057     QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
0058 
0059     /**
0060      * @brief Number of rows in the model.
0061      *
0062      * @sa  QAbstractItemModel::rowCount
0063      */
0064     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0065 
0066     /**
0067      * @brief Returns a mapping from Role enum values to role names.
0068      *
0069      * @sa Roles, QAbstractItemModel::roleNames()
0070      */
0071     QHash<int, QByteArray> roleNames() const override;
0072 
0073     /**
0074      * @brief Substitute any custom emojis for an image in the input text.
0075      */
0076     Q_INVOKABLE QString preprocessText(const QString &it);
0077 
0078     /**
0079      * @brief Return a list of custom emojis where the name contains the filter text.
0080      */
0081     Q_INVOKABLE QVariantList filterModel(const QString &filter);
0082 
0083     /**
0084      * @brief Add a new emoji to the model.
0085      */
0086     Q_INVOKABLE void addEmoji(const QString &name, const QUrl &location);
0087 
0088     /**
0089      * @brief Remove an emoji from the model.
0090      */
0091     Q_INVOKABLE void removeEmoji(const QString &name);
0092 
0093 private:
0094     explicit CustomEmojiModel(QObject *parent = nullptr);
0095     QList<CustomEmoji> m_emojis;
0096 
0097     void fetchEmojis();
0098 };