Public: anyone can read this; the crew can change it.
Every post's time on the home timeline shows its exact UTC on hover #6685
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/6063-every-post-s-time-on-the-home-timeline-s → main 2 commits fork 1 thread · 1 unresolved
2 files
changed +23
−3
src/web/studio/feed.ts +3 −3
| @@ -26,7 +26,7 @@ import { html, type Html } from "../html.ts"; | ||
| 26 | 26 | import { fragment } from "../layout.ts"; |
| 27 | 27 | import { draftJs } from "../draft.ts"; |
| 28 | 28 | import { outboxJs } from "../outbox.ts"; |
| 29 | import { avatar, btn, card, disclosure, empty, nameMark, stateBadge, time, timeAgo } from "../ui.ts"; | |
| 29 | import { avatar, btn, card, disclosure, empty, nameMark, stateBadge, time } from "../ui.ts"; | |
| 30 | 30 | import { writableAppsOf } from "./asks.ts"; |
| 31 | 31 | |
| 32 | 32 | /** Events that can change what the feed says. */ |
| @@ -114,7 +114,7 @@ export function feedCard( | ||
| 114 | 114 | const head = html`${avatar(item.actor ?? item.app)} |
| 115 | 115 | <strong class="break">${item.actor ?? item.app}</strong |
| 116 | 116 | >${nameMark(item.actor === null ? undefined : marks.get(item.actor))} |
| 117 | <span class="muted small break">${item.app} · ${timeAgo(item.at)}</span> | |
| 117 | <span class="muted small break">${item.app} · ${time(item.at)}</span> | |
| 118 | 118 | ${settledBadge(item.settled)} |
| 119 | 119 | <span class="spacer"></span> |
| 120 | 120 | <span class="badge">${KIND_LABEL[item.kind]}</span>`; |
| @@ -164,7 +164,7 @@ const lines = (text: string): Html[] => | ||
| 164 | 164 | export function thoughtCard(thought: Thought, who: string, placement?: Placement): Html { |
| 165 | 165 | const head = html`${avatar(who)} |
| 166 | 166 | <strong>${who}</strong> |
| 167 | <span class="muted small">${timeAgo(thought.receivedAt)}</span> | |
| 167 | <span class="muted small">${time(thought.receivedAt)}</span> | |
| 168 | 168 | <span class="spacer"></span> |
| 169 | 169 | <span class="badge">Received</span>`; |
| 170 | 170 | return card( |
test/feed-time-title.test.ts added +20
| @@ -0,0 +1,20 @@ | ||
| 1 | /** Every post's time on the home timeline carries its exact UTC on hover (#6063). */ | |
| 2 | import { describe, expect, test } from "bun:test"; | |
| 3 | import type { Thought } from "../src/core/thoughts.ts"; | |
| 4 | import type { FeedItem } from "../src/feed/rank.ts"; | |
| 5 | import { feedCard, thoughtCard } from "../src/web/studio/feed.ts"; | |
| 6 | ||
| 7 | const at = "2026-03-04T05:06:07.000Z"; | |
| 8 | const stamp = /<time datetime="2026-03-04T05:06:07\.000Z"\s+title="2026-03-04 05:06 UTC"\s*>/; | |
| 9 | ||
| 10 | describe("feed card times", () => { | |
| 11 | test("a post's time is a <time> with its exact UTC", () => { | |
| 12 | const item = { id: "e1", kind: "run", app: "alice/notes", actor: "scribe", at, what: "x", reason: "y", link: "/alice/notes/runs/r1" } as FeedItem; | |
| 13 | expect(feedCard(item).text).toMatch(stamp); | |
| 14 | }); | |
| 15 | ||
| 16 | test("a thought's time is a <time> with its exact UTC", () => { | |
| 17 | const thought = { id: "t1", text: "hi", receivedAt: at } as Thought; | |
| 18 | expect(thoughtCard(thought, "alice", undefined).text).toMatch(stamp); | |
| 19 | }); | |
| 20 | }); |
new above
offline
Add a liveFeedFragment assertion too: that is the path web viewers get live, and it is currently untested.