I don't have any hard numbers on what difference this makes, but it's
definitely a positive improvement. I noticed and fixed a few issues that
were made more glaring by recent changes in libQuotient:
1. Room::memberJoined is called during the historical loading or
whatever, when we only need that *after* stuff is settled.
2. We really don't need to sort the room's members immediately - it's
only relevant when UserListModel is used (and I think this was previous
behavior?) So now its done lazily.
3. We do not want to call Room::effectivePowerLevel willy-nilly. It may
become a more expensive lookup, and it's also varying levels of wasteful
depending on which sorting algorithm the STL uses. It doesn't cost much
for us to keep a temporary cache for the lambda function to use.
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.
If an item is added, the corresponding code should be wrapped with
beginInsertRows() and endInsertRows(), otherwise proxy or filter models
can end up with corrupted internal state.
m_members.insert() in refreshMember() should be unnecessary because
if pos is not the same as m_members.size(), then it means there's already
a member.id() item in the member list.
This used to be a feature but kinda broke/changed when we switched to
focusing on context-aware or notable events. Basically instead of only
notable events making a room bold in the room list, it's any unread
messages now.
Use the forget function to leave a room everywhere this is both for consistency and to reduce dependencies. This way no dependency on RoomManager is required to leave a room and since in all cases they have an object they can just call the function.
Create a new module for the room info drawer QML. This also requires moving some QML to LibNeoChat common with other modules. Finally all QML in roominfo is modifed to not depend on app.
This is only called after we already get an event with lastEvent() so
doing it again is useless. Instead, we should refactor it to behave like
similar functions (e.g. isEventHighlighted.)
I'm 99% sure of the recent crashes we've been seeing are double-frees,
the QCache one me and Duha encountered must be one. The QCache is in
charge of the one in ContentProvider, so it will sometimes try to delete
or access something already destroyed by the QML engine.
While I'm at it, I also made sure to check every other Q_INVOKABLE to
ensure we don't hit this elsewhere.
CCBUG: 502747