From e40d4e71e389e0e5b2d75092d1e9c8ebbad14dd2 Mon Sep 17 00:00:00 2001 From: Thomas Petersen Date: Mon, 4 May 2026 19:02:52 -0400 Subject: [PATCH] Align active agent pill with timeline text Render active agent process pills inline with the message timeline so they sit under the latest message text instead of the composer edge. Co-authored-by: Cursor --- .../features/channels/ui/BotActivityBar.tsx | 2 +- .../src/features/channels/ui/ChannelPane.tsx | 40 +++++++++++-------- .../features/messages/ui/MessageTimeline.tsx | 35 +++++++++------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/desktop/src/features/channels/ui/BotActivityBar.tsx b/desktop/src/features/channels/ui/BotActivityBar.tsx index c0179d0c76..070526a54f 100644 --- a/desktop/src/features/channels/ui/BotActivityBar.tsx +++ b/desktop/src/features/channels/ui/BotActivityBar.tsx @@ -56,7 +56,7 @@ export function BotActivityBar({ return (
{visibleAgents.map((agent) => { diff --git a/desktop/src/features/channels/ui/ChannelPane.tsx b/desktop/src/features/channels/ui/ChannelPane.tsx index 4550a2bfa1..bee6f16867 100644 --- a/desktop/src/features/channels/ui/ChannelPane.tsx +++ b/desktop/src/features/channels/ui/ChannelPane.tsx @@ -229,6 +229,8 @@ export const ChannelPane = React.memo(function ChannelPane({ activeChannel.archivedAt !== null || activeChannel.channelType === "forum" || isSending; + const hasTypingActivity = typingPubkeys.length > 0; + const hasBotActivity = botTypingPubkeys.length > 0; const selectedAgent = React.useMemo( () => @@ -260,6 +262,18 @@ export const ChannelPane = React.memo(function ChannelPane({ currentPubkey={currentPubkey} fetchOlder={fetchOlder} hasOlderMessages={hasOlderMessages} + inlineFooter={ + hasBotActivity ? ( +
+ +
+ ) : null + } isFetchingOlder={isFetchingOlder} personaLookup={personaLookup} profiles={profiles} @@ -287,6 +301,16 @@ export const ChannelPane = React.memo(function ChannelPane({ searchQuery={channelFind.query} targetMessageId={targetMessageId} /> + {hasTypingActivity ? ( +
+ +
+ ) : null} {isNonMemberView ? (
)} -
- -
- -
-
{threadHeadMessage ? ( diff --git a/desktop/src/features/messages/ui/MessageTimeline.tsx b/desktop/src/features/messages/ui/MessageTimeline.tsx index 09e6524ccb..a6e53ac86a 100644 --- a/desktop/src/features/messages/ui/MessageTimeline.tsx +++ b/desktop/src/features/messages/ui/MessageTimeline.tsx @@ -15,6 +15,7 @@ import { useTimelineScrollManager } from "./useTimelineScrollManager"; type MessageTimelineProps = { channelId?: string | null; messages: TimelineMessage[]; + inlineFooter?: React.ReactNode; isLoading?: boolean; emptyTitle?: string; emptyDescription?: string; @@ -47,6 +48,7 @@ type MessageTimelineProps = { export const MessageTimeline = React.memo(function MessageTimeline({ channelId, messages, + inlineFooter, isLoading = false, emptyTitle = "No messages yet", emptyDescription = "Send the first message to start the thread.", @@ -172,21 +174,24 @@ export const MessageTimeline = React.memo(function MessageTimeline({ ) : null} {!isLoading && messages.length > 0 ? ( - + <> + + {inlineFooter} + ) : null}