diff --git a/CMakeLists.txt b/CMakeLists.txt index c669262b..b0a5c610 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,7 @@ set(SRC_FILES src/TopRoomBar.cc src/TrayIcon.cc src/TypingDisplay.cc + src/Utils.cc src/UserInfoWidget.cc src/UserSettingsPage.cc src/WelcomePage.cc diff --git a/include/Utils.h b/include/Utils.h new file mode 100644 index 00000000..183ebbbe --- /dev/null +++ b/include/Utils.h @@ -0,0 +1,20 @@ +#pragma once + +#include "RoomInfoListItem.h" + +#include +#include + +namespace utils { + +using TimelineEvent = mtx::events::collections::TimelineEvents; + +//! Human friendly timestamp representation. +QString +descriptiveTime(const QDateTime &then); + +//! Generate a message description from the event to be displayed +//! in the RoomList. +DescInfo +getMessageDescription(const TimelineEvent &event, const QString &localUser); +} diff --git a/include/timeline/TimelineItem.h b/include/timeline/TimelineItem.h index 78fb95c9..d7e7911a 100644 --- a/include/timeline/TimelineItem.h +++ b/include/timeline/TimelineItem.h @@ -28,6 +28,7 @@ #include "AvatarProvider.h" #include "RoomInfoListItem.h" #include "TimelineViewManager.h" +#include "Utils.h" class ImageItem; class AudioItem; @@ -107,7 +108,6 @@ private: void generateBody(const QString &body); void generateBody(const QString &userid, const QString &body); void generateTimestamp(const QDateTime &time); - QString descriptiveTime(const QDateTime &then); void setupAvatarLayout(const QString &userName); void setupSimpleLayout(); @@ -145,8 +145,11 @@ TimelineItem::setupLocalWidgetLayout(Widget *widget, auto displayName = TimelineViewManager::displayName(userid); auto timestamp = QDateTime::currentDateTime(); - descriptionMsg_ = { - "You", userid, QString(" %1").arg(msgDescription), descriptiveTime(timestamp), timestamp}; + descriptionMsg_ = {"You", + userid, + QString(" %1").arg(msgDescription), + utils::descriptiveTime(timestamp), + timestamp}; generateTimestamp(timestamp); @@ -187,7 +190,7 @@ TimelineItem::setupWidgetLayout(Widget *widget, descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName, sender, msgDescription, - descriptiveTime(timestamp), + utils::descriptiveTime(timestamp), timestamp}; generateTimestamp(timestamp); diff --git a/include/timeline/TimelineView.h b/include/timeline/TimelineView.h index caf4634a..cde64148 100644 --- a/include/timeline/TimelineView.h +++ b/include/timeline/TimelineView.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -119,10 +118,13 @@ protected: bool event(QEvent *event) override; private: + using TimelineEvent = mtx::events::collections::TimelineEvents; + void init(); void addTimelineItem(TimelineItem *item, TimelineDirection direction); void updateLastSender(const QString &user_id, TimelineDirection direction); void notifyForLastEvent(); + void notifyForLastEvent(const TimelineEvent &event); void readLastEvent() const; bool isScrollbarActivated() { return scroll_area_->verticalScrollBar()->value() != 0; } QString getLastEventId() const; @@ -193,6 +195,18 @@ private: TimelineDirection lastMessageDirection_; + //! Messages received by sync not added to the timeline. + std::vector bottomMessages_; + + //! Render the given timeline events to the bottom of the timeline. + void renderBottomEvents(const std::vector &events); + + //! Decide if the given timeline event can be rendered. + inline bool isViewable(const TimelineEvent &event) const; + + //! Decide if the given event should trigger a notification. + inline bool isNotifiable(const TimelineEvent &event) const; + // The events currently rendered. Used for duplicate detection. QMap eventIds_; QQueue pending_msgs_; @@ -204,20 +218,19 @@ template void TimelineView::addUserMessage(const QString &url, const QString &filename) { - QSettings settings; - auto user_id = settings.value("auth/user_id").toString(); - auto with_sender = lastSender_ != user_id; + auto with_sender = lastSender_ != local_user_; auto widget = new Widget(client_, url, filename, this); - TimelineItem *view_item = new TimelineItem(widget, user_id, with_sender, scroll_widget_); + TimelineItem *view_item = + new TimelineItem(widget, local_user_, with_sender, scroll_widget_); scroll_layout_->addWidget(view_item); lastMessageDirection_ = TimelineDirection::Bottom; QApplication::processEvents(); - lastSender_ = user_id; + lastSender_ = local_user_; int txn_id = client_->incrementTransactionId(); diff --git a/src/Utils.cc b/src/Utils.cc new file mode 100644 index 00000000..663f7196 --- /dev/null +++ b/src/Utils.cc @@ -0,0 +1,121 @@ +#include "Utils.h" +#include "timeline/TimelineViewManager.h" + +#include + +using TimelineEvent = mtx::events::collections::TimelineEvents; + +QString +utils::descriptiveTime(const QDateTime &then) +{ + const auto now = QDateTime::currentDateTime(); + const auto days = then.daysTo(now); + + if (days == 0) + return then.toString("HH:mm"); + else if (days < 2) + return QString("Yesterday"); + else if (days < 365) + return then.toString("dd/MM"); + + return then.toString("dd/MM/yy"); +} + +DescInfo +utils::getMessageDescription(const TimelineEvent &event, const QString &localUser) +{ + using Audio = mtx::events::RoomEvent; + using Emote = mtx::events::RoomEvent; + using File = mtx::events::RoomEvent; + using Image = mtx::events::RoomEvent; + using Notice = mtx::events::RoomEvent; + using Text = mtx::events::RoomEvent; + using Video = mtx::events::RoomEvent; + + if (mpark::holds_alternative