From 12467417fe0062c634e5ff934fc780eee0e6c5b7 Mon Sep 17 00:00:00 2001 From: Thomas Petersen Date: Thu, 16 Apr 2026 11:41:30 -0400 Subject: [PATCH] fix(desktop): polish timeline spacing and panel chrome Align sticky day headers, thread summaries, and composer offsets so message content stays visible and date transitions happen at the right moment. Soften side-sheet headers and markdown code blocks while keeping thread conversations auto-scrolled as new content arrives. Made-with: Cursor --- .../agents/ui/PersonaCatalogDetailsSheet.tsx | 159 +++++++++--------- .../channels/ui/ChannelManagementSheet.tsx | 13 +- .../features/channels/ui/MembersSidebar.tsx | 2 +- .../src/features/messages/ui/DayDivider.tsx | 8 +- .../messages/ui/MessageThreadPanel.tsx | 147 ++++++++++------ .../messages/ui/MessageThreadSummaryRow.tsx | 2 +- .../features/messages/ui/MessageTimeline.tsx | 8 +- .../messages/ui/TimelineMessageList.tsx | 39 +++-- .../messages/ui/useStickyDayHeader.ts | 9 +- desktop/src/shared/styles/globals.css | 4 +- desktop/src/shared/ui/markdown.tsx | 2 +- 11 files changed, 226 insertions(+), 167 deletions(-) diff --git a/desktop/src/features/agents/ui/PersonaCatalogDetailsSheet.tsx b/desktop/src/features/agents/ui/PersonaCatalogDetailsSheet.tsx index 5c4892c03d..0df75a779d 100644 --- a/desktop/src/features/agents/ui/PersonaCatalogDetailsSheet.tsx +++ b/desktop/src/features/agents/ui/PersonaCatalogDetailsSheet.tsx @@ -43,12 +43,12 @@ export function PersonaCatalogDetailsSheet({ return ( {persona ? ( -
- + <> +
+
+ - - {feedbackNoticeMessage ? ( -

- {feedbackNoticeMessage} -

- ) : null} - - {feedbackErrorMessage ? ( -

- {feedbackErrorMessage} -

- ) : null} - -

- Type -

-

Built-in persona

-
-
-

- Preferred model -

-

- {persona.model ?? "Use app default"} -

-
-
-

- Preferred provider -

-

- {persona.provider ?? "Use app default"} + System prompt

+
+                  {persona.systemPrompt}
+                
- -
-

- System prompt -

-
-                {persona.systemPrompt}
-              
-
-
+ ) : null} diff --git a/desktop/src/features/channels/ui/ChannelManagementSheet.tsx b/desktop/src/features/channels/ui/ChannelManagementSheet.tsx index 8ec47403f2..8c294340c6 100644 --- a/desktop/src/features/channels/ui/ChannelManagementSheet.tsx +++ b/desktop/src/features/channels/ui/ChannelManagementSheet.tsx @@ -38,7 +38,6 @@ import { } from "@/shared/ui/alert-dialog"; import { Button } from "@/shared/ui/button"; import { Input } from "@/shared/ui/input"; -import { Separator } from "@/shared/ui/separator"; import { Sheet, SheetContent, @@ -214,7 +213,7 @@ export function ChannelManagementSheet({ data-testid="channel-management-sheet" side="right" > - +
{channel.name} @@ -314,8 +313,6 @@ export function ChannelManagementSheet({

) : null} - - ) : null} @@ -330,8 +327,6 @@ export function ChannelManagementSheet({ /> - -
- -
- -
- -
- + Members People and bots in {channel.name}. diff --git a/desktop/src/features/messages/ui/DayDivider.tsx b/desktop/src/features/messages/ui/DayDivider.tsx index 93a03cf21a..8ca39cb945 100644 --- a/desktop/src/features/messages/ui/DayDivider.tsx +++ b/desktop/src/features/messages/ui/DayDivider.tsx @@ -4,15 +4,15 @@ export function DayDivider({ label }: { label: string }) { return (
- -

+ +

{label}

- +
); } diff --git a/desktop/src/features/messages/ui/MessageThreadPanel.tsx b/desktop/src/features/messages/ui/MessageThreadPanel.tsx index 19b2dbbc2c..a5673d73b1 100644 --- a/desktop/src/features/messages/ui/MessageThreadPanel.tsx +++ b/desktop/src/features/messages/ui/MessageThreadPanel.tsx @@ -1,3 +1,4 @@ +import * as React from "react"; import { ArrowLeft, X } from "lucide-react"; import type { MainTimelineEntry } from "@/features/messages/lib/threadPanel"; @@ -75,12 +76,11 @@ export function MessageThreadPanel({ threadReplies, threadTypingPubkeys, }: MessageThreadPanelProps) { - if (!threadHead) { - return null; - } + const threadBodyRef = React.useRef(null); + const threadContentRef = React.useRef(null); const composerReplyTarget = - replyTargetMessage && replyTargetMessage.id !== threadHead.id + threadHead && replyTargetMessage && replyTargetMessage.id !== threadHead.id ? { author: replyTargetMessage.author, body: replyTargetMessage.body, @@ -88,9 +88,52 @@ export function MessageThreadPanel({ } : null; + const scrollThreadToBottom = React.useCallback(() => { + const threadBody = threadBodyRef.current; + if (!threadBody) { + return; + } + + threadBody.scrollTo({ + top: threadBody.scrollHeight, + behavior: "auto", + }); + }, []); + + React.useLayoutEffect(() => { + if (!threadHead) { + return; + } + scrollThreadToBottom(); + }, [scrollThreadToBottom, threadHead?.id]); + + React.useEffect(() => { + if (!threadHead) { + return; + } + + const threadContent = threadContentRef.current; + if (!threadContent || typeof ResizeObserver === "undefined") { + return; + } + + const observer = new ResizeObserver(() => { + scrollThreadToBottom(); + }); + + observer.observe(threadContent); + return () => { + observer.disconnect(); + }; + }, [scrollThreadToBottom, threadHead?.id]); + + if (!threadHead) { + return null; + } + return (