Refactor lastEvent
Now lastEvent() return the last event and lastActiveTime() and lastEventToString() are convenient functions to get the visual representation and the timestamp. We are also now fetching new events when the timeline is empty so that we can correctly order the rooms. In the future, we should instead probably cache the last event in an SQLite database to optimize the startup time. This also ignore state event when the configuration ask to ignore them. Fix: #97
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
#include "notificationsmanager.h"
|
#include "notificationsmanager.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "neochatconfig.h"
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
||||||
@@ -63,7 +64,11 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
|
|||||||
NotificationsManager::instance().postNotification(id(), lastEvent->id(), displayName(), sender->displayname(this), eventToString(*lastEvent), avatar(128));
|
NotificationsManager::instance().postNotification(id(), lastEvent->id(), displayName(), sender->displayname(this), eventToString(*lastEvent), avatar(128));
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &Room::aboutToAddHistoricalMessages, this, &NeoChatRoom::readMarkerLoadedChanged);
|
connect(this, &Room::aboutToAddHistoricalMessages,
|
||||||
|
this, &NeoChatRoom::readMarkerLoadedChanged);
|
||||||
|
|
||||||
|
connect(this, &Quotient::Room::eventsHistoryJobChanged,
|
||||||
|
this, &NeoChatRoom::lastActiveTimeChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeoChatRoom::uploadFile(const QUrl &url, const QString &body)
|
void NeoChatRoom::uploadFile(const QUrl &url, const QString &body)
|
||||||
@@ -120,37 +125,48 @@ void NeoChatRoom::sendTypingNotification(bool isTyping)
|
|||||||
connection()->callApi<SetTypingJob>(BackgroundRequest, localUser()->id(), id(), isTyping, 10000);
|
connection()->callApi<SetTypingJob>(BackgroundRequest, localUser()->id(), id(), isTyping, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NeoChatRoom::lastEvent() const
|
const RoomMessageEvent *NeoChatRoom::lastEvent(bool ignoreStateEvent) const
|
||||||
{
|
{
|
||||||
for (auto i = messageEvents().rbegin(); i < messageEvents().rend(); i++) {
|
for (auto timelineItem = messageEvents().rbegin(); timelineItem < messageEvents().rend(); timelineItem++) {
|
||||||
const RoomEvent *evt = i->get();
|
const RoomEvent *event = timelineItem->get();
|
||||||
|
|
||||||
if (is<RedactionEvent>(*evt) || is<ReactionEvent>(*evt)) {
|
if (is<RedactionEvent>(*event) || is<ReactionEvent>(*event)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (evt->isRedacted()) {
|
if (event->isRedacted()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt->isStateEvent() && static_cast<const StateEventBase &>(*evt).repeatsState()) {
|
if (event->isStateEvent() && (ignoreStateEvent || !NeoChatConfig::self()->showLeaveJoinEvent() || static_cast<const StateEventBase &>(*event).repeatsState())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto e = eventCast<const RoomMessageEvent>(evt)) {
|
if (auto roomEvent = eventCast<const RoomMessageEvent>(event)) {
|
||||||
if (!e->replacedEvent().isEmpty() && e->replacedEvent() != e->id()) {
|
if (!roomEvent->replacedEvent().isEmpty() && roomEvent->replacedEvent() != roomEvent->id()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection()->isIgnored(user(evt->senderId()))) {
|
if (connection()->isIgnored(user(event->senderId()))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return user(evt->senderId())->displayname() + (evt->isStateEvent() ? " " : ": ") + eventToString(*evt);
|
if (auto lastEvent = eventCast<const RoomMessageEvent>(event)) {
|
||||||
|
return lastEvent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString NeoChatRoom::lastEventToString() const
|
||||||
|
{
|
||||||
|
if (auto event = lastEvent()) {
|
||||||
|
return user(event->senderId())->displayname() + (event->isStateEvent() ? " " : ": ") + eventToString(*event);
|
||||||
|
}
|
||||||
|
return QLatin1String("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NeoChatRoom::isEventHighlighted(const RoomEvent *e) const
|
bool NeoChatRoom::isEventHighlighted(const RoomEvent *e) const
|
||||||
{
|
{
|
||||||
return highlights.contains(e);
|
return highlights.contains(e);
|
||||||
@@ -201,11 +217,22 @@ void NeoChatRoom::countChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime NeoChatRoom::lastActiveTime() const
|
QDateTime NeoChatRoom::lastActiveTime()
|
||||||
{
|
{
|
||||||
if (timelineSize() == 0) {
|
if (timelineSize() == 0) {
|
||||||
|
QTimer::singleShot(0, this, [=]() {
|
||||||
|
if (localUser()) {
|
||||||
|
getPreviousContent(10);
|
||||||
|
}
|
||||||
|
});
|
||||||
return QDateTime();
|
return QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto event = lastEvent(true)) {
|
||||||
|
return event->originTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// no message found, take last event
|
||||||
return messageEvents().rbegin()->get()->originTimestamp();
|
return messageEvents().rbegin()->get()->originTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,16 +31,31 @@ class NeoChatRoom : public Room
|
|||||||
Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY fileUploadingProgressChanged)
|
Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY fileUploadingProgressChanged)
|
||||||
Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false)
|
Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false)
|
||||||
Q_PROPERTY(bool readMarkerLoaded READ readMarkerLoaded NOTIFY readMarkerLoadedChanged)
|
Q_PROPERTY(bool readMarkerLoaded READ readMarkerLoaded NOTIFY readMarkerLoadedChanged)
|
||||||
|
Q_PROPERTY(QDateTime lastActiveTime READ lastActiveTime NOTIFY lastActiveTimeChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NeoChatRoom(Connection *connection, QString roomId, JoinState joinState = {});
|
explicit NeoChatRoom(Connection *connection, QString roomId, JoinState joinState = {});
|
||||||
|
|
||||||
[[nodiscard]] QVariantList getUsersTyping() const;
|
[[nodiscard]] QVariantList getUsersTyping() const;
|
||||||
|
|
||||||
[[nodiscard]] QString lastEvent() const;
|
/// Get the interesting last event.
|
||||||
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
|
///
|
||||||
|
/// This function respect the showLeaveJoinEvent setting and discard
|
||||||
|
/// other not interesting events. This function can return an empty pointer
|
||||||
|
/// when the room is empty of RoomMessageEvent.
|
||||||
|
[[nodiscard]] const RoomMessageEvent *lastEvent(bool ignoreStateEvent = false) const;
|
||||||
|
|
||||||
[[nodiscard]] QDateTime lastActiveTime() const;
|
/// Convenient way to get the last event but in a string format.
|
||||||
|
///
|
||||||
|
/// \see lastEvent
|
||||||
|
[[nodiscard]] QString lastEventToString() const;
|
||||||
|
|
||||||
|
/// Convenient way to get the QDateTime of the last event.
|
||||||
|
///
|
||||||
|
/// \see lastEvent
|
||||||
|
[[nodiscard]] QDateTime lastActiveTime();
|
||||||
|
|
||||||
|
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
|
||||||
|
|
||||||
[[nodiscard]] bool hasFileUploading() const
|
[[nodiscard]] bool hasFileUploading() const
|
||||||
{
|
{
|
||||||
@@ -112,6 +127,7 @@ Q_SIGNALS:
|
|||||||
void fileUploadingProgressChanged();
|
void fileUploadingProgressChanged();
|
||||||
void backgroundChanged();
|
void backgroundChanged();
|
||||||
void readMarkerLoadedChanged();
|
void readMarkerLoadedChanged();
|
||||||
|
void lastActiveTimeChanged();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void uploadFile(const QUrl &url, const QString &body = "");
|
void uploadFile(const QUrl &url, const QString &body = "");
|
||||||
|
|||||||
@@ -136,15 +136,19 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
|
|||||||
if (room->timelineSize() == 0) {
|
if (room->timelineSize() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const RoomEvent *lastEvent = room->messageEvents().rbegin()->get();
|
auto *lastEvent = room->lastEvent();
|
||||||
if (lastEvent->isStateEvent()) {
|
|
||||||
|
if (!lastEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
User *sender = room->user(lastEvent->senderId());
|
|
||||||
if (sender == room->localUser()) {
|
if (!lastEvent->isStateEvent()) {
|
||||||
return;
|
User *sender = room->user(lastEvent->senderId());
|
||||||
|
if (sender == room->localUser()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_EMIT newMessage(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
|
||||||
}
|
}
|
||||||
Q_EMIT newMessage(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
|
|
||||||
});
|
});
|
||||||
connect(room, &Room::highlightCountChanged, this, [=] {
|
connect(room, &Room::highlightCountChanged, this, [=] {
|
||||||
if (room->highlightCount() == 0) {
|
if (room->highlightCount() == 0) {
|
||||||
@@ -153,15 +157,19 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
|
|||||||
if (room->timelineSize() == 0) {
|
if (room->timelineSize() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const RoomEvent *lastEvent = room->messageEvents().rbegin()->get();
|
auto *lastEvent = room->lastEvent();
|
||||||
if (lastEvent->isStateEvent()) {
|
|
||||||
|
if (!lastEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
User *sender = room->user(lastEvent->senderId());
|
|
||||||
if (sender == room->localUser()) {
|
if (!lastEvent->isStateEvent()) {
|
||||||
return;
|
User *sender = room->user(lastEvent->senderId());
|
||||||
|
if (sender == room->localUser()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_EMIT newHighlight(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
|
||||||
}
|
}
|
||||||
Q_EMIT newHighlight(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
|
|
||||||
});
|
});
|
||||||
connect(room, &Room::notificationCountChanged, this, &RoomListModel::refreshNotificationCount);
|
connect(room, &Room::notificationCountChanged, this, &RoomListModel::refreshNotificationCount);
|
||||||
}
|
}
|
||||||
@@ -279,7 +287,7 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
|
|||||||
return room->highlightCount();
|
return room->highlightCount();
|
||||||
}
|
}
|
||||||
if (role == LastEventRole) {
|
if (role == LastEventRole) {
|
||||||
return room->lastEvent();
|
return room->lastEventToString();
|
||||||
}
|
}
|
||||||
if (role == LastActiveTimeRole) {
|
if (role == LastActiveTimeRole) {
|
||||||
return room->lastActiveTime();
|
return room->lastActiveTime();
|
||||||
|
|||||||
Reference in New Issue
Block a user