refactor(desktop): split aux-pane assemblies out of ChannelPane

Rebasing onto current main tripped the repository file-size ratchet:
main's own growth left ChannelPane.tsx at 1011 lines (frozen) and
ChannelScreen.tsx at 1010, so the viewer's pane wiring no longer fits
in-file. Extract the agent-session and markdown-doc pane assemblies into
AgentSessionAuxiliaryPanel and MarkdownDocAuxiliaryPanel (following the
ChannelManagementAuxiliaryPanel pattern), leaving both files under their
caps. No behavior change.

Signed-off-by: Riley Crane <rileycrane@squareup.com>
Co-authored-by: Fizz <d4ec90109b43092b0ec94cf136850915a3732a29ab3089a1dec43d2ed43dd6eb@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Riley Crane
2026-08-24 13:58:19 -07:00
parent 34c9f56c0b
commit c3b1721810
4 changed files with 143 additions and 64 deletions

View File

@@ -0,0 +1,72 @@
import { AgentSessionThreadPanel } from "@/features/channels/ui/AgentSessionThreadPanel";
import * as agentSessionSelection from "@/features/channels/ui/agentSessionSelection";
import type { ChannelPaneProps } from "@/features/channels/ui/ChannelPane.types";
type AgentSessionAuxiliaryPanelProps = Pick<
ChannelPaneProps,
"openAgentSessionChannelId" | "profiles"
> & {
activeChannel: NonNullable<ChannelPaneProps["activeChannel"]>;
// ChannelPane defaults this prop, so it is always defined at this call site.
activityAgents: NonNullable<ChannelPaneProps["activityAgents"]>;
isSinglePanelView: boolean;
onBack: ChannelPaneProps["onBackFromAgentSession"];
onClose: ChannelPaneProps["onCloseAgentSession"];
selectedAgent: NonNullable<
ReturnType<typeof agentSessionSelection.resolveSelectedAgentSession>
>;
useSplitAuxiliaryPane: boolean;
widthPx: number;
};
/**
* Assembles the agent-session auxiliary pane for ChannelPane's pane chain.
* Split out of ChannelPane.tsx to keep it under the per-file line cap.
*/
export function AgentSessionAuxiliaryPanel({
activeChannel,
activityAgents,
isSinglePanelView,
onBack,
onClose,
openAgentSessionChannelId,
profiles,
selectedAgent,
useSplitAuxiliaryPane,
widthPx,
}: AgentSessionAuxiliaryPanelProps) {
// When the panel was opened from a different channel than the currently
// active one, re-scope it to the active channel so that both the
// content/header AND channel-backed actions (e.g. Stop current turn)
// operate on the same channel object.
const effectiveAgentSessionChannelId =
openAgentSessionChannelId && activeChannel.id !== openAgentSessionChannelId
? activeChannel.id
: openAgentSessionChannelId;
return (
<AgentSessionThreadPanel
agent={selectedAgent}
canInterruptTurn={selectedAgent.canInterruptTurn}
channel={
effectiveAgentSessionChannelId
? effectiveAgentSessionChannelId === activeChannel.id
? activeChannel
: null
: agentSessionSelection.isAgentInActivityList({
activityAgents,
selectedAgent,
})
? activeChannel
: null
}
channelId={effectiveAgentSessionChannelId}
isSinglePanelView={useSplitAuxiliaryPane ? false : isSinglePanelView}
layout={useSplitAuxiliaryPane ? "split" : "standalone"}
transparentChrome={useSplitAuxiliaryPane}
profiles={profiles}
onBack={onBack}
onClose={onClose}
widthPx={widthPx}
/>
);
}

View File

@@ -28,9 +28,9 @@ import { buildVideoReviewPresentationByMessageId } from "@/features/messages/lib
import { isThreadReply } from "@/features/messages/lib/threading";
import { useComposerHeightPadding } from "@/features/messages/ui/useComposerHeightPadding";
import { UserProfilePanel } from "@/features/profile/ui/UserProfilePanel";
import { AgentSessionThreadPanel } from "@/features/channels/ui/AgentSessionThreadPanel";
import { AgentSessionAuxiliaryPanel } from "@/features/channels/ui/AgentSessionAuxiliaryPanel";
import { ChannelManagementAuxiliaryPanel } from "@/features/channels/ui/ChannelManagementAuxiliaryPanel";
import { MarkdownDocPanel } from "@/features/channels/ui/MarkdownDocPanel";
import { MarkdownDocAuxiliaryPanel } from "@/features/channels/ui/MarkdownDocAuxiliaryPanel";
import { RightAuxiliaryPane } from "@/features/channels/ui/RightAuxiliaryPane";
import { ThreadViewModeToggle } from "@/features/channels/ui/ThreadViewModeToggle";
import { FocusThreadDrawer } from "@/features/channels/ui/FocusThreadDrawer";
@@ -948,42 +948,21 @@ export const ChannelPane = React.memo(function ChannelPane({
return wrapThreadPanel(panel);
})()
) : activeChannel && selectedAgent ? (
(() => {
const effectiveAgentSessionChannelId =
openAgentSessionChannelId &&
activeChannel.id !== openAgentSessionChannelId
? activeChannelId
: openAgentSessionChannelId;
const panel = (
<AgentSessionThreadPanel
agent={selectedAgent}
canInterruptTurn={selectedAgent.canInterruptTurn}
channel={
effectiveAgentSessionChannelId
? effectiveAgentSessionChannelId === activeChannel.id
? activeChannel
: null
: agentSessionSelection.isAgentInActivityList({
activityAgents,
selectedAgent,
})
? activeChannel
: null
}
channelId={effectiveAgentSessionChannelId}
isSinglePanelView={
useSplitAuxiliaryPane ? false : isSinglePanelView
}
layout={useSplitAuxiliaryPane ? "split" : "standalone"}
transparentChrome={useSplitAuxiliaryPane}
profiles={profiles}
onBack={onBackFromAgentSession}
onClose={onCloseAgentSession}
widthPx={threadPanelWidthPx}
/>
);
return wrapAux(panel, "agent-session-thread-panel");
})()
wrapAux(
<AgentSessionAuxiliaryPanel
activeChannel={activeChannel}
activityAgents={activityAgents}
isSinglePanelView={isSinglePanelView}
onBack={onBackFromAgentSession}
onClose={onCloseAgentSession}
openAgentSessionChannelId={openAgentSessionChannelId}
profiles={profiles}
selectedAgent={selectedAgent}
useSplitAuxiliaryPane={useSplitAuxiliaryPane}
widthPx={threadPanelWidthPx}
/>,
"agent-session-thread-panel",
)
) : profilePanelPubkey ? (
(() => {
const panel = (
@@ -1009,29 +988,16 @@ export const ChannelPane = React.memo(function ChannelPane({
return wrapAux(panel, "user-profile-panel");
})()
) : openMarkdownDoc && onCloseMarkdownDoc ? (
(() => {
// Lowest-priority pane: a higher-priority pane opened afterwards
// (thread, activity, profile) shows immediately, and the document
// reappears when it closes. Opening a document clears competitors
// in the screen-level handler, so it is never dead on arrival.
const panel = (
// Keyed by URL so opening a different document resets the
// Preview/Code toggle instead of inheriting the previous doc's.
<MarkdownDocPanel
key={openMarkdownDoc.url}
filename={openMarkdownDoc.filename}
isSinglePanelView={
useSplitAuxiliaryPane ? false : isSinglePanelView
}
layout={useSplitAuxiliaryPane ? "split" : "standalone"}
onClose={onCloseMarkdownDoc}
transparentChrome={useSplitAuxiliaryPane}
url={openMarkdownDoc.url}
widthPx={threadPanelWidthPx}
/>
);
return wrapAux(panel, "markdown-doc-panel");
})()
wrapAux(
<MarkdownDocAuxiliaryPanel
doc={openMarkdownDoc}
isSinglePanelView={isSinglePanelView}
onClose={onCloseMarkdownDoc}
useSplitAuxiliaryPane={useSplitAuxiliaryPane}
widthPx={threadPanelWidthPx}
/>,
"markdown-doc-panel",
)
) : null}
</AnimatePresence>
</div>

View File

@@ -833,9 +833,7 @@ export function ChannelScreen({
searchTarget,
)
) : (
// Scoped to the pane that hosts the markdown-doc auxiliary
// panel — the forum branch has no host, so its FileCards keep
// download behavior instead of a dead open-in-viewer click.
// Forum has no doc-panel host; its FileCards keep downloading.
<MarkdownDocViewerProvider value={handleOpenMarkdownDoc}>
<React.Suspense
fallback={

View File

@@ -0,0 +1,43 @@
import { MarkdownDocPanel } from "@/features/channels/ui/MarkdownDocPanel";
import type { MarkdownDocTarget } from "@/shared/ui/markdown/markdownDocViewerContext";
type MarkdownDocAuxiliaryPanelProps = {
doc: MarkdownDocTarget;
isSinglePanelView: boolean;
onClose: () => void;
useSplitAuxiliaryPane: boolean;
widthPx: number;
};
/**
* Assembles the markdown-document auxiliary pane for ChannelPane's pane
* chain. Split out of ChannelPane.tsx to keep it under the per-file line
* cap.
*
* This is the chain's lowest-priority pane: a higher-priority pane opened
* afterwards (thread, activity, profile) shows immediately, and the document
* reappears when it closes. Opening a document clears competitors in the
* screen-level handler, so it is never dead on arrival.
*/
export function MarkdownDocAuxiliaryPanel({
doc,
isSinglePanelView,
onClose,
useSplitAuxiliaryPane,
widthPx,
}: MarkdownDocAuxiliaryPanelProps) {
return (
// Keyed by URL so opening a different document resets the Preview/Code
// toggle instead of inheriting the previous document's.
<MarkdownDocPanel
key={doc.url}
filename={doc.filename}
isSinglePanelView={useSplitAuxiliaryPane ? false : isSinglePanelView}
layout={useSplitAuxiliaryPane ? "split" : "standalone"}
onClose={onClose}
transparentChrome={useSplitAuxiliaryPane}
url={doc.url}
widthPx={widthPx}
/>
);
}