Do not render unknown state events in the timeline - #7464
Conversation
An unknown or custom state event was rendered in the timeline as the untranslated developer string "Custom event <type>", while the room list already filtered the same event out. Any room whose members use a custom state event therefore shows rows of internal event types to every user. The formatter now declines custom state events in both rendering modes, and the timeline drops events the formatter cannot render instead of coercing the missing text to an empty string. Filtering the raw items before the item factory runs matters: returning null later would leave an empty tappable pill behind, and would also split the bubble block of the messages either side of the hidden event. A day divider whose only remaining event was hidden is dropped with it. The SDK-side timeline filter cannot express this, because it excludes enumerated state event types and the set of custom types is unbounded.
|
Thank you for your contribution! Here are a few things to check in the PR to ensure it's reviewed as quickly as possible:
|
|
Can I ask that instead of unconditionally removing these from the timeline, there's still an option to show them? Maybe a toggle in developer options? |
|
I think we need some product decision for this. @mxandreas this is waiting for when you come back. |
|
That said, this seems something that should use |
Happy to help but not sure if I fully understand the core problem correctly. So, there can always be a case where the client just does not know an event type (perhaps it is a new event type and the client is old or it is some kind of custom event as mentioned) - correct? I think hiding such an event isn't good because that can make "messages" disappear and create confusion. But I also agree that a hardcoded English message is also not great. Thus, ideally:
|
|
Also, I assume this applies only to non-state events and that in case the event has the fallback |
|
I think this duplicates #6862 |
Content
An unknown or custom state event was rendered in the timeline as the untranslated developer string
Custom event <type>, while the room list already filtered the same event out. Any room whose members use a custom state event therefore shows rows of internal event types to every user, in English, whatever their locale.The formatter now declines custom state events in both rendering modes, and the timeline drops events the formatter cannot render instead of coercing the missing text to an empty string. Both halves are needed: on its own, returning null from the formatter turns the wrong string into an empty tappable pill, because the timeline had no notion of "this event has nothing to display".
The filter is applied to the raw items before the item factory runs, rather than by returning null later. That matters for two reasons: the hidden event never becomes a neighbour when bubble grouping is computed, so the messages either side of it are not split into separate blocks for no visible reason; and a day divider whose only remaining event was hidden is dropped with it. This mirrors the existing
keepDisplayablePinnedEventsprecedent.The SDK-side timeline filter cannot express this. It excludes an enumerated list of state event types, and the set of custom types is unbounded, so client-side filtering is the only option.
The issue also asks for a developer option to view hidden events (#3760). No such option exists in the codebase yet, so this ships the plain hide; the opt-in would be purely additive later.
Motivation and context
Part of #4095.
Tests
features/messages/impl/.../timeline/factories/DisplayableTimelineEventsTest.kt: a custom state event is dropped, a known state event and a message are kept, a day divider is dropped when its only event was hidden and kept when the day still has an event or a read marker.features/messages/impl/.../timeline/factories/TimelineItemsFactoryTest.kt: a custom state event is not emitted and does not split the group of the messages around it. This fails on develop withNone, Middle, Noneinstead ofFirst, Last, so it pins both the filtering and the fact that it happens before the group position is computed.libraries/eventformatter/impl/.../StateContentFormatterTest.kt: a custom state event is not rendered in either rendering mode.Run with
./gradlew :features:messages:impl:testDebugUnitTest :libraries:eventformatter:impl:testDebugUnitTest.Read receipts and permalinks that land on a hidden event are not covered: as with the state types the SDK already excludes, they have nowhere to resolve to.
Tested devices
Checklist