From 1bb36782afd212c07b2731e4a4fefbb46ecd1067 Mon Sep 17 00:00:00 2001 From: Taylor Ho Date: Mon, 27 Jul 2026 14:52:53 -0700 Subject: [PATCH] feat(composer): unify typing indicator into the pill strip and align pill styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typing group becomes a slot sibling of the working-agent pills: - BotActivityBar.tsx: BotActivityComposerAction gains a `typingIndicator` prop rendered as the strip's trailing AnimatedPillSlot, so the typing group shares the scroller, edge fades, and layout/enter/exit animations with the pills; lone-item shrink logic now counts the typing slot - ChannelComposerActivityRow.tsx: the row renders ONE strip hosting both groups instead of a pill strip beside a standalone TypingIndicatorRow - ChannelPane.tsx / MessageThreadPanel.tsx: thread panel mirrors the same structure — ChannelPane builds the strip (thread typers included) and the panel's activity row just mounts it; `threadTypingPubkeys` prop removed from MessageThreadPanel; row height fixed at h-8.5 to match the channel row so the bottom-anchored composer never bumps - TypingIndicatorRow.tsx: drop the now-unused "activity" variant — the strip's slot owns sizing/spacing, so only the default variant remains - composer.css: corner-mask offset 2.5rem -> 2.625rem to match the fixed h-8.5 activity row below the composer in both surfaces - channels.spec.ts: new e2e covering the typing group rendering inside the strip, trailing the pills, and scrolling under the edge fades Align the "is working" pill with the "is typing" indicator: - Remove the pill's border, background, shadow, and horizontal padding — hover/open states signal through text color only - Match label typography (text-xs font-medium, was font-semibold) and the typing label's translate-y-px optical nudge; avatar-to-label gap-2 - Drop the labelClassName="font-semibold" overrides that compensated for the pill's old heavier weight (channel row + thread strip) Also document in AGENTS.md that e2e reruns need `pnpm run build:e2e` — a plain build omits the mock-bridge module and every spec fails at boot. Co-authored-by: Taylor Ho Signed-off-by: Taylor Ho --- .../features/channels/ui/BotActivityBar.tsx | 57 +++++++++++++-- .../ui/ChannelComposerActivityRow.tsx | 71 +++++++++---------- .../src/features/channels/ui/ChannelPane.tsx | 25 ++++++- .../messages/ui/MessageThreadPanel.tsx | 41 +++-------- .../messages/ui/TypingIndicatorRow.tsx | 34 ++------- desktop/tests/e2e/channels.spec.ts | 70 ++++++++++++++++++ 6 files changed, 189 insertions(+), 109 deletions(-) diff --git a/desktop/src/features/channels/ui/BotActivityBar.tsx b/desktop/src/features/channels/ui/BotActivityBar.tsx index c13e918cc..bfe322764 100644 --- a/desktop/src/features/channels/ui/BotActivityBar.tsx +++ b/desktop/src/features/channels/ui/BotActivityBar.tsx @@ -25,6 +25,12 @@ type BotActivityBarProps = { channelId?: string | null; onOpenAgentSession: (pubkey: string, channelId?: string | null) => void; profiles?: UserProfileLookup; + /** + * Combined typing indicator (humans + typing-fallback agents), rendered as + * the strip's trailing item — a sibling of the working pills, so it shares + * the scroller, edge fades, and layout/enter/exit animations. + */ + typingIndicator?: React.ReactNode; workingBotPubkeys: string[]; }; @@ -285,8 +291,10 @@ function BotActivityAgentPill({ overrides the button's leading-none). Inter's ascent+descent ink is ~1.21em (~14.5px at text-xs) — taller than a leading-none line box — and BOTH this span and the truncate span clip to their boxes, which - sheared descenders ("g", "y") off the label. */} - + sheared descenders + ("g", "y") off the label. translate-y-px mirrors the typing + indicator label's optical nudge so both baselines line up. */} +