Never refresh the author role except when a member updated signal is generated. This should remove a potential source of crashes where a RoomMember object tries to access an already deleted room member state event

This commit is contained in:
James Graham
2024-07-07 14:02:43 +01:00
parent ea1b577ec7
commit 8751f6fea7
2 changed files with 12 additions and 15 deletions

View File

@@ -179,13 +179,13 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
endMoveRows();
movingEvent = false;
}
refreshRow(timelineBaseIndex()); // Refresh the looks
fullEventRefresh(timelineBaseIndex());
refreshLastUserEvents(0);
if (timelineBaseIndex() > 0) { // Refresh below, see #312
refreshEventRoles(timelineBaseIndex() - 1, {ContentModelRole});
}
});
connect(m_currentRoom, &Room::pendingEventChanged, this, &MessageEventModel::refreshRow);
connect(m_currentRoom, &Room::pendingEventChanged, this, &MessageEventModel::fullEventRefresh);
connect(m_currentRoom, &Room::pendingEventAboutToDiscard, this, [this](int i) {
beginRemoveRows({}, i, i);
});
@@ -255,14 +255,15 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
}
}
int MessageEventModel::refreshEvent(const QString &eventId)
void MessageEventModel::fullEventRefresh(int row)
{
return refreshEventRoles(eventId);
}
void MessageEventModel::refreshRow(int row)
{
refreshEventRoles(row);
auto roles = roleNames().keys();
// The author of an event never changes so should only be updated when a member
// changed signal is emitted.
// This also avoids any race conditions where a member is updating and this refresh
// tries to access a member event that has already been deleted.
roles.removeAll(AuthorRole);
refreshEventRoles(row, roles);
}
int MessageEventModel::timelineBaseIndex() const
@@ -378,8 +379,7 @@ void MessageEventModel::refreshLastUserEvents(int baseTimelineRow)
const auto limit = timelineBottom + std::min(baseTimelineRow + 10, m_currentRoom->timelineSize());
for (auto it = timelineBottom + std::max(baseTimelineRow - 10, 0); it != limit; ++it) {
if ((*it)->senderId() == lastSender) {
auto idx = index(it - timelineBottom);
Q_EMIT dataChanged(idx, idx);
fullEventRefresh(it - timelineBottom);
}
}
}

View File

@@ -107,10 +107,6 @@ public:
protected:
bool event(QEvent *event) override;
private Q_SLOTS:
int refreshEvent(const QString &eventId);
void refreshRow(int row);
private:
QPointer<NeoChatRoom> m_currentRoom = nullptr;
QString lastReadEventId;
@@ -128,6 +124,7 @@ private:
bool canFetchMore(const QModelIndex &parent) const override;
void fetchMore(const QModelIndex &parent) override;
void fullEventRefresh(int row);
void refreshLastUserEvents(int baseTimelineRow);
void refreshEventRoles(int row, const QList<int> &roles = {});
int refreshEventRoles(const QString &eventId, const QList<int> &roles = {});