// SPDX-FileCopyrightText: 2018-2019 Black Hat // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include "neochatroom.h" class MessageEventModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged) public: enum DelegateType { Emote, Notice, Image, Audio, Video, File, Message, Sticker, State, Encrypted, ReadMarker, Poll, Other, }; Q_ENUM(DelegateType); enum EventRoles { EventTypeRole = Qt::UserRole + 1, MessageRole, EventIdRole, TimeRole, SectionRole, AuthorRole, ContentRole, ContentTypeRole, HighlightRole, SpecialMarksRole, LongOperationRole, AnnotationRole, UserMarkerRole, FormattedBodyRole, GenericDisplayRole, MimeTypeRole, FileMimetypeIcon, IsReplyRole, ReplyRole, ReplyIdRole, ShowAuthorRole, ShowSectionRole, ReadMarkersRole, /**< QVariantList of users at the event for read marker tracking. */ ReadMarkersStringRole, /**< QString with the display name and mxID of the users at the event. */ ShowReadMarkersRole, /**< bool with whether there are any other user read markers to be shown. */ ReactionRole, IsEditedRole, SourceRole, MediaUrlRole, // For debugging EventResolvedTypeRole, AuthorIdRole, VerifiedRole, // Sender's displayname, always without the matrix id DisplayNameForInitialsRole, // The displayname for the event's sender; for name change events, the old displayname AuthorDisplayNameRole, IsNameChangeRole, IsAvatarChangeRole, IsRedactedRole, IsPendingRole, LastRole, // Keep this last }; Q_ENUM(EventRoles) explicit MessageEventModel(QObject *parent = nullptr); ~MessageEventModel() override; [[nodiscard]] NeoChatRoom *room() const { return m_currentRoom; } void setRoom(NeoChatRoom *room); [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override; [[nodiscard]] QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override; [[nodiscard]] QHash roleNames() const override; Q_INVOKABLE [[nodiscard]] int eventIDToIndex(const QString &eventID) const; Q_INVOKABLE [[nodiscard]] QVariant getLastLocalUserMessageEventId(); Q_INVOKABLE [[nodiscard]] QVariant getLatestMessageFromIndex(const int baseline); Q_INVOKABLE void loadReply(const QModelIndex &row); private Q_SLOTS: int refreshEvent(const QString &eventId); void refreshRow(int row); private: NeoChatRoom *m_currentRoom = nullptr; QString lastReadEventId; QPersistentModelIndex m_lastReadEventIndex; int rowBelowInserted = -1; bool movingEvent = false; [[nodiscard]] int timelineBaseIndex() const; [[nodiscard]] QDateTime makeMessageTimestamp(const Quotient::Room::rev_iter_t &baseIt) const; [[nodiscard]] static QString renderDate(const QDateTime ×tamp); bool canFetchMore(const QModelIndex &parent) const override; void fetchMore(const QModelIndex &parent) override; void refreshLastUserEvents(int baseTimelineRow); void refreshEventRoles(int row, const QVector &roles = {}); int refreshEventRoles(const QString &eventId, const QVector &roles = {}); void moveReadMarker(const QString &toEventId); std::vector> m_extraEvents; Q_SIGNALS: void roomChanged(); void fancyEffectsReasonFound(const QString &fancyEffect); };