File indexing completed on 2024-04-28 04:59:35

0001 // SPDX-FileCopyrightText: 2018 Black Hat <bhat@encom.eu.org>
0002 // SPDX-License-Identifier: GPL-3.0-only
0003 
0004 #pragma once
0005 
0006 #include <QAbstractListModel>
0007 #include <QQmlEngine>
0008 
0009 class NeoChatRoom;
0010 
0011 namespace Quotient
0012 {
0013 class Connection;
0014 class Room;
0015 }
0016 
0017 class NeoChatRoomType : public QObject
0018 {
0019     Q_OBJECT
0020     QML_ELEMENT
0021     QML_UNCREATABLE("")
0022 
0023 public:
0024     /**
0025      * @brief Defines the room list categories a room can be assigned.
0026      */
0027     enum Types {
0028         Invited = 1, /**< The user has been invited to the room. */
0029         Favorite, /**< The room is set as a favourite. */
0030         Direct, /**< The room is a direct chat. */
0031         Normal, /**< The default category for a joined room. */
0032         Deprioritized, /**< The room is set as low priority. */
0033         Space, /**< The room is a space. */
0034     };
0035     Q_ENUM(Types)
0036 };
0037 
0038 /**
0039  * @class RoomListModel
0040  *
0041  * This class defines the model for visualising the user's list of joined rooms.
0042  */
0043 class RoomListModel : public QAbstractListModel
0044 {
0045     Q_OBJECT
0046     QML_ELEMENT
0047 
0048     /**
0049      * @brief The current connection that the model is getting its rooms from.
0050      */
0051     Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
0052 
0053     /**
0054      * @brief The total number of notifications for all the rooms.
0055      */
0056     Q_PROPERTY(int notificationCount READ notificationCount NOTIFY notificationCountChanged)
0057 
0058 public:
0059     /**
0060      * @brief Defines the model roles.
0061      */
0062     enum EventRoles {
0063         DisplayNameRole = Qt::DisplayRole, /**< The display name of the room. */
0064         AvatarRole, /**< The source URL for the room's avatar. */
0065         CanonicalAliasRole, /**< The room canonical alias. */
0066         TopicRole, /**< The room topic. */
0067         CategoryRole, /**< The room category, e.g favourite. */
0068         NotificationCountRole, /**< The number of notifications in the room. */
0069         HighlightCountRole, /**< The number of highlighted messages in the room. */
0070         LastActiveTimeRole, /**< The timestamp of the last event sent in the room. */
0071         JoinStateRole, /**< The local user's join state in the room. */
0072         CurrentRoomRole, /**< The room object for the room. */
0073         CategoryVisibleRole, /**< If the room's category is visible. */
0074         SubtitleTextRole, /**< The text to show as the room subtitle. */
0075         AvatarImageRole, /**< The room avatar as an image. */
0076         RoomIdRole, /**< The room matrix ID. */
0077         IsSpaceRole, /**< Whether the room is a space. */
0078         IsChildSpaceRole, /**< Whether this space is a child of a different space. */
0079         ReplacementIdRole, /**< The room id of the room replacing this one, if any. */
0080         IsDirectChat, /**< Whether this room is a direct chat. */
0081     };
0082     Q_ENUM(EventRoles)
0083 
0084     explicit RoomListModel(QObject *parent = nullptr);
0085     ~RoomListModel() override;
0086 
0087     [[nodiscard]] Quotient::Connection *connection() const;
0088     void setConnection(Quotient::Connection *connection);
0089 
0090     [[nodiscard]] int notificationCount() const;
0091     [[nodiscard]] int highlightCount() const;
0092 
0093     /**
0094      * @brief Get the given role value at the given index.
0095      *
0096      * @sa QAbstractItemModel::data
0097      */
0098     [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0099 
0100     /**
0101      * @brief Number of rows in the model.
0102      *
0103      * @sa QAbstractItemModel::rowCount
0104      */
0105     Q_INVOKABLE [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0106 
0107     /**
0108      * @brief Returns a mapping from Role enum values to role names.
0109      *
0110      * @sa EventRoles, QAbstractItemModel::roleNames()
0111      */
0112     [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
0113 
0114     /**
0115      * @brief Return the room at the given row.
0116      */
0117     Q_INVOKABLE [[nodiscard]] NeoChatRoom *roomAt(int row) const;
0118 
0119     /**
0120      * @brief Return a string to represent the given room category.
0121      */
0122     Q_INVOKABLE [[nodiscard]] static QString categoryName(int category);
0123 
0124     /**
0125      * @brief Return a string with the name of the given room category icon.
0126      */
0127     Q_INVOKABLE [[nodiscard]] static QString categoryIconName(int category);
0128 
0129     /**
0130      * @brief Set whether a given category should be visible or not.
0131      *
0132      * @param category the NeoChatRoomType::Types value for the category (it's an
0133      *                 int due to the pain of Q_INVOKABLES and cpp enums).
0134      * @param visible true if the category should be visible, false if not.
0135      */
0136     Q_INVOKABLE void setCategoryVisible(int category, bool visible);
0137 
0138     /**
0139      * @brief Return whether a room category is set to be visible.
0140      */
0141     Q_INVOKABLE [[nodiscard]] bool categoryVisible(int category) const;
0142 
0143     /**
0144      * @brief Return the model row for the given room.
0145      */
0146     Q_INVOKABLE [[nodiscard]] int rowForRoom(NeoChatRoom *room) const;
0147 
0148     /**
0149      * @brief Return a room for the given room alias or room matrix ID.
0150      *
0151      * The room must be in the model.
0152      */
0153     Q_INVOKABLE NeoChatRoom *roomByAliasOrId(const QString &aliasOrId);
0154 
0155 private Q_SLOTS:
0156     void doResetModel();
0157     void doAddRoom(Quotient::Room *room);
0158     void updateRoom(Quotient::Room *room, Quotient::Room *prev);
0159     void deleteRoom(Quotient::Room *room);
0160     void refresh(NeoChatRoom *room, const QList<int> &roles = {});
0161     void refreshNotificationCount();
0162     void refreshHighlightCount();
0163 
0164 private:
0165     Quotient::Connection *m_connection = nullptr;
0166     QList<NeoChatRoom *> m_rooms;
0167 
0168     QMap<int, bool> m_categoryVisibility;
0169 
0170     int m_notificationCount = 0;
0171     int m_highlightCount = 0;
0172     QString m_activeSpaceId;
0173 
0174     void connectRoomSignals(NeoChatRoom *room);
0175 
0176 Q_SIGNALS:
0177     void connectionChanged();
0178     void notificationCountChanged();
0179     void highlightCountChanged();
0180 
0181     void roomAdded(NeoChatRoom *_t1);
0182 };