roomlist: first pass at some new, different extensible sorting options
This commit is contained in:
@@ -340,6 +340,12 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == TopicRole) {
|
if (role == TopicRole) {
|
||||||
return room->topic();
|
return room->topic();
|
||||||
}
|
}
|
||||||
|
if (role == FavoritedRole) {
|
||||||
|
return room->isFavourite();
|
||||||
|
}
|
||||||
|
if (role == AttentionRole) {
|
||||||
|
return room->notificationCount() + room->unreadCount() + room->highlightCount() > 0;
|
||||||
|
}
|
||||||
if (role == CategoryRole) {
|
if (role == CategoryRole) {
|
||||||
if (room->joinState() == JoinState::Invite) {
|
if (room->joinState() == JoinState::Invite) {
|
||||||
return NeoChatRoomType::Invited;
|
return NeoChatRoomType::Invited;
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ public:
|
|||||||
AvatarImageRole,
|
AvatarImageRole,
|
||||||
IdRole,
|
IdRole,
|
||||||
IsSpaceRole,
|
IsSpaceRole,
|
||||||
|
// Whether or not the room is favorited
|
||||||
|
FavoritedRole,
|
||||||
|
// Whether or not the room needs attention, ie, pings, mentions, unread
|
||||||
|
AttentionRole,
|
||||||
};
|
};
|
||||||
Q_ENUM(EventRoles)
|
Q_ENUM(EventRoles)
|
||||||
|
|
||||||
|
|||||||
@@ -33,34 +33,72 @@ SortFilterRoomListModel::RoomSortOrder SortFilterRoomListModel::roomSortOrder()
|
|||||||
return m_sortOrder;
|
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
|
bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||||
{
|
{
|
||||||
if (m_sortOrder == SortFilterRoomListModel::LastActivity) {
|
switch(m_sortOrder) {
|
||||||
// display favorite rooms always on top
|
case SortFilterRoomListModel::Alphabetical:
|
||||||
const auto categoryLeft = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt());
|
return prioritiesCmp(alphabeticalSortPriorities, source_left, source_right);
|
||||||
const auto categoryRight = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt());
|
case SortFilterRoomListModel::Categories:
|
||||||
|
return prioritiesCmp(categorySortPriorities, source_left, source_right);
|
||||||
if (categoryLeft == NeoChatRoomType::Types::Favorite && categoryRight == NeoChatRoomType::Types::Favorite) {
|
case SortFilterRoomListModel::LastActivity:
|
||||||
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
|
return prioritiesCmp(activitySortPriorities, source_left, source_right);
|
||||||
> 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();
|
|
||||||
}
|
}
|
||||||
if (m_sortOrder != SortFilterRoomListModel::Categories) {
|
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SortFilterRoomListModel::setFilterText(const QString &text)
|
void SortFilterRoomListModel::setFilterText(const QString &text)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
#include "roomlistmodel.h"
|
||||||
|
|
||||||
class SortFilterRoomListModel : public QSortFilterProxyModel
|
class SortFilterRoomListModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
@@ -46,4 +47,7 @@ private:
|
|||||||
RoomSortOrder m_sortOrder = Categories;
|
RoomSortOrder m_sortOrder = Categories;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
QString m_activeSpaceId;
|
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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user