perf(*): 创作工作台 - 优化首页按需加载与画布交互并修复历史迁移冲突
This commit is contained in:
1 parent
ca7ad1f9b2
commit
711d1b79eb
107 files changed
+3025
-1089
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useMemo, useRef, useState, type CSSProperties, type KeyboardEvent as ReactKeyboardEvent, type PointerEvent as ReactPointerEvent, type ReactNode } from "react";
|
||||
import { ArrowUp, AtSign, Boxes, ChevronDown, FileText, ImageIcon, ImagePlus, LoaderCircle, Maximize2, Music2, Pencil, SlidersHorizontal, UserRound, Video, WandSparkles, X } from "lucide-react";
|
||||
import { useEffect, useMemo, useRef, useState, type CSSProperties, type KeyboardEvent as ReactKeyboardEvent, type PointerEvent as ReactPointerEvent } from "react";
|
||||
import { ArrowUp, AtSign, ChevronDown, FileText, ImageIcon, ImagePlus, LoaderCircle, Maximize2, Music2, Pencil, SlidersHorizontal, UserRound, Video, WandSparkles, X } from "lucide-react";
|
||||
import { Button, Image as AntImage, InputNumber, Modal, Tooltip } from "antd";
|
||||
|
||||
import { ModelPicker } from "@/components/model-picker";
|
||||
@@ -244,32 +244,29 @@ export function CanvasNodePromptPanel({ node, isRunning, onPromptChange, onConfi
|
||||
<span className="grid size-3.5 shrink-0 place-items-center" style={{ color: monochromeAccent }}>
|
||||
<GenerationModeIcon mode={mode} />
|
||||
</span>
|
||||
<span className="truncate text-[var(--fs-tiny)] font-medium">{modeDisplayName(mode)}创作</span>
|
||||
<span className="truncate text-[var(--fs-tiny)] font-medium">{modeDisplayName(mode)}生成</span>
|
||||
</div>
|
||||
)}
|
||||
{!simpleMode ? <CanvasPresetPicker mode={mode} skillReferences={skillReferences} open={expanded ? expandedPresetOpen : presetOpen} onOpenChange={expanded ? setExpandedPresetOpen : setPresetOpen} onSelect={applyPreset} dense /> : null}
|
||||
<div className="ml-auto flex shrink-0 items-center justify-end gap-1">
|
||||
{!simpleMode ? <CanvasPresetPicker mode={mode} skillReferences={skillReferences} open={expanded ? expandedPresetOpen : presetOpen} onOpenChange={expanded ? setExpandedPresetOpen : setPresetOpen} onSelect={applyPreset} dense appearance="quiet" /> : null}
|
||||
{canOptimizePrompt ? (
|
||||
<Tooltip title="用 AI 优化提示词">
|
||||
<Tooltip title="用 AI 润色提示词">
|
||||
<button
|
||||
type="button"
|
||||
className="canvas-node-composer-icon-button inline-flex h-6 shrink-0 items-center gap-1 rounded-md px-1.5 transition-[background-color,filter] hover:brightness-125 focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-1 motion-reduce:hover:translate-y-0"
|
||||
style={{ background: controlSurface, color: theme.node.text, outlineColor: monochromeAccent }}
|
||||
className="canvas-node-composer-header-action inline-flex h-6 shrink-0 items-center gap-1 rounded-md px-1.5"
|
||||
onClick={() => setPromptOptimizerOpen(true)}
|
||||
aria-label="优化提示词"
|
||||
aria-label="润色提示词"
|
||||
>
|
||||
<WandSparkles className="size-3" />
|
||||
<span className="hidden text-[var(--fs-micro)] font-medium sm:inline">优化</span>
|
||||
<span className="text-[var(--fs-tiny)] font-medium">润色</span>
|
||||
</button>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
<div className="ml-auto flex shrink-0 items-center justify-end gap-1">
|
||||
{activeReferenceCount ? <ComposerPill theme={theme} icon={<Boxes className="size-2.5" />} label={`参考 ${activeReferenceCount}`} /> : null}
|
||||
{!expanded && canExpandPrompt ? (
|
||||
<Tooltip title="放大编辑">
|
||||
<button
|
||||
type="button"
|
||||
className="canvas-node-composer-icon-button grid size-6 shrink-0 place-items-center rounded-md transition-[background-color,filter] hover:brightness-125 focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-1 motion-reduce:hover:translate-y-0"
|
||||
style={{ background: controlSurface, color: theme.node.text, outlineColor: monochromeAccent }}
|
||||
className="canvas-node-composer-header-action grid size-6 shrink-0 place-items-center rounded-md"
|
||||
onClick={() => setExpandedPromptOpen(true)}
|
||||
aria-label="放大编辑提示词"
|
||||
>
|
||||
@@ -281,8 +278,7 @@ export function CanvasNodePromptPanel({ node, isRunning, onPromptChange, onConfi
|
||||
<Tooltip title="关闭">
|
||||
<button
|
||||
type="button"
|
||||
className="canvas-node-composer-icon-button grid size-6 shrink-0 place-items-center rounded-md transition-[background-color,filter] hover:brightness-125 focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-1 motion-reduce:hover:translate-y-0"
|
||||
style={{ background: controlSurface, color: theme.node.text, outlineColor: monochromeAccent }}
|
||||
className="canvas-node-composer-header-action grid size-6 shrink-0 place-items-center rounded-md"
|
||||
onClick={onClose}
|
||||
aria-label="关闭创作面板"
|
||||
>
|
||||
@@ -508,15 +504,6 @@ export function CanvasNodePromptPanel({ node, isRunning, onPromptChange, onConfi
|
||||
);
|
||||
}
|
||||
|
||||
function ComposerPill({ theme, icon, label }: { theme: CanvasTheme; icon: ReactNode; label: string }) {
|
||||
return (
|
||||
<span className="inline-flex h-6 shrink-0 items-center gap-1 rounded-[var(--r-sm)] px-1.5 text-[var(--fs-micro)] font-medium" style={{ background: "var(--canvas-composer-control-surface)", color: theme.node.activeStroke }}>
|
||||
{icon}
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function GenerationModeIcon({ mode }: { mode: CanvasNodeGenerationMode }) {
|
||||
if (mode === "image") return <ImagePlus className="size-3" />;
|
||||
if (mode === "video") return <Video className="size-3" />;
|
||||
@@ -539,6 +526,9 @@ function ConnectedReferenceShelf({ references, theme, onInsert, onRemove }: { re
|
||||
return (
|
||||
<>
|
||||
<div className="canvas-node-composer-references thin-scrollbar" role="group" aria-label="已连接素材">
|
||||
<span className="canvas-node-composer-reference-heading">
|
||||
{activeReferences.every((reference) => reference.kind === "image" || reference.kind === "character") ? "参考图" : "参考素材"} · {activeReferences.length}
|
||||
</span>
|
||||
{activeReferences.map((reference) => {
|
||||
const canPreview = (reference.kind === "image" || reference.kind === "character") && Boolean(reference.previewUrl);
|
||||
return (
|
||||
|
||||
Reference in new issue
Block a user