From f9cdd55a4d0dbc14a3b71e01dd73733e2fd72ece Mon Sep 17 00:00:00 2001 From: James Graham Date: Sun, 4 Feb 2024 19:10:37 +0000 Subject: [PATCH] Support the order parameter in m.space.child events Support the order parameter in m.space.child events, with the exception of always putting spaces higher than non-spaces see https://spec.matrix.org/v1.8/client-server-api/#ordering-of-children-within-a-space for the spec algorithm --- src/models/spacechildrenmodel.cpp | 16 ++++++++++++++++ src/models/spacechildrenmodel.h | 2 ++ src/models/spacechildsortfiltermodel.cpp | 21 +++++++++++++++++++-- src/models/spacetreeitem.cpp | 16 ++++++++++++++++ src/models/spacetreeitem.h | 5 +++++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/models/spacechildrenmodel.cpp b/src/models/spacechildrenmodel.cpp index 6364fbcfc..49cdaca59 100644 --- a/src/models/spacechildrenmodel.cpp +++ b/src/models/spacechildrenmodel.cpp @@ -244,6 +244,20 @@ QVariant SpaceChildrenModel::data(const QModelIndex &index, int role) const } return QVariant::fromValue(nullptr); } + if (role == OrderRole) { + if (child->parentItem() == nullptr) { + return QString(); + } + const auto childState = child->parentItem()->childStateContent(child); + return childState[QLatin1String("order")].toString(); + } + if (role == ChildTimestampRole) { + if (child->parentItem() == nullptr) { + return QString(); + } + const auto childState = child->parentItem()->childState(child); + return childState[QLatin1String("origin_server_ts")].toString(); + } return {}; } @@ -325,6 +339,8 @@ QHash SpaceChildrenModel::roleNames() const roles[IsDeclaredParentRole] = "isDeclaredParent"; roles[CanRemove] = "canRemove"; roles[ParentRoomRole] = "parentRoom"; + roles[OrderRole] = "order"; + roles[ChildTimestampRole] = "childTimestamp"; return roles; } diff --git a/src/models/spacechildrenmodel.h b/src/models/spacechildrenmodel.h index bbea62fc8..7b7f2b858 100644 --- a/src/models/spacechildrenmodel.h +++ b/src/models/spacechildrenmodel.h @@ -51,6 +51,8 @@ public: IsDeclaredParentRole, CanRemove, ParentRoomRole, + OrderRole, + ChildTimestampRole, }; explicit SpaceChildrenModel(QObject *parent = nullptr); diff --git a/src/models/spacechildsortfiltermodel.cpp b/src/models/spacechildsortfiltermodel.cpp index d5a5e445e..8866264f3 100644 --- a/src/models/spacechildsortfiltermodel.cpp +++ b/src/models/spacechildsortfiltermodel.cpp @@ -26,10 +26,27 @@ QString SpaceChildSortFilterModel::filterText() const bool SpaceChildSortFilterModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { - if (!source_left.data(SpaceChildrenModel::IsSpaceRole).toBool() && source_right.data(SpaceChildrenModel::IsSpaceRole).toBool()) { + if (source_left.data(SpaceChildrenModel::IsSpaceRole).toBool() && source_right.data(SpaceChildrenModel::IsSpaceRole).toBool()) { + if (!source_left.data(SpaceChildrenModel::OrderRole).toString().isEmpty() && !source_right.data(SpaceChildrenModel::OrderRole).toString().isEmpty()) { + return QString::compare(source_left.data(SpaceChildrenModel::OrderRole).toString(), source_right.data(SpaceChildrenModel::OrderRole).toString()) + < 0; + } + return source_left.data(SpaceChildrenModel::ChildTimestampRole).toDateTime() > source_right.data(SpaceChildrenModel::ChildTimestampRole).toDateTime(); + } + if (source_left.data(SpaceChildrenModel::IsSpaceRole).toBool()) { + return true; + } else if (source_right.data(SpaceChildrenModel::IsSpaceRole).toBool()) { return false; } - return true; + if (!source_left.data(SpaceChildrenModel::OrderRole).toString().isEmpty() && !source_right.data(SpaceChildrenModel::OrderRole).toString().isEmpty()) { + return QString::compare(source_left.data(SpaceChildrenModel::OrderRole).toString(), source_right.data(SpaceChildrenModel::OrderRole).toString()) < 0; + } + if (!source_left.data(SpaceChildrenModel::OrderRole).toString().isEmpty()) { + return true; + } else if (!source_right.data(SpaceChildrenModel::OrderRole).toString().isEmpty()) { + return false; + } + return source_left.data(SpaceChildrenModel::ChildTimestampRole).toDateTime() > source_right.data(SpaceChildrenModel::ChildTimestampRole).toDateTime(); } bool SpaceChildSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const diff --git a/src/models/spacetreeitem.cpp b/src/models/spacetreeitem.cpp index 21820304f..ebe5c818e 100644 --- a/src/models/spacetreeitem.cpp +++ b/src/models/spacetreeitem.cpp @@ -141,6 +141,22 @@ bool SpaceTreeItem::isSpace() const return m_isSpace; } +QJsonObject SpaceTreeItem::childState(const SpaceTreeItem *child) const +{ + if (child == nullptr) { + return {}; + } + if (child->parentItem() != this) { + return {}; + } + for (const auto &childState : m_childStates) { + if (childState->stateKey() == child->id()) { + return childState->fullJson(); + } + } + return {}; +} + QJsonObject SpaceTreeItem::childStateContent(const SpaceTreeItem *child) const { if (child == nullptr) { diff --git a/src/models/spacetreeitem.h b/src/models/spacetreeitem.h index d49d74fe3..f339f3770 100644 --- a/src/models/spacetreeitem.h +++ b/src/models/spacetreeitem.h @@ -125,6 +125,11 @@ public: */ bool isSpace() const; + /** + * @brief Return the m.space.child stripped state Json for the given child. + */ + QJsonObject childState(const SpaceTreeItem *child) const; + /** * @brief Return the m.space.child state event content for the given child. */