1 // SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org> 2 // SPDX-License-Identifier: GPL-3.0-only 3 4 #pragma once 5 6 #include <events/encryptionevent.h> 7 #include <events/redactionevent.h> 8 #include <events/roomavatarevent.h> 9 #include <events/roomcreateevent.h> 10 #include <events/roommemberevent.h> 11 #include <events/roommessageevent.h> 12 #include <events/simplestateevents.h> 13 14 #include <QObject> 15 #include <QPointer> 16 #include <QTimer> 17 18 #include "neochatuser.h" 19 #include "room.h" 20 21 using namespace Quotient; 22 23 class NeoChatRoom : public Room 24 { 25 Q_OBJECT 26 Q_PROPERTY(QVariantList usersTyping READ getUsersTyping NOTIFY typingChanged) 27 Q_PROPERTY(QString cachedInput MEMBER m_cachedInput NOTIFY cachedInputChanged) 28 Q_PROPERTY(bool hasFileUploading READ hasFileUploading WRITE setHasFileUploading NOTIFY hasFileUploadingChanged) 29 Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY fileUploadingProgressChanged) 30 Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false) 31 Q_PROPERTY(bool readMarkerLoaded READ readMarkerLoaded NOTIFY readMarkerLoadedChanged) 32 Q_PROPERTY(QDateTime lastActiveTime READ lastActiveTime NOTIFY lastActiveTimeChanged) 33 Q_PROPERTY(bool isInvite READ isInvite NOTIFY isInviteChanged) 34 35 public: 36 explicit NeoChatRoom(Connection *connection, QString roomId, JoinState joinState = {}); 37 38 [[nodiscard]] QVariantList getUsersTyping() const; 39 40 /// Get the interesting last event. 41 /// 42 /// This function respect the showLeaveJoinEvent setting and discard 43 /// other not interesting events. This function can return an empty pointer 44 /// when the room is empty of RoomMessageEvent. 45 [[nodiscard]] const RoomMessageEvent *lastEvent(bool ignoreStateEvent = false) const; 46 47 /// Convenient way to get the last event but in a string format. 48 /// 49 /// \see lastEvent 50 [[nodiscard]] QString lastEventToString() const; 51 52 /// Convenient way to get the QDateTime of the last event. 53 /// 54 /// \see lastEvent 55 [[nodiscard]] QDateTime lastActiveTime(); 56 57 bool isEventHighlighted(const Quotient::RoomEvent *e) const; 58 hasFileUploading()59 [[nodiscard]] bool hasFileUploading() const 60 { 61 return m_hasFileUploading; 62 } setHasFileUploading(bool value)63 void setHasFileUploading(bool value) 64 { 65 if (value == m_hasFileUploading) { 66 return; 67 } 68 m_hasFileUploading = value; 69 Q_EMIT hasFileUploadingChanged(); 70 } 71 fileUploadingProgress()72 [[nodiscard]] int fileUploadingProgress() const 73 { 74 return m_fileUploadingProgress; 75 } setFileUploadingProgress(int value)76 void setFileUploadingProgress(int value) 77 { 78 if (m_fileUploadingProgress == value) { 79 return; 80 } 81 m_fileUploadingProgress = value; 82 Q_EMIT fileUploadingProgressChanged(); 83 } 84 85 [[nodiscard]] bool readMarkerLoaded() const; 86 87 Q_INVOKABLE [[nodiscard]] int savedTopVisibleIndex() const; 88 Q_INVOKABLE [[nodiscard]] int savedBottomVisibleIndex() const; 89 Q_INVOKABLE void saveViewport(int topIndex, int bottomIndex); 90 91 Q_INVOKABLE [[nodiscard]] QVariantList getUsers(const QString &keyword) const; 92 Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const; 93 94 Q_INVOKABLE QUrl urlToMxcUrl(const QUrl &mxcUrl); 95 96 [[nodiscard]] QString avatarMediaId() const; 97 98 [[nodiscard]] QString eventToString(const RoomEvent &evt, Qt::TextFormat format = Qt::PlainText, bool removeReply = true) const; 99 100 Q_INVOKABLE [[nodiscard]] bool containsUser(const QString &userID) const; 101 Q_INVOKABLE [[nodiscard]] bool isUserBanned(const QString &user) const; 102 103 Q_INVOKABLE [[nodiscard]] bool canSendEvent(const QString &eventType) const; 104 Q_INVOKABLE [[nodiscard]] bool canSendState(const QString &eventType) const; 105 106 bool isInvite() const; 107 108 private: 109 QString m_cachedInput; 110 QSet<const Quotient::RoomEvent *> highlights; 111 112 bool m_hasFileUploading = false; 113 int m_fileUploadingProgress = 0; 114 115 void checkForHighlights(const Quotient::TimelineItem &ti); 116 117 void onAddNewTimelineEvents(timeline_iter_t from) override; 118 void onAddHistoricalTimelineEvents(rev_iter_t from) override; 119 void onRedaction(const RoomEvent &prevEvent, const RoomEvent &after) override; 120 121 static QString markdownToHTML(const QString &markdown); 122 123 private Q_SLOTS: 124 void countChanged(); 125 126 Q_SIGNALS: 127 void cachedInputChanged(); 128 void busyChanged(); 129 void hasFileUploadingChanged(); 130 void fileUploadingProgressChanged(); 131 void backgroundChanged(); 132 void readMarkerLoadedChanged(); 133 void lastActiveTimeChanged(); 134 void isInviteChanged(); 135 136 public Q_SLOTS: 137 void uploadFile(const QUrl &url, const QString &body = QString()); 138 void acceptInvitation(); 139 void forget(); 140 void sendTypingNotification(bool isTyping); 141 /// @param rawText The text as it was typed. 142 /// @param cleanedText The text with link to the users. 143 void postMessage(const QString &rawText, 144 const QString &cleanedText, 145 Quotient::MessageEventType type = Quotient::MessageEventType::Text, 146 const QString &replyEventId = QString(), 147 const QString &relateToEventId = QString()); 148 void postHtmlMessage(const QString &text, 149 const QString &html, 150 Quotient::MessageEventType type = Quotient::MessageEventType::Text, 151 const QString &replyEventId = QString(), 152 const QString &relateToEventId = QString()); 153 void changeAvatar(const QUrl &localFile); 154 void addLocalAlias(const QString &alias); 155 void removeLocalAlias(const QString &alias); 156 void toggleReaction(const QString &eventId, const QString &reaction); 157 }; 158