File indexing completed on 2024-10-06 04:33:36

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 <QConcatenateTablesProxyModel>
0008 #include <QQmlEngine>
0009 
0010 #include "messageeventmodel.h"
0011 #include "neochatroom.h"
0012 
0013 /**
0014  * @class TimelineEndModel
0015  *
0016  * A model to provide a single delegate to mark the end of the timeline.
0017  *
0018  * The delegate will either be a loading delegate if more events are being loaded
0019  * or a timeline end delegate if all history is loaded.
0020  */
0021 class TimelineEndModel : public QAbstractListModel
0022 {
0023     Q_OBJECT
0024     QML_ELEMENT
0025 
0026 public:
0027     /**
0028      * @brief Defines the model roles.
0029      */
0030     enum Roles {
0031         DelegateTypeRole = MessageEventModel::DelegateTypeRole, /**< The delegate type of the message. */
0032     };
0033     Q_ENUM(Roles)
0034 
0035     explicit TimelineEndModel(QObject *parent = nullptr);
0036 
0037     /**
0038      * @brief Set the room for the timeline.
0039      */
0040     void setRoom(NeoChatRoom *room);
0041 
0042     /**
0043      * @brief Get the given role value at the given index.
0044      *
0045      * @sa QAbstractItemModel::data
0046      */
0047     [[nodiscard]] QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
0048 
0049     /**
0050      * @brief 1, the answer is always 1.
0051      *
0052      * @sa  QAbstractItemModel::rowCount
0053      */
0054     [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0055 
0056     /**
0057      * @brief Returns a map with DelegateTypeRole it's the only one.
0058      *
0059      * @sa Roles, QAbstractItemModel::roleNames()
0060      */
0061     [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
0062 
0063 private:
0064     NeoChatRoom *m_room = nullptr;
0065 };
0066 
0067 /**
0068  * @class TimelineModel
0069  *
0070  * A model to visualise a room timeline.
0071  *
0072  * This model combines a MessageEventModel with a TimelineEndModel.
0073  *
0074  * @sa MessageEventModel, TimelineEndModel
0075  */
0076 class TimelineModel : public QConcatenateTablesProxyModel
0077 {
0078     Q_OBJECT
0079     QML_ELEMENT
0080 
0081     /**
0082      * @brief The current room that the model is getting its messages from.
0083      */
0084     Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
0085 
0086     /**
0087      * @brief The MessageEventModel for the timeline.
0088      */
0089     Q_PROPERTY(MessageEventModel *messageEventModel READ messageEventModel CONSTANT)
0090 
0091 public:
0092     TimelineModel(QObject *parent = nullptr);
0093 
0094     [[nodiscard]] NeoChatRoom *room() const;
0095     void setRoom(NeoChatRoom *room);
0096 
0097     MessageEventModel *messageEventModel() const;
0098 
0099     /**
0100      * @brief Returns a mapping from Role enum values to role names.
0101      *
0102      * @sa Roles, QAbstractProxyModel::roleNames()
0103      */
0104     [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
0105 
0106 Q_SIGNALS:
0107     void roomChanged();
0108 
0109 private:
0110     MessageEventModel *m_messageEventModel = nullptr;
0111     TimelineEndModel *m_timelineEndModel = nullptr;
0112 };