From f22cafbce1d12cf5229fbb53179dcd41a773359a Mon Sep 17 00:00:00 2001 From: James Graham Date: Sun, 25 Jan 2026 13:07:53 +0000 Subject: [PATCH] Revert "Improve time handling in NeoChat" This reverts commit 92c58b0ea09f7ee88103d6c264a52e1a74e21e8a. --- autotests/eventhandlertest.cpp | 39 ++++++++- src/libneochat/CMakeLists.txt | 1 - src/libneochat/eventhandler.cpp | 21 ++++- src/libneochat/eventhandler.h | 38 +++++++- src/libneochat/neochatdatetime.cpp | 48 ----------- src/libneochat/neochatdatetime.h | 86 ------------------- src/messagecontent/AuthorComponent.qml | 13 ++- .../models/eventmessagecontentmodel.cpp | 23 +++-- .../models/eventmessagecontentmodel.h | 3 +- .../models/messagecontentmodel.cpp | 18 ++-- .../models/messagecontentmodel.h | 16 ++-- src/timeline/MessageDelegate.qml | 6 +- src/timeline/StateDelegate.qml | 6 +- .../models/mediamessagefiltermodel.cpp | 6 +- src/timeline/models/messagefiltermodel.cpp | 11 +-- src/timeline/models/messagemodel.cpp | 25 ++++-- src/timeline/models/messagemodel.h | 3 +- 17 files changed, 172 insertions(+), 191 deletions(-) delete mode 100644 src/libneochat/neochatdatetime.cpp delete mode 100644 src/libneochat/neochatdatetime.h diff --git a/autotests/eventhandlertest.cpp b/autotests/eventhandlertest.cpp index ff6dbfc06..2c9da178f 100644 --- a/autotests/eventhandlertest.cpp +++ b/autotests/eventhandlertest.cpp @@ -40,6 +40,7 @@ private Q_SLOTS: void nullSingleLineDisplayName(); void time(); void nullTime(); + void timeString(); void highlighted(); void nullHighlighted(); void hidden(); @@ -99,12 +100,12 @@ void EventHandlerTest::time() { const auto event = room->messageEvents().at(0).get(); - QCOMPARE(EventHandler::dateTime(room, event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC))); + QCOMPARE(EventHandler::time(room, event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC))); const auto txID = room->postJson("m.room.message"_L1, event->fullJson()); QCOMPARE(room->pendingEvents().size(), 1); const auto pendingIt = room->findPendingEvent(txID); - QCOMPARE(EventHandler::dateTime(room, pendingIt->event(), true), pendingIt->lastUpdated()); + QCOMPARE(EventHandler::time(room, pendingIt->event(), true), pendingIt->lastUpdated()); room->discardMessage(txID); QCOMPARE(room->pendingEvents().size(), 0); @@ -113,10 +114,40 @@ void EventHandlerTest::time() void EventHandlerTest::nullTime() { QTest::ignoreMessage(QtWarningMsg, "time called with room set to nullptr."); - QCOMPARE(EventHandler::dateTime(nullptr, nullptr), QDateTime()); + QCOMPARE(EventHandler::time(nullptr, nullptr), QDateTime()); QTest::ignoreMessage(QtWarningMsg, "time called with event set to nullptr."); - QCOMPARE(EventHandler::dateTime(room, nullptr), QDateTime()); + QCOMPARE(EventHandler::time(room, nullptr), QDateTime()); +} + +void EventHandlerTest::timeString() +{ + const auto event = room->messageEvents().at(0).get(); + + KFormat format; + + QCOMPARE(EventHandler::timeString(room, event, false), + QLocale().toString(QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toLocalTime().time(), QLocale::ShortFormat)); + QCOMPARE(EventHandler::timeString(room, event, true), + format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::ShortFormat)); + QCOMPARE(EventHandler::timeString(room, event, u"hh:mm"_s), + QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::LocalTime)).toString(u"hh:mm"_s)); + + const auto txID = room->postJson("m.room.message"_L1, event->fullJson()); + QCOMPARE(room->pendingEvents().size(), 1); + const auto pendingIt = room->findPendingEvent(txID); + + QCOMPARE(EventHandler::timeString(room, pendingIt->event(), false, QLocale::ShortFormat, true), + QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::ShortFormat)); + QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::ShortFormat, true), + format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::ShortFormat)); + QCOMPARE(EventHandler::timeString(room, pendingIt->event(), false, QLocale::LongFormat, true), + QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::LongFormat)); + QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::LongFormat, true), + format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::LongFormat)); + + room->discardMessage(txID); + QCOMPARE(room->pendingEvents().size(), 0); } void EventHandlerTest::highlighted() diff --git a/src/libneochat/CMakeLists.txt b/src/libneochat/CMakeLists.txt index 309d98927..be18088b7 100644 --- a/src/libneochat/CMakeLists.txt +++ b/src/libneochat/CMakeLists.txt @@ -17,7 +17,6 @@ target_sources(LibNeoChat PRIVATE filetransferpseudojob.cpp filetype.cpp linkpreviewer.cpp - neochatdatetime.cpp roomlastmessageprovider.cpp spacehierarchycache.cpp texthandler.cpp diff --git a/src/libneochat/eventhandler.cpp b/src/libneochat/eventhandler.cpp index 9d8b41030..68fd31a01 100644 --- a/src/libneochat/eventhandler.cpp +++ b/src/libneochat/eventhandler.cpp @@ -93,7 +93,7 @@ QString EventHandler::singleLineAuthorDisplayname(const NeoChatRoom *room, const return displayName; } -NeoChatDateTime EventHandler::dateTime(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending) +QDateTime EventHandler::time(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending) { if (room == nullptr) { qCWarning(EventHandling) << "time called with room set to nullptr."; @@ -114,6 +114,25 @@ NeoChatDateTime EventHandler::dateTime(const NeoChatRoom *room, const Quotient:: return event->originTimestamp(); } +QString EventHandler::timeString(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool relative, QLocale::FormatType format, bool isPending) +{ + auto ts = time(room, event, isPending); + if (ts.isValid()) { + if (relative) { + KFormat formatter; + return formatter.formatRelativeDate(ts.toLocalTime().date(), format); + } else { + return QLocale().toString(ts.toLocalTime().time(), format); + } + } + return {}; +} + +QString EventHandler::timeString(const NeoChatRoom *room, const Quotient::RoomEvent *event, const QString &format, bool isPending) +{ + return time(room, event, isPending).toLocalTime().toString(format); +} + bool EventHandler::isHighlighted(const NeoChatRoom *room, const Quotient::RoomEvent *event) { if (room == nullptr) { diff --git a/src/libneochat/eventhandler.h b/src/libneochat/eventhandler.h index d48f0dbf3..baee8d48c 100644 --- a/src/libneochat/eventhandler.h +++ b/src/libneochat/eventhandler.h @@ -7,8 +7,6 @@ #include #include -#include "neochatdatetime.h" - namespace Quotient { namespace EventContent @@ -66,7 +64,41 @@ public: /** * @brief Return a QDateTime object for the event timestamp. */ - static NeoChatDateTime dateTime(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending = false); + static QDateTime time(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending = false); + + /** + * @brief Return a QString for the event timestamp. + * + * This is intended to return a string that is read for display in the UI without + * any further manipulation required. + * + * @param relative whether the string is realtive to the current date, i.e. + * Yesterday or Wednesday, etc. + * @param format the QLocale::FormatType to use. + * @param isPending whether the event is pending as this cannot be derived from + * just the event object. + * @param lastUpdated the time the event was last updated locally as this cannot be + * obtained from the event. + */ + static QString timeString(const NeoChatRoom *room, + const Quotient::RoomEvent *event, + bool relative, + QLocale::FormatType format = QLocale::ShortFormat, + bool isPending = false); + + /** + * @brief Return a QString for the event timestamp. + * + * This is intended to return a string that is read for display in the UI without + * any further manipulation required. + * + * @param format the format to use as a string. + * @param isPending whether the event is pending as this cannot be derived from + * just the event object. + * @param lastUpdated the time the event was last updated locally as this cannot be + * obtained from the event. + */ + static QString timeString(const NeoChatRoom *room, const Quotient::RoomEvent *event, const QString &format, bool isPending = false); /** * @brief Whether the event should be highlighted in the timeline. diff --git a/src/libneochat/neochatdatetime.cpp b/src/libneochat/neochatdatetime.cpp deleted file mode 100644 index ae541a95c..000000000 --- a/src/libneochat/neochatdatetime.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2026 James Graham -// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - -#include "neochatdatetime.h" - -#include - -using namespace Qt::Literals::StringLiterals; - -NeoChatDateTime::NeoChatDateTime(QDateTime dateTime) - : m_dateTime(dateTime) -{ -} - -QDateTime NeoChatDateTime::dateTime() const -{ - return m_dateTime; -} - -QString NeoChatDateTime::hourMinuteString() const -{ - return m_dateTime.toLocalTime().toString(u"hh:mm"_s); -} - -QString NeoChatDateTime::shortDateTime() const -{ - return QLocale().toString(m_dateTime.toLocalTime(), QLocale::ShortFormat); -} - -QString NeoChatDateTime::relativeDate() const -{ - KFormat formatter; - return formatter.formatRelativeDate(m_dateTime.toLocalTime().date(), QLocale::ShortFormat); -} - -QString NeoChatDateTime::relativeDateTime() const -{ - KFormat formatter; - const auto relativePart = formatter.formatRelativeDate(m_dateTime.toLocalTime().date(), QLocale::ShortFormat); - return u"%1, %2"_s.arg(relativePart, hourMinuteString()); -} - -bool NeoChatDateTime::operator==(const QDateTime &right) const -{ - return m_dateTime == right; -} - -#include "moc_neochatdatetime.cpp" diff --git a/src/libneochat/neochatdatetime.h b/src/libneochat/neochatdatetime.h deleted file mode 100644 index 94b5b11cf..000000000 --- a/src/libneochat/neochatdatetime.h +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: 2026 James Graham -// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - -#pragma once - -#include -#include - -/** - * @class NeoChatDateTime - * - * This class is a helper for converting a QDateTime into the various format required in NeoChat. - * - * The intention is that this can be passed to QML and then the various Q_Properties - * can be called to get the date/time in the desired format reading for viewing in - * the UI. - */ -class NeoChatDateTime -{ - Q_GADGET - QML_ELEMENT - - /** - * @brief The base QDateTime used to generate the other values. - */ - Q_PROPERTY(QDateTime dateTime READ dateTime CONSTANT) - - /** - * @brief The time formatted as "hh:mm". - */ - Q_PROPERTY(QString hourMinuteString READ hourMinuteString CONSTANT) - - /** - * @brief The date and time formatted as per QLocale::ShortFormat for your locale. - */ - Q_PROPERTY(QString shortDateTime READ shortDateTime CONSTANT) - - /** - * @brief The date formatted as relative to now. - * - * If the date falls within one week before or after the current date - * then a relative date string will be returned, such as: - * - Yesterday - * - Today - * - Tomorrow - * - Last Tuesday - * - Next Wednesday - * - * If the date falls outside this period then the format QLocale::ShortFormat - * for your locale is used. - */ - Q_PROPERTY(QString relativeDate READ relativeDate CONSTANT) - - /** - * @brief The time and date formatted as relative to now. - * - * The format is "RelativeDate, hh::mm" - * - * If the date falls within one week before or after the current date - * then a relative date string will be returned, such as: - * - Yesterday - * - Today - * - Tomorrow - * - Last Tuesday - * - Next Wednesday - * - * If the date falls outside this period then the format QLocale::ShortFormat - * for your locale is used. - */ - Q_PROPERTY(QString relativeDateTime READ relativeDateTime CONSTANT) - -public: - NeoChatDateTime(QDateTime dateTime = {}); - - QDateTime dateTime() const; - - QString hourMinuteString() const; - QString shortDateTime() const; - QString relativeDate() const; - QString relativeDateTime() const; - - bool operator==(const QDateTime &right) const; - -private: - QDateTime m_dateTime; -}; diff --git a/src/messagecontent/AuthorComponent.qml b/src/messagecontent/AuthorComponent.qml index ef1cd281b..381d8541c 100644 --- a/src/messagecontent/AuthorComponent.qml +++ b/src/messagecontent/AuthorComponent.qml @@ -27,9 +27,14 @@ RowLayout { required property var author /** - * @brief The timestamp of the event as a NeoChatDateTime. + * @brief The timestamp of the message. */ - required property NeoChatDateTime dateTime + required property var time + + /** + * @brief The timestamp of the message as a string. + */ + required property string timeString Layout.fillWidth: true Layout.maximumWidth: Message.maxContentWidth @@ -78,11 +83,11 @@ RowLayout { } QQC2.Label { id: timeLabel - text: root.dateTime.hourMinuteString + text: root.timeString horizontalAlignment: Text.AlignRight color: Kirigami.Theme.disabledTextColor QQC2.ToolTip.visible: timeHoverHandler.hovered - QQC2.ToolTip.text: root.dateTime.shortDateTime + QQC2.ToolTip.text: root.time.toLocaleString(Qt.locale(), Locale.ShortFormat) QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay HoverHandler { diff --git a/src/messagecontent/models/eventmessagecontentmodel.cpp b/src/messagecontent/models/eventmessagecontentmodel.cpp index d01f34a19..19dc47196 100644 --- a/src/messagecontent/models/eventmessagecontentmodel.cpp +++ b/src/messagecontent/models/eventmessagecontentmodel.cpp @@ -16,7 +16,6 @@ #include "contentprovider.h" #include "eventhandler.h" #include "models/reactionmodel.h" -#include "neochatdatetime.h" #include "neochatroom.h" #include "texthandler.h" @@ -124,13 +123,22 @@ void EventMessageContentModel::initializeModel() resetModel(); } -NeoChatDateTime EventMessageContentModel::dateTime() const +QDateTime EventMessageContentModel::time() const { const auto event = m_room->getEvent(m_eventId); if (event.first == nullptr) { - return MessageContentModel::dateTime(); + return MessageContentModel::time(); }; - return EventHandler::dateTime(m_room, event.first, m_currentState == Pending); + return EventHandler::time(m_room, event.first, m_currentState == Pending); +} + +QString EventMessageContentModel::timeString() const +{ + const auto event = m_room->getEvent(m_eventId); + if (event.first == nullptr) { + return MessageContentModel::timeString(); + }; + return EventHandler::timeString(m_room, event.first, u"hh:mm"_s, m_currentState == Pending); } QString EventMessageContentModel::authorId() const @@ -246,7 +254,12 @@ void EventMessageContentModel::resetModel() return; } - m_components += MessageComponent{MessageComponentType::Author, {}, {}}; + m_components += MessageComponent{MessageComponentType::Author, + QString(), + { + {u"time"_s, EventHandler::time(m_room, event.first, m_currentState == Pending)}, + {u"timeString"_s, EventHandler::timeString(m_room, event.first, u"hh:mm"_s, m_currentState == Pending)}, + }}; m_components += messageContentComponents(); endResetModel(); diff --git a/src/messagecontent/models/eventmessagecontentmodel.h b/src/messagecontent/models/eventmessagecontentmodel.h index 3c677bc5a..666e41a6c 100644 --- a/src/messagecontent/models/eventmessagecontentmodel.h +++ b/src/messagecontent/models/eventmessagecontentmodel.h @@ -52,7 +52,8 @@ Q_SIGNALS: private: void initializeModel(); - NeoChatDateTime dateTime() const override; + QDateTime time() const override; + QString timeString() const override; QString authorId() const override; QString threadRootId() const override; diff --git a/src/messagecontent/models/messagecontentmodel.cpp b/src/messagecontent/models/messagecontentmodel.cpp index 016208307..fa79c5e43 100644 --- a/src/messagecontent/models/messagecontentmodel.cpp +++ b/src/messagecontent/models/messagecontentmodel.cpp @@ -10,7 +10,6 @@ #include "chatbarcache.h" #include "contentprovider.h" #include "neochatconnection.h" -#include "neochatdatetime.h" #include "texthandler.h" using namespace Quotient; @@ -80,11 +79,16 @@ QString MessageContentModel::eventId() const return m_eventId; } -NeoChatDateTime MessageContentModel::dateTime() const +QDateTime MessageContentModel::time() const { return QDateTime::currentDateTime(); } +QString MessageContentModel::timeString() const +{ + return time().toLocalTime().toString(u"hh:mm"_s); +} + QString MessageContentModel::authorId() const { return m_room->localMember().id(); @@ -132,8 +136,11 @@ QVariant MessageContentModel::data(const QModelIndex &index, int role) const if (role == EventIdRole) { return eventId(); } - if (role == DateTimeRole) { - return QVariant::fromValue(dateTime()); + if (role == TimeRole) { + return time(); + } + if (role == TimeStringRole) { + return timeString(); } if (role == AuthorRole) { return QVariant::fromValue(author()); @@ -192,7 +199,8 @@ QHash MessageContentModel::roleNamesStatic() roles[MessageContentModel::ComponentTypeRole] = "componentType"; roles[MessageContentModel::ComponentAttributesRole] = "componentAttributes"; roles[MessageContentModel::EventIdRole] = "eventId"; - roles[MessageContentModel::DateTimeRole] = "dateTime"; + roles[MessageContentModel::TimeRole] = "time"; + roles[MessageContentModel::TimeStringRole] = "timeString"; roles[MessageContentModel::AuthorRole] = "author"; roles[MessageContentModel::FileTransferInfoRole] = "fileTransferInfo"; roles[MessageContentModel::ItineraryModelRole] = "itineraryModel"; diff --git a/src/messagecontent/models/messagecontentmodel.h b/src/messagecontent/models/messagecontentmodel.h index b6e07b3f3..b14dcc166 100644 --- a/src/messagecontent/models/messagecontentmodel.h +++ b/src/messagecontent/models/messagecontentmodel.h @@ -21,8 +21,6 @@ #include "neochatroom.h" #include "neochatroommember.h" -class NeoChatDateTime; - /** * @class MessageContentModel * @@ -49,7 +47,8 @@ public: ComponentTypeRole = Qt::UserRole, /**< The type of component to visualise the message. */ ComponentAttributesRole, /**< The attributes of the component. */ EventIdRole, /**< The matrix event ID of the event. */ - DateTimeRole, /**< The timestamp for when the event was sent (as a NeoChatDateTime). */ + TimeRole, /**< The timestamp for when the event was sent (as a QDateTime). */ + TimeStringRole, /**< The timestamp for when the event was sent as a string (in QLocale::ShortFormat). */ AuthorRole, /**< The author of the event. */ FileTransferInfoRole, /**< FileTransferInfo for any downloading files. */ ItineraryModelRole, /**< The itinerary model for a file. */ @@ -126,11 +125,18 @@ protected: QString m_eventId; /** - * @brief NeoChatDateTime for the message. + * @brief QDateTime for the message. * * The default implementation returns the current time. */ - virtual NeoChatDateTime dateTime() const; + virtual QDateTime time() const; + + /** + * @brief Time for the message as a string in the from "hh:mm". + * + * The default implementation returns the current time. + */ + virtual QString timeString() const; /** * @brief The author of the message. diff --git a/src/timeline/MessageDelegate.qml b/src/timeline/MessageDelegate.qml index 8637730f9..67a34b83d 100644 --- a/src/timeline/MessageDelegate.qml +++ b/src/timeline/MessageDelegate.qml @@ -50,9 +50,9 @@ MessageDelegateBase { required property MessageContentModel contentModel /** - * @brief The timestamp of the event as a NeoChatDateTime. + * @brief The date of the event as a string. */ - required property NeoChatDateTime dateTime + required property string section /** * @brief A model with the first 5 other user read markers for this message. @@ -203,7 +203,7 @@ MessageDelegateBase { sectionComponent: Kirigami.ListSectionHeader { horizontalPadding: 0 - text: root.dateTime.relativeDate + text: root.section } readMarkerComponent: AvatarFlow { diff --git a/src/timeline/StateDelegate.qml b/src/timeline/StateDelegate.qml index 0a33c9f30..873f9c4f9 100644 --- a/src/timeline/StateDelegate.qml +++ b/src/timeline/StateDelegate.qml @@ -49,9 +49,9 @@ TimelineDelegate { required property bool showSection /** - * @brief The timestamp of the event as a NeoChatDateTime. + * @brief The date of the event as a string. */ - required property NeoChatDateTime dateTime + required property string section /** * @brief A model with the first 5 other user read markers for this message. @@ -80,7 +80,7 @@ TimelineDelegate { Layout.fillWidth: true visible: root.showSection horizontalPadding: 0 - text: root.dateTime.relativeDate + text: root.section } RowLayout { Layout.fillWidth: true diff --git a/src/timeline/models/mediamessagefiltermodel.cpp b/src/timeline/models/mediamessagefiltermodel.cpp index 3a254b710..c1652d6d5 100644 --- a/src/timeline/models/mediamessagefiltermodel.cpp +++ b/src/timeline/models/mediamessagefiltermodel.cpp @@ -7,7 +7,6 @@ #include #include "messagefiltermodel.h" -#include "neochatdatetime.h" #include "timelinemessagemodel.h" using namespace Qt::StringLiterals; @@ -35,9 +34,8 @@ QVariant MediaMessageFilterModel::data(const QModelIndex &index, int role) const // We need to catch this one and return true if the next media object was // on a different day. if (role == TimelineMessageModel::ShowSectionRole) { - const auto day = mapToSource(index).data(TimelineMessageModel::DateTimeRole).value().dateTime().toLocalTime().date(); - const auto previousEventDay = - mapToSource(this->index(index.row() + 1, 0)).data(TimelineMessageModel::DateTimeRole).value().dateTime().toLocalTime().date(); + const auto day = mapToSource(index).data(TimelineMessageModel::TimeRole).toDateTime().toLocalTime().date(); + const auto previousEventDay = mapToSource(this->index(index.row() + 1, 0)).data(TimelineMessageModel::TimeRole).toDateTime().toLocalTime().date(); return day != previousEventDay; } diff --git a/src/timeline/models/messagefiltermodel.cpp b/src/timeline/models/messagefiltermodel.cpp index 82427cfe1..6ae5a5b6b 100644 --- a/src/timeline/models/messagefiltermodel.cpp +++ b/src/timeline/models/messagefiltermodel.cpp @@ -9,7 +9,6 @@ #include "enums/delegatetype.h" #include "messagemodel.h" #include "models/timelinemodel.h" -#include "neochatdatetime.h" using namespace Quotient; @@ -180,13 +179,9 @@ bool MessageFilterModel::showAuthor(QModelIndex index) const if (data(i, TimelineMessageModel::SpecialMarksRole) != EventStatus::Hidden && !itemData(i).empty()) { return data(i, TimelineMessageModel::AuthorRole) != data(index, TimelineMessageModel::AuthorRole) || data(i, TimelineMessageModel::DelegateTypeRole) == DelegateType::State - || data(i, TimelineMessageModel::DateTimeRole) - .value() - .dateTime() - .msecsTo(data(index, TimelineMessageModel::DateTimeRole).value().dateTime()) - > 600000 - || data(i, TimelineMessageModel::DateTimeRole).value().dateTime().toLocalTime().date().day() - != data(index, TimelineMessageModel::DateTimeRole).value().dateTime().toLocalTime().date().day(); + || data(i, TimelineMessageModel::TimeRole).toDateTime().msecsTo(data(index, TimelineMessageModel::TimeRole).toDateTime()) > 600000 + || data(i, TimelineMessageModel::TimeRole).toDateTime().toLocalTime().date().day() + != data(index, TimelineMessageModel::TimeRole).toDateTime().toLocalTime().date().day(); } } diff --git a/src/timeline/models/messagemodel.cpp b/src/timeline/models/messagemodel.cpp index 2fddc2575..40f94a1e3 100644 --- a/src/timeline/models/messagemodel.cpp +++ b/src/timeline/models/messagemodel.cpp @@ -17,9 +17,8 @@ #include "enums/messagecomponenttype.h" #include "eventhandler.h" #include "events/pollevent.h" -#include "models/eventmessagecontentmodel.h" #include "models/reactionmodel.h" -#include "neochatdatetime.h" +#include "models/eventmessagecontentmodel.h" #include "neochatroommember.h" using namespace Quotient; @@ -111,8 +110,11 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const switch (role) { case DelegateTypeRole: return DelegateType::ReadMarker; - case DateTimeRole: - return data(index(m_lastReadEventIndex.row() + 1, 0), DateTimeRole); + case TimeRole: { + const QDateTime eventDate = data(index(m_lastReadEventIndex.row() + 1, 0), TimeRole).toDateTime().toLocalTime(); + static const KFormat format; + return format.formatRelativeDateTime(eventDate, QLocale::ShortFormat); + } case SpecialMarksRole: // Check if all the earlier events in the timeline are hidden. If so hide this. for (auto r = row - 1; r >= 0; --r) { @@ -228,8 +230,12 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const return {}; } - if (role == DateTimeRole) { - return QVariant::fromValue(EventHandler::dateTime(eventRoom, &event.value().get(), isPending)); + if (role == TimeRole) { + return EventHandler::time(eventRoom, &event.value().get(), isPending); + } + + if (role == SectionRole) { + return EventHandler::timeString(eventRoom, &event.value().get(), true, QLocale::ShortFormat, isPending); } if (role == IsThreadedRole) { @@ -261,8 +267,8 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const // While the row is removed the subsequent row indexes are not changed so we need to skip over the removed index. // See - https://doc.qt.io/qt-5/qabstractitemmodel.html#beginRemoveRows if (data(i, SpecialMarksRole) != EventStatus::Hidden && !itemData(i).empty()) { - const auto day = data(idx, DateTimeRole).value().dateTime().toLocalTime().date().dayOfYear(); - const auto previousEventDay = data(i, DateTimeRole).value().dateTime().toLocalTime().date().dayOfYear(); + const auto day = data(idx, TimeRole).toDateTime().toLocalTime().date().dayOfYear(); + const auto previousEventDay = data(i, TimeRole).toDateTime().toLocalTime().date().dayOfYear(); return day != previousEventDay; } } @@ -336,7 +342,8 @@ QHash MessageModel::roleNames() const QHash roles = QAbstractItemModel::roleNames(); roles[DelegateTypeRole] = "delegateType"; roles[EventIdRole] = "eventId"; - roles[DateTimeRole] = "dateTime"; + roles[TimeRole] = "time"; + roles[SectionRole] = "section"; roles[AuthorRole] = "author"; roles[HighlightRole] = "isHighlighted"; roles[SpecialMarksRole] = "marks"; diff --git a/src/timeline/models/messagemodel.h b/src/timeline/models/messagemodel.h index 76f49a27c..6fb02c3c4 100644 --- a/src/timeline/models/messagemodel.h +++ b/src/timeline/models/messagemodel.h @@ -60,7 +60,8 @@ public: enum EventRoles { DelegateTypeRole = Qt::UserRole + 1, /**< The delegate type of the message. */ EventIdRole, /**< The matrix event ID of the event. */ - DateTimeRole, /**< The timestamp for when the event was sent (as a NeoChatDateTime). */ + TimeRole, /**< The timestamp for when the event was sent (as a QDateTime). */ + SectionRole, /**< The date of the event as a string. */ AuthorRole, /**< The author of the event. */ HighlightRole, /**< Whether the event should be highlighted. */ SpecialMarksRole, /**< Whether the event is hidden or not. */