File indexing completed on 2024-12-08 07:33:46

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     };
0081     Q_ENUM(EventRoles)
0082 
0083     explicit RoomListModel(QObject *parent = nullptr);
0084     ~RoomListModel() override;
0085 
0086     [[nodiscard]] Quotient::Connection *connection() const;
0087     void setConnection(Quotient::Connection *connection);
0088 
0089     [[nodiscard]] int notificationCount() const;
0090     [[nodiscard]] int highlightCount() const;
0091 
0092     /**
0093      * @brief Get the given role value at the given index.
0094      *
0095      * @sa QAbstractItemModel::data
0096      */
0097     [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0098 
0099     /**
0100      * @brief Number of rows in the model.
0101      *
0102      * @sa QAbstractItemModel::rowCount
0103      */
0104     Q_INVOKABLE [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0105 
0106     /**
0107      * @brief Returns a mapping from Role enum values to role names.
0108      *
0109      * @sa EventRoles, QAbstractItemModel::roleNames()
0110      */
0111     [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
0112 
0113     /**
0114      * @brief Return the room at the given row.
0115      */
0116     Q_INVOKABLE [[nodiscard]] NeoChatRoom *roomAt(int row) const;
0117 
0118     /**
0119      * @brief Return a string to represent the given room category.
0120      */
0121     Q_INVOKABLE [[nodiscard]] static QString categoryName(int category);
0122 
0123     /**
0124      * @brief Return a string with the name of the given room category icon.
0125      */
0126     Q_INVOKABLE [[nodiscard]] static QString categoryIconName(int category);
0127 
0128     /**
0129      * @brief Set whether a given category should be visible or not.
0130      *
0131      * @param category the NeoChatRoomType::Types value for the category (it's an
0132      *                 int due to the pain of Q_INVOKABLES and cpp enums).
0133      * @param visible true if the category should be visible, false if not.
0134      */
0135     Q_INVOKABLE void setCategoryVisible(int category, bool visible);
0136 
0137     /**
0138      * @brief Return whether a room category is set to be visible.
0139      */
0140     Q_INVOKABLE [[nodiscard]] bool categoryVisible(int category) const;
0141 
0142     /**
0143      * @brief Return the model row for the given room.
0144      */
0145     Q_INVOKABLE [[nodiscard]] int rowForRoom(NeoChatRoom *room) const;
0146 
0147     /**
0148      * @brief Return a room for the given room alias or room matrix ID.
0149      *
0150      * The room must be in the model.
0151      */
0152     Q_INVOKABLE NeoChatRoom *roomByAliasOrId(const QString &aliasOrId);
0153 
0154 private Q_SLOTS:
0155     void doResetModel();
0156     void doAddRoom(Quotient::Room *room);
0157     void updateRoom(Quotient::Room *room, Quotient::Room *prev);
0158     void deleteRoom(Quotient::Room *room);
0159     void refresh(NeoChatRoom *room, const QList<int> &roles = {});
0160     void refreshNotificationCount();
0161     void refreshHighlightCount();
0162 
0163 private:
0164     Quotient::Connection *m_connection = nullptr;
0165     QList<NeoChatRoom *> m_rooms;
0166 
0167     QMap<int, bool> m_categoryVisibility;
0168 
0169     int m_notificationCount = 0;
0170     int m_highlightCount = 0;
0171     QString m_activeSpaceId;
0172 
0173     void connectRoomSignals(NeoChatRoom *room);
0174 
0175 Q_SIGNALS:
0176     void connectionChanged();
0177     void notificationCountChanged();
0178     void highlightCountChanged();
0179 
0180     void roomAdded(NeoChatRoom *_t1);
0181 };