Sort the room list
This commit is contained in:
parent
cd67046f60
commit
beeb60e4a1
@ -131,7 +131,7 @@ Page {
|
|||||||
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
|
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
|
||||||
font.pixelSize: fontMetrics.font.pixelSize * 0.9
|
font.pixelSize: fontMetrics.font.pixelSize * 0.9
|
||||||
color: roomItem.unimportantText
|
color: roomItem.unimportantText
|
||||||
text: model.timestamp
|
text: model.time
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,13 @@ RoomlistModel::roleNames() const
|
|||||||
{RoomName, "roomName"},
|
{RoomName, "roomName"},
|
||||||
{RoomId, "roomId"},
|
{RoomId, "roomId"},
|
||||||
{LastMessage, "lastMessage"},
|
{LastMessage, "lastMessage"},
|
||||||
|
{Time, "time"},
|
||||||
{Timestamp, "timestamp"},
|
{Timestamp, "timestamp"},
|
||||||
{HasUnreadMessages, "hasUnreadMessages"},
|
{HasUnreadMessages, "hasUnreadMessages"},
|
||||||
{HasLoudNotification, "hasLoudNotification"},
|
{HasLoudNotification, "hasLoudNotification"},
|
||||||
{NotificationCount, "notificationCount"},
|
{NotificationCount, "notificationCount"},
|
||||||
|
{IsInvite, "isInvite"},
|
||||||
|
{IsSpace, "isSpace"},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,8 +67,10 @@ RoomlistModel::data(const QModelIndex &index, int role) const
|
|||||||
return room->roomId();
|
return room->roomId();
|
||||||
case Roles::LastMessage:
|
case Roles::LastMessage:
|
||||||
return room->lastMessage().body;
|
return room->lastMessage().body;
|
||||||
case Roles::Timestamp:
|
case Roles::Time:
|
||||||
return room->lastMessage().descriptiveTime;
|
return room->lastMessage().descriptiveTime;
|
||||||
|
case Roles::Timestamp:
|
||||||
|
return QVariant(static_cast<quint64>(room->lastMessage().timestamp));
|
||||||
case Roles::HasUnreadMessages:
|
case Roles::HasUnreadMessages:
|
||||||
return this->roomReadStatus.count(roomid) &&
|
return this->roomReadStatus.count(roomid) &&
|
||||||
this->roomReadStatus.at(roomid);
|
this->roomReadStatus.at(roomid);
|
||||||
@ -73,6 +78,9 @@ RoomlistModel::data(const QModelIndex &index, int role) const
|
|||||||
return room->hasMentions();
|
return room->hasMentions();
|
||||||
case Roles::NotificationCount:
|
case Roles::NotificationCount:
|
||||||
return room->notificationCount();
|
return room->notificationCount();
|
||||||
|
case Roles::IsInvite:
|
||||||
|
case Roles::IsSpace:
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -90,9 +98,9 @@ RoomlistModel::updateReadStatus(const std::map<QString, bool> roomReadStatus_)
|
|||||||
if (roomUnread != roomReadStatus[roomid]) {
|
if (roomUnread != roomReadStatus[roomid]) {
|
||||||
roomsToUpdate.push_back(this->roomidToIndex(roomid));
|
roomsToUpdate.push_back(this->roomidToIndex(roomid));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this->roomReadStatus = roomReadStatus_;
|
this->roomReadStatus[roomid] = roomUnread;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto idx : roomsToUpdate) {
|
for (auto idx : roomsToUpdate) {
|
||||||
emit dataChanged(index(idx),
|
emit dataChanged(index(idx),
|
||||||
@ -135,6 +143,7 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification)
|
|||||||
Roles::LastMessage,
|
Roles::LastMessage,
|
||||||
Roles::Timestamp,
|
Roles::Timestamp,
|
||||||
Roles::NotificationCount,
|
Roles::NotificationCount,
|
||||||
|
Qt::DisplayRole,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
@ -162,6 +171,7 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification)
|
|||||||
{
|
{
|
||||||
Roles::HasLoudNotification,
|
Roles::HasLoudNotification,
|
||||||
Roles::NotificationCount,
|
Roles::NotificationCount,
|
||||||
|
Qt::DisplayRole,
|
||||||
});
|
});
|
||||||
|
|
||||||
int total_unread_msgs = 0;
|
int total_unread_msgs = 0;
|
||||||
@ -225,7 +235,6 @@ RoomlistModel::initializeRooms(const std::vector<QString> &roomIds_)
|
|||||||
beginResetModel();
|
beginResetModel();
|
||||||
models.clear();
|
models.clear();
|
||||||
roomids.clear();
|
roomids.clear();
|
||||||
roomids = roomIds_;
|
|
||||||
for (const auto &id : roomIds_)
|
for (const auto &id : roomIds_)
|
||||||
addRoom(id, true);
|
addRoom(id, true);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@ -239,3 +248,79 @@ RoomlistModel::clear()
|
|||||||
roomids.clear();
|
roomids.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
enum NotificationImportance : short
|
||||||
|
{
|
||||||
|
ImportanceDisabled = -1,
|
||||||
|
AllEventsRead = 0,
|
||||||
|
NewMessage = 1,
|
||||||
|
NewMentions = 2,
|
||||||
|
Invite = 3
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
short int
|
||||||
|
FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const
|
||||||
|
{
|
||||||
|
// Returns the degree of importance of the unread messages in the room.
|
||||||
|
// If sorting by importance is disabled in settings, this only ever
|
||||||
|
// returns ImportanceDisabled or Invite
|
||||||
|
if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) {
|
||||||
|
return Invite;
|
||||||
|
} else if (!this->sortByImportance) {
|
||||||
|
return ImportanceDisabled;
|
||||||
|
} else if (sourceModel()->data(idx, RoomlistModel::HasLoudNotification).toBool()) {
|
||||||
|
return NewMentions;
|
||||||
|
} else if (sourceModel()->data(idx, RoomlistModel::NotificationCount).toInt() > 0) {
|
||||||
|
return NewMessage;
|
||||||
|
} else {
|
||||||
|
return AllEventsRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
FilteredRoomlistModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
|
{
|
||||||
|
QModelIndex const left_idx = sourceModel()->index(left.row(), 0, QModelIndex());
|
||||||
|
QModelIndex const right_idx = sourceModel()->index(right.row(), 0, QModelIndex());
|
||||||
|
|
||||||
|
// Sort by "importance" (i.e. invites before mentions before
|
||||||
|
// notifs before new events before old events), then secondly
|
||||||
|
// by recency.
|
||||||
|
|
||||||
|
// Checking importance first
|
||||||
|
const auto a_importance = calculateImportance(left_idx);
|
||||||
|
const auto b_importance = calculateImportance(right_idx);
|
||||||
|
if (a_importance != b_importance) {
|
||||||
|
return a_importance > b_importance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now sort by recency
|
||||||
|
// Zero if empty, otherwise the time that the event occured
|
||||||
|
uint64_t a_recency = sourceModel()->data(left_idx, RoomlistModel::Timestamp).toULongLong();
|
||||||
|
uint64_t b_recency = sourceModel()->data(right_idx, RoomlistModel::Timestamp).toULongLong();
|
||||||
|
|
||||||
|
if (a_recency != b_recency)
|
||||||
|
return a_recency > b_recency;
|
||||||
|
else
|
||||||
|
return left.row() < right.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
, roomlistmodel(model)
|
||||||
|
{
|
||||||
|
this->sortByImportance = UserSettings::instance()->sortByImportance();
|
||||||
|
setSourceModel(model);
|
||||||
|
setDynamicSortFilter(true);
|
||||||
|
|
||||||
|
QObject::connect(UserSettings::instance().get(),
|
||||||
|
&UserSettings::roomSortingChanged,
|
||||||
|
this,
|
||||||
|
[this](bool sortByImportance_) {
|
||||||
|
this->sortByImportance = sortByImportance_;
|
||||||
|
invalidate();
|
||||||
|
});
|
||||||
|
|
||||||
|
sort(0);
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <mtx/responses/sync.hpp>
|
#include <mtx/responses/sync.hpp>
|
||||||
@ -24,10 +25,13 @@ public:
|
|||||||
RoomName,
|
RoomName,
|
||||||
RoomId,
|
RoomId,
|
||||||
LastMessage,
|
LastMessage,
|
||||||
|
Time,
|
||||||
Timestamp,
|
Timestamp,
|
||||||
HasUnreadMessages,
|
HasUnreadMessages,
|
||||||
HasLoudNotification,
|
HasLoudNotification,
|
||||||
NotificationCount,
|
NotificationCount,
|
||||||
|
IsInvite,
|
||||||
|
IsSpace,
|
||||||
};
|
};
|
||||||
|
|
||||||
RoomlistModel(TimelineViewManager *parent = nullptr);
|
RoomlistModel(TimelineViewManager *parent = nullptr);
|
||||||
@ -73,4 +77,26 @@ private:
|
|||||||
std::vector<QString> roomids;
|
std::vector<QString> roomids;
|
||||||
QHash<QString, QSharedPointer<TimelineModel>> models;
|
QHash<QString, QSharedPointer<TimelineModel>> models;
|
||||||
std::map<QString, bool> roomReadStatus;
|
std::map<QString, bool> roomReadStatus;
|
||||||
|
|
||||||
|
friend class FilteredRoomlistModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FilteredRoomlistModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FilteredRoomlistModel(RoomlistModel *model, QObject *parent = nullptr);
|
||||||
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
int roomidToIndex(QString roomid)
|
||||||
|
{
|
||||||
|
return mapFromSource(roomlistmodel->index(roomlistmodel->roomidToIndex(roomid)))
|
||||||
|
.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
short int calculateImportance(const QModelIndex &idx) const;
|
||||||
|
RoomlistModel *roomlistmodel;
|
||||||
|
bool sortByImportance = true;
|
||||||
};
|
};
|
||||||
|
@ -318,6 +318,8 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
|
|||||||
, room_id_(room_id)
|
, room_id_(room_id)
|
||||||
, manager_(manager)
|
, manager_(manager)
|
||||||
{
|
{
|
||||||
|
lastMessage_.timestamp = 0;
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
this,
|
this,
|
||||||
&TimelineModel::redactionFailed,
|
&TimelineModel::redactionFailed,
|
||||||
|
@ -382,7 +382,7 @@ private:
|
|||||||
QString eventIdToShow;
|
QString eventIdToShow;
|
||||||
int showEventTimerCounter = 0;
|
int showEventTimerCounter = 0;
|
||||||
|
|
||||||
DescInfo lastMessage_;
|
DescInfo lastMessage_{};
|
||||||
|
|
||||||
friend struct SendMessageVisitor;
|
friend struct SendMessageVisitor;
|
||||||
|
|
||||||
|
@ -193,9 +193,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
|
|||||||
});
|
});
|
||||||
qmlRegisterSingletonType<RoomlistModel>(
|
qmlRegisterSingletonType<RoomlistModel>(
|
||||||
"im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
"im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||||
auto ptr = self->rooms;
|
return new FilteredRoomlistModel(self->rooms);
|
||||||
QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
|
|
||||||
return ptr;
|
|
||||||
});
|
});
|
||||||
qmlRegisterSingletonType<UserSettings>(
|
qmlRegisterSingletonType<UserSettings>(
|
||||||
"im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
"im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||||
|
Loading…
Reference in New Issue
Block a user