summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/Config.h3
-rw-r--r--include/RoomInfoListItem.h2
-rw-r--r--include/timeline/TimelineItem.h5
-rw-r--r--include/timeline/TimelineView.h1
-rw-r--r--src/timeline/TimelineItem.cc25
-rw-r--r--src/timeline/TimelineView.cc63
6 files changed, 80 insertions, 19 deletions
diff --git a/include/Config.h b/include/Config.h
index 805e7c02..7d35094e 100644
--- a/include/Config.h
+++ b/include/Config.h
@@ -79,7 +79,8 @@ static constexpr int headerSpacing    = 7;
 static constexpr int headerLeftMargin = 15;
 
 namespace fonts {
-static constexpr int timestamp = 10;
+static constexpr int timestamp     = 10;
+static constexpr int dateSeparator = conf::fontSize - 2;
 } // namespace fonts
 } // namespace timeline
 
diff --git a/include/RoomInfoListItem.h b/include/RoomInfoListItem.h
index d4e4f983..bb8e0f1a 100644
--- a/include/RoomInfoListItem.h
+++ b/include/RoomInfoListItem.h
@@ -18,6 +18,7 @@
 #pragma once
 
 #include <QAction>
+#include <QDateTime>
 #include <QSharedPointer>
 #include <QWidget>
 
@@ -35,6 +36,7 @@ struct DescInfo
         QString userid;
         QString body;
         QString timestamp;
+        QDateTime datetime;
 };
 
 class RoomInfoListItem : public QWidget
diff --git a/include/timeline/TimelineItem.h b/include/timeline/TimelineItem.h
index 17b110fc..f1498d1b 100644
--- a/include/timeline/TimelineItem.h
+++ b/include/timeline/TimelineItem.h
@@ -142,7 +142,7 @@ TimelineItem::setupLocalWidgetLayout(Widget *widget,
         auto timestamp   = QDateTime::currentDateTime();
 
         descriptionMsg_ = {
-          "You", userid, QString(" %1").arg(msgDescription), descriptiveTime(timestamp)};
+          "You", userid, QString(" %1").arg(msgDescription), descriptiveTime(timestamp), timestamp};
 
         generateTimestamp(timestamp);
 
@@ -183,7 +183,8 @@ TimelineItem::setupWidgetLayout(Widget *widget,
         descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
                            sender,
                            msgDescription,
-                           descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.origin_server_ts))};
+                           descriptiveTime(timestamp),
+                           timestamp};
 
         generateTimestamp(timestamp);
 
diff --git a/include/timeline/TimelineView.h b/include/timeline/TimelineView.h
index faada44c..caf4634a 100644
--- a/include/timeline/TimelineView.h
+++ b/include/timeline/TimelineView.h
@@ -91,6 +91,7 @@ public:
         void addUserMessage(const QString &url, const QString &filename);
         void updatePendingMessage(int txn_id, QString event_id);
         void scrollDown();
+        void addDateSeparator(QDateTime datetime, int position);
 
 public slots:
         void sliderRangeChanged(int min, int max);
diff --git a/src/timeline/TimelineItem.cc b/src/timeline/TimelineItem.cc
index 3ebbbee0..a42edbb7 100644
--- a/src/timeline/TimelineItem.cc
+++ b/src/timeline/TimelineItem.cc
@@ -73,10 +73,9 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty,
 
         if (ty == mtx::events::MessageType::Emote) {
                 body            = QString("* %1 %2").arg(displayName).arg(body);
-                descriptionMsg_ = {"", userid, body, descriptiveTime(timestamp)};
+                descriptionMsg_ = {"", userid, body, descriptiveTime(timestamp), timestamp};
         } else {
-                descriptionMsg_ = {
-                  "You: ", userid, body, descriptiveTime(QDateTime::currentDateTime())};
+                descriptionMsg_ = {"You: ", userid, body, descriptiveTime(timestamp), timestamp};
         }
 
         body = body.toHtmlEscaped();
@@ -189,16 +188,16 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice
 {
         init();
 
-        event_id_         = QString::fromStdString(event.event_id);
-        const auto sender = QString::fromStdString(event.sender);
+        event_id_            = QString::fromStdString(event.event_id);
+        const auto sender    = QString::fromStdString(event.sender);
+        const auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
+        auto body            = QString::fromStdString(event.content.body).trimmed().toHtmlEscaped();
 
         descriptionMsg_ = {TimelineViewManager::displayName(sender),
                            sender,
                            " sent a notification",
-                           descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.origin_server_ts))};
-
-        auto body      = QString::fromStdString(event.content.body).trimmed().toHtmlEscaped();
-        auto timestamp = QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
+                           descriptiveTime(timestamp),
+                           timestamp};
 
         generateTimestamp(timestamp);
 
@@ -241,10 +240,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Emote>
         auto displayName = TimelineViewManager::displayName(sender);
         auto emoteMsg    = QString("* %1 %2").arg(displayName).arg(body);
 
-        descriptionMsg_ = {"",
-                           sender,
-                           emoteMsg,
-                           descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.origin_server_ts))};
+        descriptionMsg_ = {"", sender, emoteMsg, descriptiveTime(timestamp), timestamp};
 
         generateTimestamp(timestamp);
         emoteMsg = emoteMsg.toHtmlEscaped();
@@ -286,7 +282,8 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Text>
         descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
                            sender,
                            QString(": %1").arg(body),
-                           descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.origin_server_ts))};
+                           descriptiveTime(timestamp),
+                           timestamp};
 
         generateTimestamp(timestamp);
 
diff --git a/src/timeline/TimelineView.cc b/src/timeline/TimelineView.cc
index dccc6f37..29da24b3 100644
--- a/src/timeline/TimelineView.cc
+++ b/src/timeline/TimelineView.cc
@@ -19,6 +19,7 @@
 #include <QFileInfo>
 #include <QTimer>
 
+#include "Config.h"
 #include "FloatingButton.h"
 #include "RoomMessages.h"
 
@@ -368,10 +369,38 @@ TimelineView::isSenderRendered(const QString &user_id, TimelineDirection directi
 void
 TimelineView::addTimelineItem(TimelineItem *item, TimelineDirection direction)
 {
-        if (direction == TimelineDirection::Bottom)
+        const auto newDate = item->descriptionMessage().datetime;
+
+        if (direction == TimelineDirection::Bottom) {
+                const auto lastItemPosition = scroll_layout_->count() - 1;
+                auto lastItem =
+                  static_cast<TimelineItem *>(scroll_layout_->itemAt(lastItemPosition)->widget());
+
+                if (lastItem) {
+                        auto oldDate = lastItem->descriptionMessage().datetime;
+
+                        if (oldDate.daysTo(newDate) != 0)
+                                addDateSeparator(newDate, lastItemPosition);
+                }
+
                 scroll_layout_->addWidget(item);
-        else
+        } else {
+                // The first item (position 0) is a stretch widget that pushes
+                // the widgets to the bottom of the page.
+                if (scroll_layout_->count() > 1) {
+                        auto firstItem =
+                          static_cast<TimelineItem *>(scroll_layout_->itemAt(1)->widget());
+
+                        if (firstItem) {
+                                auto oldDate = firstItem->descriptionMessage().datetime;
+
+                                if (newDate.daysTo(oldDate) != 0)
+                                        addDateSeparator(oldDate, 1);
+                        }
+                }
+
                 scroll_layout_->insertWidget(1, item);
+        }
 }
 
 void
@@ -563,6 +592,36 @@ TimelineView::event(QEvent *event)
         return QWidget::event(event);
 }
 
+void
+TimelineView::addDateSeparator(QDateTime datetime, int position)
+{
+        auto now  = QDateTime::currentDateTime();
+        auto days = now.daysTo(datetime);
+
+        QString fmt;
+        QLabel *separator;
+
+        if (now.date().year() != datetime.date().year())
+                fmt = QString("ddd d MMMM yy");
+        else
+                fmt = QString("ddd d MMMM");
+
+        if (days == 0)
+                separator = new QLabel(tr("Today"));
+        else if (std::abs(days) == 1)
+                separator = new QLabel(tr("Yesterday"));
+        else
+                separator = new QLabel(datetime.toString(fmt));
+
+        if (separator) {
+                separator->setStyleSheet(
+                  QString("font-size: %1px").arg(conf::timeline::fonts::dateSeparator));
+                separator->setAlignment(Qt::AlignCenter);
+                separator->setContentsMargins(0, 15, 0, 15);
+                scroll_layout_->insertWidget(position, separator);
+        }
+}
+
 QString
 TimelineView::getEventSender(const mtx::events::collections::TimelineEvents &event) const
 {