Cherrypick Fix state event visiblity in timeline 23.04
Rework the filtering of state events in the timeline and for lastevent. This is now consistent everywhere and includes the following:
- The timeline settings are obeyed everywhere
- A new setting is added to filter all state events
- Last event obeys the timeline setting in all cases
- The roomlist will show a state event as the latest event if it's visible in the timeline
- Names are no longer hyperlinked in eventToString if plaintext is selected.
BUG: 455048\
Closes network/neochat#148
(cherry picked from commit 741cb57105)
This commit is contained in:
committed by
Tobias Fella
parent
8b26a9f45f
commit
76b5463dac
@@ -66,8 +66,6 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
|
||||
roles[VerifiedRole] = "verified";
|
||||
roles[DisplayNameForInitialsRole] = "displayNameForInitials";
|
||||
roles[AuthorDisplayNameRole] = "authorDisplayName";
|
||||
roles[IsNameChangeRole] = "isNameChange";
|
||||
roles[IsAvatarChangeRole] = "isAvatarChange";
|
||||
roles[IsRedactedRole] = "isRedacted";
|
||||
roles[GenericDisplayRole] = "genericDisplay";
|
||||
roles[IsPendingRole] = "isPending";
|
||||
@@ -610,9 +608,17 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
return pendingIt->deliveryStatus();
|
||||
}
|
||||
|
||||
auto *memberEvent = timelineIt->viewAs<RoomMemberEvent>();
|
||||
if (memberEvent) {
|
||||
if ((memberEvent->isJoin() || memberEvent->isLeave()) && !NeoChatConfig::self()->showLeaveJoinEvent()) {
|
||||
if (evt.isStateEvent() && !NeoChatConfig::self()->showStateEvent()) {
|
||||
return EventStatus::Hidden;
|
||||
}
|
||||
|
||||
if (auto roomMemberEvent = eventCast<const RoomMemberEvent>(&evt)) {
|
||||
if ((roomMemberEvent->isJoin() || roomMemberEvent->isLeave()) && !NeoChatConfig::self()->showLeaveJoinEvent()) {
|
||||
return EventStatus::Hidden;
|
||||
} else if (roomMemberEvent->isRename() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave() && !NeoChatConfig::self()->showRename()) {
|
||||
return EventStatus::Hidden;
|
||||
} else if (roomMemberEvent->isAvatarUpdate() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave()
|
||||
&& !NeoChatConfig::self()->showAvatarUpdate()) {
|
||||
return EventStatus::Hidden;
|
||||
}
|
||||
}
|
||||
@@ -958,21 +964,6 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
}
|
||||
|
||||
if (role == IsNameChangeRole) {
|
||||
auto roomMemberEvent = eventCast<const RoomMemberEvent>(&evt);
|
||||
if (roomMemberEvent) {
|
||||
return roomMemberEvent->isRename();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (role == IsAvatarChangeRole) {
|
||||
auto roomMemberEvent = eventCast<const RoomMemberEvent>(&evt);
|
||||
if (roomMemberEvent) {
|
||||
return roomMemberEvent->isAvatarUpdate();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (role == IsRedactedRole) {
|
||||
return evt.isRedacted();
|
||||
}
|
||||
|
||||
@@ -73,8 +73,6 @@ public:
|
||||
DisplayNameForInitialsRole,
|
||||
// The displayname for the event's sender; for name change events, the old displayname
|
||||
AuthorDisplayNameRole,
|
||||
IsNameChangeRole,
|
||||
IsAvatarChangeRole,
|
||||
IsRedactedRole,
|
||||
IsPendingRole,
|
||||
LastRole, // Keep this last
|
||||
|
||||
@@ -11,23 +11,20 @@ using namespace Quotient;
|
||||
MessageFilterModel::MessageFilterModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowStateEventChanged, this, [this] {
|
||||
invalidateFilter();
|
||||
});
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowLeaveJoinEventChanged, this, [this] {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
invalidateFilter();
|
||||
});
|
||||
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowRenameChanged, this, [this] {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
invalidateFilter();
|
||||
});
|
||||
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowAvatarUpdateChanged, this, [this] {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
invalidateFilter();
|
||||
});
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowDeletedMessagesChanged, this, [this] {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
invalidateFilter();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,18 +32,11 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
||||
{
|
||||
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
|
||||
const int specialMarks = index.data(MessageEventModel::SpecialMarksRole).toInt();
|
||||
if (index.data(MessageEventModel::IsNameChangeRole).toBool() && !NeoChatConfig::self()->showRename()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index.data(MessageEventModel::IsAvatarChangeRole).toBool() && !NeoChatConfig::self()->showAvatarUpdate()) {
|
||||
return false;
|
||||
}
|
||||
if (index.data(MessageEventModel::IsRedactedRole).toBool() && !NeoChatConfig::self()->showDeletedMessages()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int specialMarks = index.data(MessageEventModel::SpecialMarksRole).toInt();
|
||||
if (specialMarks == EventStatus::Hidden || specialMarks == EventStatus::Replaced) {
|
||||
return false;
|
||||
}
|
||||
@@ -57,9 +47,5 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NeoChatConfig::self()->showLeaveJoinEvent() && eventType == MessageEventModel::State) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -180,28 +180,7 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
|
||||
#ifndef QUOTIENT_07
|
||||
connect(room, &Room::notificationCountChanged, this, &RoomListModel::handleNotifications);
|
||||
#endif
|
||||
connect(room, &Room::highlightCountChanged, this, [this, room] {
|
||||
if (room->highlightCount() == 0) {
|
||||
return;
|
||||
}
|
||||
if (room->timelineSize() == 0) {
|
||||
return;
|
||||
}
|
||||
auto *lastEvent = room->lastEvent();
|
||||
|
||||
if (!lastEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lastEvent->isStateEvent()) {
|
||||
return;
|
||||
}
|
||||
User *sender = room->user(lastEvent->senderId());
|
||||
if (sender == room->localUser()) {
|
||||
return;
|
||||
}
|
||||
Q_EMIT newHighlight(room->id(), lastEvent->id(), room->displayName(), sender->displayname(), room->eventToString(*lastEvent), room->avatar(128));
|
||||
});
|
||||
#ifndef QUOTIENT_07
|
||||
connect(room, &Room::notificationCountChanged, this, &RoomListModel::refreshNotificationCount);
|
||||
#else
|
||||
|
||||
@@ -116,5 +116,4 @@ Q_SIGNALS:
|
||||
void notificationCountChanged();
|
||||
|
||||
void roomAdded(NeoChatRoom *_t1);
|
||||
void newHighlight(const QString &_t1, const QString &_t2, const QString &_t3, const QString &_t4, const QString &_t5, const QImage &_t6);
|
||||
};
|
||||
|
||||
@@ -29,10 +29,6 @@
|
||||
<label>Merge Room Lists</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="ShowLeaveJoinEvent" type="bool">
|
||||
<label>Show leave and join events in the timeline</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="AllowQuickEdit" type="bool">
|
||||
<label>Use s/text/replacement syntax to edit your last message.</label>
|
||||
<default>false</default>
|
||||
@@ -72,6 +68,14 @@
|
||||
<label>Use a compact room list layout</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="ShowStateEvent" type="bool">
|
||||
<label>Show state events in the timeline</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ShowLeaveJoinEvent" type="bool">
|
||||
<label>Show leave and join events in the timeline</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ShowRename" type="bool">
|
||||
<label>Show rename events in the timeline</label>
|
||||
<default>true</default>
|
||||
|
||||
@@ -215,7 +215,7 @@ void NeoChatRoom::sendTypingNotification(bool isTyping)
|
||||
connection()->callApi<SetTypingJob>(BackgroundRequest, localUser()->id(), id(), isTyping, 10000);
|
||||
}
|
||||
|
||||
const RoomEvent *NeoChatRoom::lastEvent(bool ignoreStateEvent) const
|
||||
const RoomEvent *NeoChatRoom::lastEvent() const
|
||||
{
|
||||
for (auto timelineItem = messageEvents().rbegin(); timelineItem < messageEvents().rend(); timelineItem++) {
|
||||
const RoomEvent *event = timelineItem->get();
|
||||
@@ -227,8 +227,21 @@ const RoomEvent *NeoChatRoom::lastEvent(bool ignoreStateEvent) const
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event->isStateEvent()
|
||||
&& (ignoreStateEvent || !NeoChatConfig::self()->showLeaveJoinEvent() || static_cast<const StateEventBase &>(*event).repeatsState())) {
|
||||
if (event->isStateEvent() && !NeoChatConfig::self()->showStateEvent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto roomMemberEvent = eventCast<const RoomMemberEvent>(event)) {
|
||||
if ((roomMemberEvent->isJoin() || roomMemberEvent->isLeave()) && !NeoChatConfig::self()->showLeaveJoinEvent()) {
|
||||
continue;
|
||||
} else if (roomMemberEvent->isRename() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave() && !NeoChatConfig::self()->showRename()) {
|
||||
continue;
|
||||
} else if (roomMemberEvent->isAvatarUpdate() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave()
|
||||
&& !NeoChatConfig::self()->showAvatarUpdate()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (event->isStateEvent() && static_cast<const StateEventBase &>(*event).repeatsState()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -242,6 +255,14 @@ const RoomEvent *NeoChatRoom::lastEvent(bool ignoreStateEvent) const
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef QUOTIENT_07
|
||||
if (auto lastEvent = eventCast<const StateEvent>(event)) {
|
||||
#else
|
||||
if (auto lastEvent = eventCast<const StateEventBase>(event)) {
|
||||
#endif
|
||||
return lastEvent;
|
||||
}
|
||||
|
||||
if (auto lastEvent = eventCast<const RoomMessageEvent>(event)) {
|
||||
return lastEvent;
|
||||
}
|
||||
@@ -332,7 +353,7 @@ QDateTime NeoChatRoom::lastActiveTime()
|
||||
return QDateTime();
|
||||
}
|
||||
|
||||
if (auto event = lastEvent(true)) {
|
||||
if (auto event = lastEvent()) {
|
||||
return event->originTimestamp();
|
||||
}
|
||||
|
||||
@@ -475,7 +496,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
|
||||
[](const StickerEvent &e) {
|
||||
return e.body();
|
||||
},
|
||||
[this](const RoomMemberEvent &e) {
|
||||
[this, prettyPrint](const RoomMemberEvent &e) {
|
||||
// FIXME: Rewind to the name that was at the time of this event
|
||||
auto subjectName = this->htmlSafeMemberName(e.userId());
|
||||
if (e.membership() == MembershipType::Leave) {
|
||||
@@ -488,8 +509,11 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
|
||||
.arg(e.userId(), static_cast<NeoChatUser *>(user(e.userId()))->color().name(), subjectName);
|
||||
|
||||
if (prettyPrint) {
|
||||
subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
|
||||
.arg(e.userId(), static_cast<NeoChatUser *>(user(e.userId()))->color().name(), subjectName);
|
||||
}
|
||||
|
||||
// The below code assumes senderName output in AuthorRole
|
||||
switch (e.membership()) {
|
||||
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
/// This function respect the showLeaveJoinEvent setting and discard
|
||||
/// other not interesting events. This function can return an empty pointer
|
||||
/// when the room is empty of RoomMessageEvent.
|
||||
[[nodiscard]] const Quotient::RoomEvent *lastEvent(bool ignoreStateEvent = false) const;
|
||||
[[nodiscard]] const Quotient::RoomEvent *lastEvent() const;
|
||||
|
||||
/// Convenient way to get the last event but in a string format.
|
||||
///
|
||||
|
||||
@@ -77,8 +77,38 @@ Kirigami.ScrollablePage {
|
||||
title: i18n("Timeline Events")
|
||||
}
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showDeletedMessages
|
||||
text: i18n("Show deleted messages")
|
||||
checked: Config.showDeletedMessages
|
||||
enabled: !Config.isShowDeletedMessagesImmutable
|
||||
onToggled: {
|
||||
Config.showDeletedMessages = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
|
||||
MobileForm.FormDelegateSeparator { above: showDeletedMessages; below: showStateEvents }
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showStateEvents
|
||||
text: i18n("Show state events")
|
||||
checked: Config.showStateEvent
|
||||
enabled: !Config.isShowStateEventImmutable
|
||||
onToggled: {
|
||||
Config.showStateEvent = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
|
||||
MobileForm.FormDelegateSeparator {
|
||||
visible: Config.showStateEvent
|
||||
above: showStateEvents
|
||||
below: showLeaveJoinEventDelegate }
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showLeaveJoinEventDelegate
|
||||
visible: Config.showStateEvent
|
||||
text: i18n("Show leave and join events")
|
||||
checked: Config.showLeaveJoinEvent
|
||||
enabled: !Config.isShowLeaveJoinEventImmutable
|
||||
@@ -88,10 +118,15 @@ Kirigami.ScrollablePage {
|
||||
}
|
||||
}
|
||||
|
||||
MobileForm.FormDelegateSeparator { above: showLeaveJoinEventDelegate; below: showNameDelegate }
|
||||
MobileForm.FormDelegateSeparator {
|
||||
visible: Config.showStateEvent
|
||||
above: showLeaveJoinEventDelegate
|
||||
below: showNameDelegate
|
||||
}
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showNameDelegate
|
||||
visible: Config.showStateEvent
|
||||
text: i18n("Show name change events")
|
||||
checked: Config.showRename
|
||||
enabled: !Config.isShowRenameImmutable
|
||||
@@ -101,10 +136,15 @@ Kirigami.ScrollablePage {
|
||||
}
|
||||
}
|
||||
|
||||
MobileForm.FormDelegateSeparator { above: showNameDelegate; below: showAvatarChangeDelegate }
|
||||
MobileForm.FormDelegateSeparator {
|
||||
visible: Config.showStateEvent
|
||||
above: showNameDelegate
|
||||
below: showAvatarChangeDelegate
|
||||
}
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showAvatarChangeDelegate
|
||||
visible: Config.showStateEvent
|
||||
text: i18n("Show avatar update events")
|
||||
checked: Config.showAvatarUpdate
|
||||
enabled: !Config.isShowAvatarUpdateImmutable
|
||||
@@ -113,19 +153,6 @@ Kirigami.ScrollablePage {
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
|
||||
MobileForm.FormDelegateSeparator { above: showAvatarChangeDelegate; below: showDeletedMessages }
|
||||
|
||||
MobileForm.FormCheckDelegate {
|
||||
id: showDeletedMessages
|
||||
text: i18n("Show deleted messages")
|
||||
checked: Config.showDeletedMessages
|
||||
enabled: !Config.isShowDeletedMessagesImmutable
|
||||
onToggled: {
|
||||
Config.showDeletedMessages = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user