feat(ai-writing): 进入写作后自动收起研究模板侧栏
把侧栏+内容区抽成 Provider 内组件 AIWritingBody,读 useAIWriting 状态: status==='idle' && 非历史模式才显示研究模板侧栏;开始写作/查看历史后收起,写作区铺满。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
380407ae2f
commit
ab21911696
1 file changed
+81
-60
@@ -217,6 +217,81 @@ function AIWritingLayout({ hideAdvancedFields, initialNotebookId, initialDocumen
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写作页主体(侧栏 + 内容区)。放在 Provider 内部,以便读 useAIWriting 状态:
|
||||
* 进入写作(status !== idle 或查看历史)后自动收起左侧研究模板栏,让写作区更宽。
|
||||
*/
|
||||
function AIWritingBody({ hideAdvancedFields, initialNotebookId, initialDocumentIds, studioToken }: { hideAdvancedFields: boolean } & NotebookProps) {
|
||||
const { state } = useAIWriting();
|
||||
const { isHistoryMode } = useAIWritingHistory();
|
||||
|
||||
// 需求 0616 #5:左栏点「笔记本 / 所有空间」→ 在右侧内嵌打开对应页,替换右侧内容
|
||||
// (写作布局不卸载,仅 display:none 隐藏,避免 WritingSetupChat 重挂丢线程)。
|
||||
const [rightView, setRightView] = useState<RightView>(null);
|
||||
const overlayActive = rightView != null;
|
||||
const viewingNotebookId = rightView?.kind === 'notebook' ? rightView.id : null;
|
||||
|
||||
// 进入写作(开始生成 / 查看历史)后收起研究模板侧栏;嵌入态(studioToken)始终不展示。
|
||||
const showSidebar = !studioToken && state.status === 'idle' && !isHistoryMode;
|
||||
|
||||
return (
|
||||
<div className="flex-1 min-h-0 overflow-hidden flex">
|
||||
{/* 需求 0616 #5:课题研究左栏(研究模板 + 笔记本)。进入写作后收起。 */}
|
||||
{showSidebar && (
|
||||
<ResearchSidebar
|
||||
viewingNotebookId={viewingNotebookId}
|
||||
onOpenNotebook={(id) => setRightView({ kind: 'notebook', id })}
|
||||
onOpenAllSpaces={() => setRightView({ kind: 'allSpaces' })}
|
||||
/>
|
||||
)}
|
||||
{/* 右侧:写作布局常驻(仅 display:none 隐藏,避免 WritingSetupChat 重挂丢线程),
|
||||
查看笔记本 / 所有空间时在其上叠加内嵌页。 */}
|
||||
<div className="relative flex-1 min-h-0 overflow-hidden">
|
||||
<div className={cn('absolute inset-0', overlayActive && 'hidden')}>
|
||||
<AIWritingLayout hideAdvancedFields={hideAdvancedFields} initialNotebookId={initialNotebookId} initialDocumentIds={initialDocumentIds} studioToken={studioToken} />
|
||||
</div>
|
||||
{overlayActive && (
|
||||
<div className="absolute inset-0 flex flex-col bg-background">
|
||||
<div className="flex shrink-0 items-center gap-1 border-b border-border px-4 py-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRightView(null)}
|
||||
className="flex items-center gap-1.5 rounded-md px-2 py-1 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
<ArrowLeft className="size-4" />
|
||||
返回写作
|
||||
</button>
|
||||
{rightView.kind === 'notebook' && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRightView({ kind: 'allSpaces' })}
|
||||
className="ml-1 rounded-md px-2 py-1 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
所有空间
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="min-h-0 flex-1 overflow-hidden">
|
||||
{rightView.kind === 'notebook' ? (
|
||||
// 笔记本详情页内部用 ChatBox(useArtifacts) → 需 ChatRuntime 提供 Provider。
|
||||
<ChatRuntime>
|
||||
<StudioNotebookDetailPage key={rightView.id} notebookId={rightView.id} />
|
||||
</ChatRuntime>
|
||||
) : (
|
||||
<div className="h-full overflow-y-auto">
|
||||
<StudioNotebooksPage
|
||||
onOpenNotebook={(id) => setRightView({ kind: 'notebook', id })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AIWritingPage({
|
||||
hideAdvancedFields = false,
|
||||
initialNotebookId,
|
||||
@@ -228,12 +303,6 @@ export default function AIWritingPage({
|
||||
initialDocumentIds?: number[];
|
||||
studioToken?: string;
|
||||
} = {}) {
|
||||
// 需求 0616 #5:左栏点「笔记本 / 所有空间」→ 在右侧内嵌打开对应页,替换右侧内容
|
||||
// (写作布局不卸载,仅 display:none 隐藏,避免 WritingSetupChat 重挂丢线程)。
|
||||
const [rightView, setRightView] = useState<RightView>(null);
|
||||
const overlayActive = rightView != null;
|
||||
const viewingNotebookId = rightView?.kind === 'notebook' ? rightView.id : null;
|
||||
|
||||
return (
|
||||
<CanvasThreadProvider>
|
||||
<CanvasGraphProvider>
|
||||
@@ -247,60 +316,12 @@ export default function AIWritingPage({
|
||||
>
|
||||
<TooltipProvider delayDuration={300}>
|
||||
<div className="h-full flex flex-col overflow-hidden bg-background canvas-writing-bg">
|
||||
<div className="flex-1 min-h-0 overflow-hidden flex">
|
||||
{/* 需求 0616 #5:课题研究左栏(研究模板 + 笔记本)。studio 嵌入态(studioToken)隐藏。 */}
|
||||
{!studioToken && (
|
||||
<ResearchSidebar
|
||||
viewingNotebookId={viewingNotebookId}
|
||||
onOpenNotebook={(id) => setRightView({ kind: 'notebook', id })}
|
||||
onOpenAllSpaces={() => setRightView({ kind: 'allSpaces' })}
|
||||
/>
|
||||
)}
|
||||
{/* 右侧:写作布局常驻(仅 display:none 隐藏,避免 WritingSetupChat 重挂丢线程),
|
||||
查看笔记本 / 所有空间时在其上叠加内嵌页。 */}
|
||||
<div className="relative flex-1 min-h-0 overflow-hidden">
|
||||
<div className={cn('absolute inset-0', overlayActive && 'hidden')}>
|
||||
<AIWritingLayout hideAdvancedFields={hideAdvancedFields} initialNotebookId={initialNotebookId} initialDocumentIds={initialDocumentIds} studioToken={studioToken} />
|
||||
</div>
|
||||
{overlayActive && (
|
||||
<div className="absolute inset-0 flex flex-col bg-background">
|
||||
<div className="flex shrink-0 items-center gap-1 border-b border-border px-4 py-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRightView(null)}
|
||||
className="flex items-center gap-1.5 rounded-md px-2 py-1 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
<ArrowLeft className="size-4" />
|
||||
返回写作
|
||||
</button>
|
||||
{rightView.kind === 'notebook' && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRightView({ kind: 'allSpaces' })}
|
||||
className="ml-1 rounded-md px-2 py-1 text-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
所有空间
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="min-h-0 flex-1 overflow-hidden">
|
||||
{rightView.kind === 'notebook' ? (
|
||||
// 笔记本详情页内部用 ChatBox(useArtifacts) → 需 ChatRuntime 提供 Provider。
|
||||
<ChatRuntime>
|
||||
<StudioNotebookDetailPage key={rightView.id} notebookId={rightView.id} />
|
||||
</ChatRuntime>
|
||||
) : (
|
||||
<div className="h-full overflow-y-auto">
|
||||
<StudioNotebooksPage
|
||||
onOpenNotebook={(id) => setRightView({ kind: 'notebook', id })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<AIWritingBody
|
||||
hideAdvancedFields={hideAdvancedFields}
|
||||
initialNotebookId={initialNotebookId}
|
||||
initialDocumentIds={initialDocumentIds}
|
||||
studioToken={studioToken}
|
||||
/>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
</WritingFormProvider>
|
||||
|
||||
Reference in new issue
Block a user