Skip to content

fix(timeline): suppress dividers when the underlying event renders null#720

Merged
7w1 merged 4 commits into
SableClient:devfrom
mvanhorn:osc/701-suppress-orphan-day-dividers
May 14, 2026
Merged

fix(timeline): suppress dividers when the underlying event renders null#720
7w1 merged 4 commits into
SableClient:devfrom
mvanhorn:osc/701-suppress-orphan-day-dividers

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

Summary

Closes #701. Stops the timeline from rendering bare day-dividers / new-message dividers when the underlying event was filtered out at render time. The orphan-divider pattern in the issue's screenshot was caused by useProcessedTimeline attaching willRenderDayDivider to events that useTimelineEventRenderer later returned null for (e.g. membership / profile-change events when hideMembershipEvents or hideNickAvatarEvents are on). The render layer would still emit the divider but skip the event under it.

Why this matters

7w1's diagnosis on the issue: "this is specifically an issue ... when there's rooms with lots of hidden events (e.g. joins/leaves, profile changes) and no other messages, such as announcement channels." The render now matches that — when an event renders to null, its divider is skipped too.

Diff

src/app/features/room/RoomTimeline.tsx:

+const showDividers = renderedEvent !== null;
-const dividers = (
+const dividers = showDividers ? (
   <>
     {eventData.willRenderDayDivider && ( ... )}
     {eventData.willRenderNewDivider && ( ... )}
   </>
-);
+) : null;

8 lines added, 2 changed.

Edge case + follow-up

If a day's first hook-eligible event is rendered-null but a later event renders correctly, the day-divider is lost for that day. That's strictly better than an orphan divider in the announcement-channel symptom case, and the proper fix (useProcessedTimeline propagates the divider forward to the first event whose renderer prediction is non-null) is a larger refactor that can land separately. Happy to follow up with that if you'd prefer not to take the small fix first.

Verification

  • pnpm tsc --noEmitNo errors found.
  • Manual smoke test path (per issue 7w1 comment): an announcement-style room dominated by profile-change events stops showing bare day-dividers between them. A normal chat with mixed messages and joins still renders dividers correctly because the day's first message-event is the one carrying the divider, and that event renders fine.

This contribution was developed with AI assistance (Claude Code).

Closes SableClient#701

The hook hands the renderer a `willRenderDayDivider` / `willRenderNewDivider`
flag attached to the FIRST event of a new day (or the readUptoEventId
boundary). The render layer in RoomTimeline always emitted those dividers
even when `useTimelineEventRenderer` returned `null` for the event itself
— for example when `hideMembershipEvents` / `hideNickAvatarEvents` /
`hideMemberInReadOnly` filtered the underlying event out at render time.

Result: announcement channels and similar rooms whose only events on a
given day are hidden (joins/leaves/profile changes) showed a bare day
divider with no message under it. Same orphan pattern produced the
"dates showing without content" complaint in SableClient#701.

Fix: gate the dividers JSX on `renderedEvent !== null`. When the event
renders null, the dividers are skipped too. When at least one event of
a day passes the renderer, the divider is attached to it the same way
as before.

Edge case: a day where the first hook-eligible event is rendered as null
but a later event renders correctly will lose the day divider entirely.
That is strictly better than an orphan divider in the symptom case the
issue reports, and the proper fix (propagate the divider forward in
useProcessedTimeline based on render prediction) is a larger refactor
that can land separately.
@mvanhorn mvanhorn requested review from 7w1 and hazre as code owners April 26, 2026 10:34
7w1 added 3 commits May 13, 2026 22:10
# Conflicts:
#	src/app/features/room/RoomTimeline.tsx
@7w1 7w1 enabled auto-merge May 14, 2026 03:17
@7w1 7w1 added this pull request to the merge queue May 14, 2026
Merged via the queue into SableClient:dev with commit ef0df13 May 14, 2026
12 checks passed
nushea pushed a commit to Septicity/Sable that referenced this pull request May 14, 2026
> [!IMPORTANT]
> Merging this PR will create a new release.

## Features

* Add Space banner support per MSC4221. You can now set it from the
space settings. ([SableClient#801](<SableClient#801>)
by @nushea)
* Add setting to show icons of the rooms in the Rooms sidebar
([SableClient#768](<SableClient#768>) by @nushea)
* Add Resize the sidepanels and the thread height of the original object
using hoverable tools.
([SableClient#768](<SableClient#768>) by @nushea)
* Add toggle to allow one to not join a call in a room by just clicking
it in the sidebar.
([SableClient#768](<SableClient#768>) by @nushea)
* Added the ability to right click on a folder to rename it.
([SableClient#814](<SableClient#814>) by @7w1)
* Upgraded the forward modal to use the same modal present for search
and added the ability to forward to same room the message is from.
([SableClient#808](<SableClient#808>) by @7w1)

### Introduce the new Sable logo!
([SableClient#809](<SableClient#809>) by @Septicity)

- You may need to reinstall PWAs to recieve the new app icons, if you
use them.
- Our logo is [licensed under
CC0](https://github.com/SableClient/Sable/blob/dev/TRADEMARKS.md), aka
do whatever you want with it!
- Also, there's a script for other us or other forks to replace the icon
in the future, if needed.

## Fixes

* Add graceful fail if MSC4140 event delay exceeded
([SableClient#276](<SableClient#276>) by
@jasonlaguidice)
* Drops paragraph tags when messages are only a single paragraph, use
markdown (two new lines) to define a new paragraph rather than a line
break. ([SableClient#799](<SableClient#799>) by @7w1)
* Fixed the text wrapping behavior of fallback messages.
([SableClient#806](<SableClient#806>) by @7w1)
* Fixed the thin line appearing at the top of unstyled profiles.
([SableClient#803](<SableClient#803>) by @7w1)
* Matrix.to links sent without explicit markdown formatting are sent as
raw links instead of html links.
([SableClient#786](<SableClient#786>) by @7w1)
* Fix `/myroomnick` and room cosmetics display name not updating name.
([SableClient#805](<SableClient#805>) by @7w1)
* Fix spoilers not hiding nested content like mentions, emoji images,
and custom-colored spans.
([SableClient#807](<SableClient#807>) by @7w1)
* Added svgs to the allowed embeds for rendering/sending.
([SableClient#804](<SableClient#804>) by @7w1)
* Suppress timeline dividers when there's no rendered events between
them. ([SableClient#720](<SableClient#720>) by
@mvanhorn)
* Improve thread drawer separation between the pinned root message and
replies with a border.
([SableClient#830](<SableClient#830>) by @7w1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dates showing even without content

2 participants