diff --git a/desktop/src/features/channels/ui/ChannelScreen.tsx b/desktop/src/features/channels/ui/ChannelScreen.tsx index 45ed6d56d8..c868230df0 100644 --- a/desktop/src/features/channels/ui/ChannelScreen.tsx +++ b/desktop/src/features/channels/ui/ChannelScreen.tsx @@ -265,6 +265,23 @@ export function ChannelScreen({ (messageId: string) => directReplyIdsByParentId.get(messageId)?.[0] ?? null, [directReplyIdsByParentId], ); + const getReplyDescendantIdsForMessage = React.useCallback( + (messageId: string) => { + const descendantIds: string[] = []; + const pendingIds = [...(directReplyIdsByParentId.get(messageId) ?? [])]; + + while (pendingIds.length > 0) { + const currentId = pendingIds.pop(); + if (!currentId) continue; + + descendantIds.push(currentId); + pendingIds.push(...(directReplyIdsByParentId.get(currentId) ?? [])); + } + + return descendantIds; + }, + [directReplyIdsByParentId], + ); const threadPanelData = React.useMemo( () => buildThreadPanelData( @@ -309,6 +326,7 @@ export function ChannelScreen({ editTargetId, expandedThreadReplyIds, getFirstReplyIdForMessage, + getReplyDescendantIdsForMessage, openThreadHeadId, sendMessageMutation, setExpandedThreadReplyIds, diff --git a/desktop/src/features/channels/useChannelPaneHandlers.ts b/desktop/src/features/channels/useChannelPaneHandlers.ts index 98751c6362..f1adf9eef2 100644 --- a/desktop/src/features/channels/useChannelPaneHandlers.ts +++ b/desktop/src/features/channels/useChannelPaneHandlers.ts @@ -21,6 +21,7 @@ export function useChannelPaneHandlers({ editTargetId, expandedThreadReplyIds, getFirstReplyIdForMessage, + getReplyDescendantIdsForMessage, openThreadHeadId, sendMessageMutation, setExpandedThreadReplyIds, @@ -36,6 +37,7 @@ export function useChannelPaneHandlers({ editTargetId: string | null; expandedThreadReplyIds: ReadonlySet; getFirstReplyIdForMessage: (messageId: string) => string | null; + getReplyDescendantIdsForMessage: (messageId: string) => string[]; openThreadHeadId: string | null; sendMessageMutation: ReturnType; setExpandedThreadReplyIds: React.Dispatch>>; @@ -158,21 +160,33 @@ export function useChannelPaneHandlers({ const handleExpandThreadReplies = React.useCallback( (message: { id: string }) => { - const firstReplyId = getFirstReplyIdForMessage(message.id); - if (!expandedThreadReplyIdsRef.current.has(message.id)) { + if (expandedThreadReplyIdsRef.current.has(message.id)) { + const descendantIds = getReplyDescendantIdsForMessage(message.id); setExpandedThreadReplyIds((current) => { const next = new Set(current); - next.add(message.id); + next.delete(message.id); + for (const descendantId of descendantIds) { + next.delete(descendantId); + } return next; }); + return; } + const firstReplyId = getFirstReplyIdForMessage(message.id); + setExpandedThreadReplyIds((current) => { + const next = new Set(current); + next.add(message.id); + return next; + }); + if (firstReplyId) { setThreadScrollTargetId(firstReplyId); } }, [ getFirstReplyIdForMessage, + getReplyDescendantIdsForMessage, setExpandedThreadReplyIds, setThreadScrollTargetId, ], diff --git a/desktop/src/features/messages/ui/MessageThreadPanel.tsx b/desktop/src/features/messages/ui/MessageThreadPanel.tsx index e592bbfee7..a4fb0eb0b1 100644 --- a/desktop/src/features/messages/ui/MessageThreadPanel.tsx +++ b/desktop/src/features/messages/ui/MessageThreadPanel.tsx @@ -220,10 +220,6 @@ export function MessageThreadPanel({ {threadReplies.length > 0 ? (
{threadReplies.map((entry, index) => { - const nextDepth = - threadReplies[index + 1]?.message.depth ?? -1; - const isExpanded = nextDepth > entry.message.depth; - return (
- {entry.summary && !isExpanded ? ( + {entry.summary ? ( void; summary: TimelineThreadSummary; }) { const visibleDepth = Math.min(Math.max(depth, 0), 6); - const messageTextOffsetPx = 50; + const messageTextOffsetPx = layoutVariant === "thread-reply" ? 8 : 50; const marginLeftPx = visibleDepth * 28 + messageTextOffsetPx; const depthGuideOffsets = Array.from( { length: visibleDepth }, diff --git a/desktop/src/features/messages/ui/TimelineMessageList.tsx b/desktop/src/features/messages/ui/TimelineMessageList.tsx index 09ae20d782..043c950112 100644 --- a/desktop/src/features/messages/ui/TimelineMessageList.tsx +++ b/desktop/src/features/messages/ui/TimelineMessageList.tsx @@ -104,6 +104,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({ profiles={profiles} />