From 0cee464ccfaecc1fe1baa452de88d97377768097 Mon Sep 17 00:00:00 2001 From: npub1885neck555704ngfny8trcdweaxe6spxjx8uweftd86spn0fz67slrg8q8 <39e93ce2d4a53cfacd09990eb1e1aecf4d9d4026918fc7652b69f500cde916bd@buzz.block.builderlab.xyz> Date: Mon, 27 Jul 2026 23:53:07 +0200 Subject: [PATCH] fix(desktop): equalize Inbox context-line height for DM rows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the Inbox list, the context line under the sender name renders a #channel chip for channel rows ("Mentioned in #general", "Thread in #general") but plain text for DM rows ("DM from alice"). The chip's min-height made chip rows 19px tall while DM rows measured 12px, so adjacent rows visibly misaligned under the name. Give the InboxLabel row min-h-(--inline-chip-min-height) — the same variable the chip resolves — so both variants occupy identical height. Text stays vertically centered via the existing items-center. New screenshot spec seeds adjacent DM/mention rows, asserts the two label heights are equal, and regenerates the documenting shots. Reported in #buzz-bugs. Co-authored-by: Thomas Petersen Signed-off-by: Thomas Petersen --- desktop/playwright.config.ts | 1 + .../src/features/home/ui/InboxListPane.tsx | 2 +- .../e2e/dm-label-spacing-screenshots.spec.ts | 185 ++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 desktop/tests/e2e/dm-label-spacing-screenshots.spec.ts diff --git a/desktop/playwright.config.ts b/desktop/playwright.config.ts index 40dd5dd1b..56ea51952 100644 --- a/desktop/playwright.config.ts +++ b/desktop/playwright.config.ts @@ -104,6 +104,7 @@ export default defineConfig({ "**/persona-model-combobox-screenshots.spec.ts", "**/drafts-screenshots.spec.ts", "**/inbox-refactor-screenshots.spec.ts", + "**/dm-label-spacing-screenshots.spec.ts", "**/buzz-theme-screenshots.spec.ts", "**/channel-sort.spec.ts", "**/identity-lost.spec.ts", diff --git a/desktop/src/features/home/ui/InboxListPane.tsx b/desktop/src/features/home/ui/InboxListPane.tsx index 20db0b515..f917e1172 100644 --- a/desktop/src/features/home/ui/InboxListPane.tsx +++ b/desktop/src/features/home/ui/InboxListPane.tsx @@ -90,7 +90,7 @@ function InboxLabel({
{ + content: string; + created_at: number; + id: string; + kind: number; + pubkey: string; + tags: string[][]; + }; + __BUZZ_E2E_PUSH_MOCK_FEED_ITEM__?: (item: { + category: "mention" | "needs_action" | "activity" | "agent_activity"; + channel_id: string | null; + channel_name: string; + channel_type?: string | null; + content: string; + created_at: number; + id: string; + kind: number; + pubkey: string; + tags: string[][]; + }) => void; +}; + +test.describe("dm label spacing screenshots", () => { + test.use({ viewport: { width: 1280, height: 900 } }); + + test("inbox rows with channel chips and DM labels align", async ({ + page, + }) => { + await installMockBridge(page, { mode: "mock" }); + + await page.goto("/", { waitUntil: "domcontentloaded" }); + await expect(page.getByTestId("home-inbox-list")).toBeVisible({ + timeout: 10_000, + }); + await page.waitForFunction(() => { + const win = window as MockFeedWindow; + return ( + typeof win.__BUZZ_E2E_EMIT_MOCK_MESSAGE__ === "function" && + typeof win.__BUZZ_E2E_PUSH_MOCK_FEED_ITEM__ === "function" + ); + }); + + await page.evaluate( + ({ alice, charlie, dmChannelId, generalChannelId }) => { + const win = window as MockFeedWindow; + const emitMessage = win.__BUZZ_E2E_EMIT_MOCK_MESSAGE__; + const pushFeedItem = win.__BUZZ_E2E_PUSH_MOCK_FEED_ITEM__; + if (!emitMessage || !pushFeedItem) { + throw new Error("Mock bridge helpers are not installed."); + } + + const base = Math.floor(Date.now() / 1000); + const seed = (input: { + category: "mention" | "activity"; + channelId: string; + channelName: string; + channelType: string | null; + content: string; + id: string; + offset: number; + pubkey: string; + }) => { + const event = emitMessage({ + channelName: input.channelName, + content: input.content, + createdAt: base + input.offset, + id: input.id, + pubkey: input.pubkey, + }); + pushFeedItem({ + category: input.category, + channel_id: input.channelId, + channel_name: input.channelName, + channel_type: input.channelType, + content: event.content, + created_at: event.created_at, + id: event.id, + kind: event.kind, + pubkey: event.pubkey, + tags: event.tags, + }); + }; + + seed({ + category: "mention", + channelId: generalChannelId, + channelName: "general", + channelType: "stream", + content: "Can you take a look at the release checklist?", + id: "shot-spacing-mention", + offset: 3, + pubkey: charlie, + }); + seed({ + category: "activity", + channelId: dmChannelId, + channelName: "alice-tyler", + channelType: "dm", + content: "also should I be doing tests on these before approving?", + id: "shot-spacing-dm", + offset: 2, + pubkey: alice, + }); + seed({ + category: "activity", + channelId: generalChannelId, + channelName: "general", + channelType: "stream", + content: "ah speaking of I have a fix for this page.", + id: "shot-spacing-thread", + offset: 1, + pubkey: charlie, + }); + }, + { + alice: TEST_IDENTITIES.alice.pubkey, + charlie: TEST_IDENTITIES.charlie.pubkey, + dmChannelId: DM_CHANNEL_ID, + generalChannelId: GENERAL_CHANNEL_ID, + }, + ); + + const mentionRow = page.getByTestId("home-inbox-item-shot-spacing-mention"); + const dmRow = page.getByTestId("home-inbox-item-shot-spacing-dm"); + await expect(mentionRow).toBeVisible(); + await expect(dmRow).toBeVisible(); + await expect(dmRow).toContainText("DM from alice"); + await expect(mentionRow).toContainText("Mentioned in"); + await waitForAnimations(page); + + // The claim under test: the context line under the sender name has the + // same height whether it holds a #channel chip or plain "DM from x" text. + const labelHeights = await page.evaluate(() => { + const measure = (id: string) => { + const row = document.querySelector(`[data-testid="${id}"]`); + const label = row?.querySelector(".message-markdown"); + return label ? label.getBoundingClientRect().height : null; + }; + return { + dm: measure("home-inbox-item-shot-spacing-dm"), + mention: measure("home-inbox-item-shot-spacing-mention"), + }; + }); + console.log("label heights:", JSON.stringify(labelHeights)); + + await page.screenshot({ path: `${SHOTS}/inbox-row-stack.png` }); + await page + .getByTestId("home-inbox-list") + .screenshot({ path: `${SHOTS}/inbox-list-only.png` }); + + expect(labelHeights.dm).not.toBeNull(); + expect(labelHeights.mention).not.toBeNull(); + // Regression guard: chip rows and plain-text DM rows share a height. + expect(labelHeights.dm).toBe(labelHeights.mention); + }); +});