Improve UserListModel performance and other preparations
In a future patch I want to add support for viewing banned/invited users, and it's also been mentioned that UserListModel is quite slow too. The biggest cost is sorting the member list (power level and alphabetically) and this happened in a few different ways: * When the member list updated * The user switches rooms * Misc events such as the palette changing But this was pretty inefficient, because internally Quotient::Room keeps a list of members, and we kept re-sorting that same list. Our connections were also too broad and despite having signals for members joining and leaving we just reloaded the entire list anyway. So my new solution is to keep the list persistently sorted in NeoChatRoom, and reload that in UserListModel. This model also keeps track of *all* members - including ones that left - which will be used for the aforementioned feature. So UserFilterModel now filters out only the joined members, and that will be configurable in the future. I also added two new roles to UserListModel for membership and color respectively (which makes some dead code useful again) and fixed us overwriting the built-in Qt roles accidentally.
This commit is contained in:
@@ -172,6 +172,10 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
|
||||
Q_ASSERT(neochatconnection);
|
||||
connect(neochatconnection, &NeoChatConnection::globalUrlPreviewEnabledChanged, this, &NeoChatRoom::urlPreviewEnabledChanged);
|
||||
connect(this, &Room::fullyReadMarkerMoved, this, &NeoChatRoom::invalidateLastUnreadHighlightId);
|
||||
|
||||
// Wait until the initial member list is available before sorting
|
||||
connect(this, &Room::memberListChanged, this, &NeoChatRoom::refreshAllMembers, Qt::SingleShotConnection);
|
||||
connect(this, &Room::memberJoined, this, &NeoChatRoom::insertMemberSorted);
|
||||
}
|
||||
|
||||
bool NeoChatRoom::visible() const
|
||||
@@ -1910,6 +1914,34 @@ void NeoChatRoom::invalidateLastUnreadHighlightId(const QString &fromEventId, co
|
||||
}
|
||||
}
|
||||
|
||||
void NeoChatRoom::refreshAllMembers()
|
||||
{
|
||||
m_sortedMemberIds = memberIds();
|
||||
|
||||
MemberSorter sorter;
|
||||
std::ranges::sort(m_sortedMemberIds, [this, &sorter](const auto &left, const auto &right) {
|
||||
const auto leftPl = memberEffectivePowerLevel(left);
|
||||
const auto rightPl = memberEffectivePowerLevel(right);
|
||||
if (leftPl > rightPl) {
|
||||
return true;
|
||||
}
|
||||
if (rightPl > leftPl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sorter(left, right);
|
||||
});
|
||||
}
|
||||
|
||||
void NeoChatRoom::insertMemberSorted(const Quotient::RoomMember member)
|
||||
{
|
||||
if (m_sortedMemberIds.contains(member.id())) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_sortedMemberIds.append(member.id());
|
||||
}
|
||||
|
||||
bool NeoChatRoom::spaceHasUnreadMessages() const
|
||||
{
|
||||
if (!isSpace()) {
|
||||
@@ -1924,6 +1956,11 @@ void NeoChatRoom::markAllChildrenMessagesAsRead()
|
||||
if (isSpace()) {
|
||||
SpaceHierarchyCache::instance().markAllChildrenMessagesAsRead(id());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
QList<QString> NeoChatRoom::sortedMemberIds() const
|
||||
{
|
||||
return m_sortedMemberIds;
|
||||
}
|
||||
|
||||
#include "moc_neochatroom.cpp"
|
||||
|
||||
Reference in New Issue
Block a user