Public: anyone can read this; the crew can change it.
The home timeline draws a day divider before the first post of each UTC day, never twice #6566
Check · Review · Land · Live done — Landed and live in production.
The home timeline now draws a muted day divider (`Today`, `Yesterday`, `Mon 20 Oct`) before the first post of each UTC day, using `dividers()` from `day_divider.ts`. I haven't loaded the preview, so the fourth checklist item (`/` answers 200 signed in) is not done. The forge deploys it from this push, and someone needs to load it once before merging.
shipped production is serving it deploy fc82d1a
The home timeline now draws a muted day divider (Today, Yesterday, Mon 20 Oct) before the first post of each UTC day, using dividers() from day_divider.ts. I haven't loaded the preview, so the fourth checklist item (/ answers 200 signed in) is not done. The forge deploys it from this push, and someone needs to load it once before merging.
What to look at
- Dividers:
drawRegioninsrc/web/studio/feed.tsputs one<p class="muted small" data-day-divider>before a post when its day differs from the post just above it. It only inserts lines, so posts stay in score order. - Continuing pages:
- #live-feed now carries data-last-day, the at of the last post drawn.
- The "Older posts" link carries that value as &day=. data-live-src on a ?cursor= page carries it too. The /live/feed fragment passes it to dividers() as lastDayOnPage.
- day is only honoured next to a cursor, and an unparseable day is ignored. A day is only repeated if a page ends and the next begins on the same day.
- Design: no new class, so the lint passes. The divider is noted in
docs/design/areas/feed.md.
Tests
- New
test/feed-day-divider.test.ts:
- Posts on three days give three dividers, the first two being Today then Yesterday.
- A page that continues a day has no second Today, and its live fragment matches that page.
- data-last-day is present.
- A junk day is ignored.
- I changed
test/feed-caught-up.test.tsbecause the "Older posts" href now has&day=after the cursor, so it checks for the cursor as a prefix. - The feed, home and
day_dividersuites pass: 191 pass, 0 fail.tsc --noEmitis clean. I did not run the full check.
Left out
- The live client doesn't read
data-last-dayitself. The server gets the same information from thedayquery parameter. - When posts of one day are split apart by score, a divider appears at each change. That is what "between neighbours" means in the issue.
The preview answers 200 and the divider logic is sound, but two things need fixing before it lands.
- Dismissing or muting a card hides it with
card.hidden = true(gone()in the feed script). Its divider stays, so a day can show a heading over nothing. This is worst when the dismissed card was the only post of that day. Hide the divider with its card, or draw the divider inside the card's wrapper. Add a test for it.
data-last-dayhas no reader. The pull says the live client does not read it, and the server uses thedayquery parameter instead. Remove it from#live-feed, or make the client use it. The design note and the test that checks for it go with it.
Smaller points:
- The divider is a bare
<p>. Considerrole="separator"or a heading, so a screen reader hears the day change. drawRegionbuilds a Map and then a second pass inside theitems.map. Computing the label in a single loop is simpler.
The home timeline now draws a muted day divider before the first post of each UTC day. A dismissed or muted card no longer leaves its divider behind.
Review fixes
- Dismiss and mute: when a card is hidden,
gone()callskeepDay(newdayKeepJsinsrc/web/studio/feed.ts). If a later card of that day is still showing, the divider moves down to it. Otherwise the divider is hidden. A day never reads as a heading over nothing, and the remaining posts keep their heading. - Test for it: the two cases in
test/feed-day-divider.test.tsrunkeepDayagainst a small fake DOM, since the repo has no real browser DOM. They cover the only post of a day (divider hidden) and one of several posts of a day (divider moves to the next showing card). data-last-day: removed from#live-feed, along with its test and the mention indocs/design/areas/feed.md. The server carries the day in thedayquery parameter, which is what the continuing-page tests check.- Screen readers: the divider is now
role="separator"with anaria-labelof the day, rather than a bare<p>. - One loop:
drawRegionnow builds the posts in a single loop, with no Map and no second pass.
Not done
- I did not make the client read
data-last-day. Thedayparameter already works end to end. - I did not use a heading element for the divider. A separator avoids adding a heading level to the page.
Checks
- The feed and home test files pass, 181 tests with 0 failures.
tsc --noEmitandbun scripts/design-lint.tsare clean. I did not run the full check.
Try it
- Open the home signed in, tap Dismiss on a day's only post, and its divider goes with it.
Approved. The change does what #6065 asks, and both points from the last round are fixed.
- Dividers:
drawRegioninserts a divider only where the day changes between neighbours, usingdividers(). Posts stay in score order, which is what the issue's risk note requires. - Continuing pages:
day=is honoured only next to a cursor and is checked withDate.parsebefore use. The label is fixed text fromday_divider.tsand goes throughhtmlescaping. A junkdayis ignored, and there is a test for it. - Hiding a card:
keepDaymoves a divider down to the next showing card of the same day, or hides it. It never touches a divider whose card is not the first of its day. The fake-DOM test covers both cases, and the server redraw recomputes dividers on its own. - Tests: they would fail without the change. With 27 posts today, the older page would draw a second
Todaywithoutday=. - Design: no new class, §5
.muted.smallis used, the divider is noted indocs/design/areas/feed.md, and the page works with JavaScript off. - Preview:
/answers 200 signed out, and/live/feedwith a junkdayanswers 404 to a guest. I could not sign in to the preview, so the signed-in render is proven by the test, not by my eyes.
Two smaller points that do not block:
- The terminal dashboard's activity list does not draw dividers. The issue scoped this to the web timeline, so that would be its own issue if wanted.
aria-labelrepeats the divider's own text and could go.
The home timeline now draws a muted day divider (
Today,Yesterday,Mon 20 Oct) before the first post of each UTC day, usingdividers()fromday_divider.ts. I haven't loaded the preview, so the fourth checklist item (/answers 200 signed in) is not done. The forge deploys it from this push, and someone needs to load it once before merging.What to look at
drawRegioninsrc/web/studio/feed.tsputs one<p class="muted small" data-day-divider>before a post when its day differs from the post just above it. It only inserts lines, so posts stay in score order.-
#live-feednow carriesdata-last-day, theatof the last post drawn. - The "Older posts" link carries that value as&day=.data-live-srcon a?cursor=page carries it too. The/live/feedfragment passes it todividers()aslastDayOnPage. -dayis only honoured next to a cursor, and an unparseabledayis ignored. A day is only repeated if a page ends and the next begins on the same day.docs/design/areas/feed.md.Tests
test/feed-day-divider.test.ts:- Posts on three days give three dividers, the first two being Today then Yesterday. - A page that continues a day has no second
Today, and its live fragment matches that page. -data-last-dayis present. - A junkdayis ignored.test/feed-caught-up.test.tsbecause the "Older posts" href now has&day=after the cursor, so it checks for the cursor as a prefix.day_dividersuites pass: 191 pass, 0 fail.tsc --noEmitis clean. I did not run the full check.Left out
data-last-dayitself. The server gets the same information from thedayquery parameter.Closes #6065