Room Custom Filter Prep

This is basically prep work for customisable sort orders. The room sort parameters are detached from the room sort model as multiple components will need to access the values. The sorting is then generified.

Some defunct sorting parameters are also removed.
This commit is contained in:
James Graham
2024-12-08 13:10:00 +00:00
parent d490e65315
commit d07a8258e9
9 changed files with 242 additions and 70 deletions

View File

@@ -129,7 +129,7 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
refresh(room);
});
connect(room, &Room::addedMessages, this, [this, room] {
refresh(room, {SubtitleTextRole, LastActiveTimeRole});
refresh(room, {SubtitleTextRole});
});
connect(room, &Room::pendingEventMerged, this, [this, room] {
refresh(room, {SubtitleTextRole});
@@ -229,9 +229,6 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == HasHighlightNotificationsRole) {
return room->highlightCount() > 0 && room->contextAwareNotificationCount() > 0;
}
if (role == LastActiveTimeRole) {
return room->lastActiveTime();
}
if (role == JoinStateRole) {
if (!room->successorId().isEmpty()) {
return QStringLiteral("upgraded");
@@ -291,7 +288,6 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
roles[CategoryRole] = "category";
roles[ContextNotificationCountRole] = "contextNotificationCount";
roles[HasHighlightNotificationsRole] = "hasHighlightNotifications";
roles[LastActiveTimeRole] = "lastActiveTime";
roles[JoinStateRole] = "joinState";
roles[CurrentRoomRole] = "currentRoom";
roles[SubtitleTextRole] = "subtitleText";

View File

@@ -43,7 +43,6 @@ public:
CategoryRole, /**< The room category, e.g favourite. */
ContextNotificationCountRole, /**< The context aware notification count for the room. */
HasHighlightNotificationsRole, /**< Whether there are any highlight notifications. */
LastActiveTimeRole, /**< The timestamp of the last event sent in the room. */
JoinStateRole, /**< The local user's join state in the room. */
CurrentRoomRole, /**< The room object for the room. */
SubtitleTextRole, /**< The text to show as the room subtitle. */

View File

@@ -176,7 +176,7 @@ void RoomTreeModel::connectRoomSignals(NeoChatRoom *room)
refreshRoomRoles(room);
});
connect(room, &Room::addedMessages, this, [this, room] {
refreshRoomRoles(room, {SubtitleTextRole, LastActiveTimeRole});
refreshRoomRoles(room, {SubtitleTextRole});
});
connect(room, &Room::pendingEventMerged, this, [this, room] {
refreshRoomRoles(room, {SubtitleTextRole});
@@ -274,7 +274,6 @@ QHash<int, QByteArray> RoomTreeModel::roleNames() const
roles[CategoryRole] = "category";
roles[ContextNotificationCountRole] = "contextNotificationCount";
roles[HasHighlightNotificationsRole] = "hasHighlightNotifications";
roles[LastActiveTimeRole] = "lastActiveTime";
roles[JoinStateRole] = "joinState";
roles[CurrentRoomRole] = "currentRoom";
roles[SubtitleTextRole] = "subtitleText";
@@ -284,8 +283,6 @@ QHash<int, QByteArray> RoomTreeModel::roleNames() const
roles[IsDirectChat] = "isDirectChat";
roles[DelegateTypeRole] = "delegateType";
roles[IconRole] = "icon";
roles[AttentionRole] = "attention";
roles[FavouriteRole] = "favourite";
roles[RoomTypeRole] = "roomType";
return roles;
}
@@ -341,9 +338,6 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
if (role == HasHighlightNotificationsRole) {
return room->highlightCount() > 0 && room->contextAwareNotificationCount() > 0;
}
if (role == LastActiveTimeRole) {
return room->lastActiveTime();
}
if (role == JoinStateRole) {
if (!room->successorId().isEmpty()) {
return QStringLiteral("upgraded");
@@ -380,12 +374,6 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
if (role == DelegateTypeRole) {
return QStringLiteral("normal");
}
if (role == AttentionRole) {
return room->notificationCount() + room->highlightCount() > 0;
}
if (role == FavouriteRole) {
return room->isFavourite();
}
if (role == RoomTypeRole) {
if (room->creation()) {
return room->creation()->contentPart<QString>("type"_L1);

View File

@@ -36,7 +36,6 @@ public:
CategoryRole, /**< The room category, e.g favourite. */
ContextNotificationCountRole, /**< The context aware notification count for the room. */
HasHighlightNotificationsRole, /**< Whether there are any highlight notifications. */
LastActiveTimeRole, /**< The timestamp of the last event sent in the room. */
JoinStateRole, /**< The local user's join state in the room. */
CurrentRoomRole, /**< The room object for the room. */
SubtitleTextRole, /**< The text to show as the room subtitle. */
@@ -48,8 +47,6 @@ public:
IsDirectChat, /**< Whether this room is a direct chat. */
DelegateTypeRole,
IconRole,
AttentionRole, /**< Whether there are any notifications. */
FavouriteRole, /**< Whether the room is favourited. */
RoomTypeRole, /**< The room's type. */
};
Q_ENUM(EventRoles)

View File

@@ -6,6 +6,7 @@
#include "neochatconfig.h"
#include "neochatconnection.h"
#include "neochatroom.h"
#include "neochatroomtype.h"
#include "roommanager.h"
#include "roomtreemodel.h"
@@ -44,67 +45,49 @@ SortFilterRoomTreeModel::SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QOb
void SortFilterRoomTreeModel::setRoomSortOrder(SortFilterRoomTreeModel::RoomSortOrder sortOrder)
{
m_sortOrder = sortOrder;
if (sortOrder == SortFilterRoomTreeModel::Alphabetical) {
setSortRole(RoomTreeModel::DisplayNameRole);
} else if (sortOrder == SortFilterRoomTreeModel::Activity) {
setSortRole(RoomTreeModel::LastActiveTimeRole);
}
invalidate();
}
static const QVector<RoomTreeModel::EventRoles> alphabeticalSortPriorities{
static const QVector<RoomSortParameter::Parameter> alphabeticalSortPriorities{
// Does exactly what it says on the tin.
RoomTreeModel::DisplayNameRole,
RoomSortParameter::AlphabeticalAscending,
};
static const QVector<RoomTreeModel::EventRoles> activitySortPriorities{
// Anything useful at the top, quiet rooms at the bottom
RoomTreeModel::AttentionRole,
// Organize by highlights, notifications, unread favorites, all other unread, in that order
RoomTreeModel::HasHighlightNotificationsRole,
RoomTreeModel::ContextNotificationCountRole,
RoomTreeModel::FavouriteRole,
static const QVector<RoomSortParameter::Parameter> activitySortPriorities{
RoomSortParameter::HasHighlight,
RoomSortParameter::MostHighlights,
RoomSortParameter::HasUnread,
RoomSortParameter::MostUnread,
RoomSortParameter::LastActive,
};
static const QVector<RoomTreeModel::EventRoles> lastMessageSortPriorities{
// Sort by last activity time
RoomTreeModel::LastActiveTimeRole,
// Anything useful at the top, quiet rooms at the bottom
RoomTreeModel::AttentionRole,
// Organize by highlights, notifications, unread favorites, all other unread, in that order
RoomTreeModel::HasHighlightNotificationsRole,
RoomTreeModel::ContextNotificationCountRole,
RoomTreeModel::FavouriteRole,
static const QVector<RoomSortParameter::Parameter> lastMessageSortPriorities{
RoomSortParameter::LastActive,
};
bool SortFilterRoomTreeModel::roleCmp(const QVariant &sortLeft, const QVariant &sortRight) const
{
switch (sortLeft.typeId()) {
case QMetaType::Bool:
return (sortLeft == sortRight) ? false : sortLeft.toBool();
case QMetaType::QString:
return sortLeft.toString() < sortRight.toString();
case QMetaType::Int:
return sortLeft.toInt() > sortRight.toInt();
case QMetaType::QDateTime:
return sortLeft.toDateTime() > sortRight.toDateTime();
default:
return false;
}
}
bool SortFilterRoomTreeModel::prioritiesCmp(const QVector<RoomTreeModel::EventRoles> &priorities,
bool SortFilterRoomTreeModel::prioritiesCmp(const QVector<RoomSortParameter::Parameter> &priorities,
const QModelIndex &source_left,
const QModelIndex &source_right) const
{
for (RoomTreeModel::EventRoles sortRole : priorities) {
const auto sortLeft = sourceModel()->data(source_left, sortRole);
const auto sortRight = sourceModel()->data(source_right, sortRole);
if (sortLeft != sortRight) {
return roleCmp(sortLeft, sortRight);
const auto treeModel = dynamic_cast<RoomTreeModel *>(sourceModel());
if (treeModel == nullptr) {
return false;
}
const auto leftRoom = dynamic_cast<NeoChatRoom *>(treeModel->connection()->room(source_left.data(RoomTreeModel::RoomIdRole).toString()));
const auto rightRoom = dynamic_cast<NeoChatRoom *>(treeModel->connection()->room(source_right.data(RoomTreeModel::RoomIdRole).toString()));
if (leftRoom == nullptr || rightRoom == nullptr) {
return false;
}
for (auto sortRole : priorities) {
auto result = RoomSortParameter::compareParameter(sortRole, leftRoom, rightRoom);
if (result != 0) {
return result > 0;
}
}
return QSortFilterProxyModel::lessThan(source_left, source_right);
return false;
}
bool SortFilterRoomTreeModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const

View File

@@ -7,6 +7,7 @@
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include "enums/roomsortparameter.h"
#include "models/roomtreemodel.h"
/**
@@ -105,6 +106,5 @@ private:
QString m_filterText;
QString m_activeSpaceId;
bool roleCmp(const QVariant &left, const QVariant &right) const;
bool prioritiesCmp(const QVector<RoomTreeModel::EventRoles> &priorities, const QModelIndex &left, const QModelIndex &right) const;
bool prioritiesCmp(const QVector<RoomSortParameter::Parameter> &priorities, const QModelIndex &left, const QModelIndex &right) const;
};