mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
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:
@@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user