Compare commits

...

1 Commits

Author SHA1 Message Date
Torrie Fischer
4139421e8e roomlist: first pass at some new, different extensible sorting options 2022-10-11 15:48:52 +02:00
4 changed files with 77 additions and 25 deletions

View File

@@ -340,6 +340,12 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == TopicRole) {
return room->topic();
}
if (role == FavoritedRole) {
return room->isFavourite();
}
if (role == AttentionRole) {
return room->notificationCount() + room->unreadCount() + room->highlightCount() > 0;
}
if (role == CategoryRole) {
if (room->joinState() == JoinState::Invite) {
return NeoChatRoomType::Invited;

View File

@@ -56,6 +56,10 @@ public:
AvatarImageRole,
IdRole,
IsSpaceRole,
// Whether or not the room is favorited
FavoritedRole,
// Whether or not the room needs attention, ie, pings, mentions, unread
AttentionRole,
};
Q_ENUM(EventRoles)

View File

@@ -33,34 +33,72 @@ SortFilterRoomListModel::RoomSortOrder SortFilterRoomListModel::roomSortOrder()
return m_sortOrder;
}
static const QVector<RoomListModel::EventRoles> categorySortPriorities{
// Favorites at the top
RoomListModel::FavoritedRole,
// Group by categories
RoomListModel::CategoryRole,
// Within each category, pull relevant ones to the top
RoomListModel::AttentionRole,
RoomListModel::HighlightCountRole,
RoomListModel::NotificationCountRole,
RoomListModel::UnreadCountRole,
// Finally sort by last activity time
RoomListModel::LastActiveTimeRole
};
static const QVector<RoomListModel::EventRoles> alphabeticalSortPriorities {
// Does exactly what it says on the tin.
(RoomListModel::EventRoles)Qt::DisplayRole
};
static const QVector<RoomListModel::EventRoles> activitySortPriorities{
// Anything useful at the top, quiet rooms at the bottom
RoomListModel::AttentionRole,
// Organize by highlights, notifications, unread favorites, all other unread, in that order
RoomListModel::HighlightCountRole,
RoomListModel::NotificationCountRole,
RoomListModel::FavoritedRole,
RoomListModel::UnreadCountRole,
// Finally sort by last activity time
RoomListModel::LastActiveTimeRole
};
bool SortFilterRoomListModel::roleCmp(RoomListModel::EventRoles role, const QVariant &sortLeft, const QVariant &sortRight) const
{
switch(role) {
case RoomListModel::FavoritedRole:
return (sortLeft == sortRight) ? false : sortLeft.toBool();
case RoomListModel::CategoryRole:
return sortLeft < sortRight;
default:
return sortLeft > sortRight;
}
}
bool SortFilterRoomListModel::prioritiesCmp(const QVector<RoomListModel::EventRoles>& priorities, const QModelIndex &source_left, const QModelIndex &source_right) const
{
for(RoomListModel::EventRoles sortRole : priorities) {
const auto sortLeft = sourceModel()->data(source_left, sortRole);
const auto sortRight = sourceModel()->data(source_right, sortRole);
if (sortLeft != sortRight) {
return roleCmp(sortRole, sortLeft, sortRight);
}
}
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (m_sortOrder == SortFilterRoomListModel::LastActivity) {
// display favorite rooms always on top
const auto categoryLeft = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt());
const auto categoryRight = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt());
if (categoryLeft == NeoChatRoomType::Types::Favorite && categoryRight == NeoChatRoomType::Types::Favorite) {
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
> sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
}
if (categoryLeft == NeoChatRoomType::Types::Favorite) {
return true;
} else if (categoryRight == NeoChatRoomType::Types::Favorite) {
return false;
}
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
> sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
switch(m_sortOrder) {
case SortFilterRoomListModel::Alphabetical:
return prioritiesCmp(alphabeticalSortPriorities, source_left, source_right);
case SortFilterRoomListModel::Categories:
return prioritiesCmp(categorySortPriorities, source_left, source_right);
case SortFilterRoomListModel::LastActivity:
return prioritiesCmp(activitySortPriorities, source_left, source_right);
}
if (m_sortOrder != SortFilterRoomListModel::Categories) {
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole)) {
return sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt() < sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt();
}
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
> sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
void SortFilterRoomListModel::setFilterText(const QString &text)

View File

@@ -4,6 +4,7 @@
#pragma once
#include <QSortFilterProxyModel>
#include "roomlistmodel.h"
class SortFilterRoomListModel : public QSortFilterProxyModel
{
@@ -46,4 +47,7 @@ private:
RoomSortOrder m_sortOrder = Categories;
QString m_filterText;
QString m_activeSpaceId;
bool prioritiesCmp(const QVector<RoomListModel::EventRoles>& priorities, const QModelIndex &left, const QModelIndex &right) const;
bool roleCmp(RoomListModel::EventRoles role, const QVariant& left, const QVariant& right) const;
};