fix: merge detail edit scale modes

This commit is contained in:
134 2026-06-22 21:47:53 +08:00
parent df0daf4d27
commit 9bc887eee1

View File

@ -910,13 +910,15 @@ function DetailResultLocalEditDialog({
useState<DetailResultLocalEditRegionInteraction | null>(null); useState<DetailResultLocalEditRegionInteraction | null>(null);
const [uploadingRegionId, setUploadingRegionId] = useState<string | null>(null); const [uploadingRegionId, setUploadingRegionId] = useState<string | null>(null);
const [drawingTargetRegionId, setDrawingTargetRegionId] = useState<string | null>(null); const [drawingTargetRegionId, setDrawingTargetRegionId] = useState<string | null>(null);
const [mode, setMode] = useState<DetailResultLocalEditMode>("local_edit");
const dragStartRef = useRef<{ x: number; y: number } | null>(null); const dragStartRef = useRef<{ x: number; y: number } | null>(null);
const editSurfaceRef = useRef<HTMLDivElement | null>(null); const editSurfaceRef = useRef<HTMLDivElement | null>(null);
const mode: DetailResultLocalEditMode =
target?.mode === "scale_adjust" ? "scale_adjust" : "local_edit";
const isScaleAdjustMode = mode === "scale_adjust"; const isScaleAdjustMode = mode === "scale_adjust";
const activePreviewResult = const activePreviewResult =
previewResult && target && previewResult.cardId === target.cardId previewResult &&
target &&
previewResult.cardId === target.cardId &&
previewResult.mode === mode
? previewResult ? previewResult
: null; : null;
const isBusy = submitting || Boolean(uploadingRegionId); const isBusy = submitting || Boolean(uploadingRegionId);
@ -926,6 +928,7 @@ function DetailResultLocalEditDialog({
const isDrawingScaleTarget = isScaleAdjustMode && Boolean(drawingTargetRegionId); const isDrawingScaleTarget = isScaleAdjustMode && Boolean(drawingTargetRegionId);
useEffect(() => { useEffect(() => {
setMode(target?.mode === "scale_adjust" ? "scale_adjust" : "local_edit");
setRegions([]); setRegions([]);
setDraftRect(null); setDraftRect(null);
setActiveRegionId(null); setActiveRegionId(null);
@ -935,6 +938,21 @@ function DetailResultLocalEditDialog({
dragStartRef.current = null; dragStartRef.current = null;
}, [target?.cardId, target?.imageUrl, target?.mode]); }, [target?.cardId, target?.imageUrl, target?.mode]);
const handleModeChange = useCallback(
(nextMode: DetailResultLocalEditMode) => {
if (nextMode === mode || submitting || activePreviewResult) return;
setMode(nextMode);
setRegions([]);
setDraftRect(null);
setActiveRegionId(null);
setRegionInteraction(null);
setUploadingRegionId(null);
setDrawingTargetRegionId(null);
dragStartRef.current = null;
},
[activePreviewResult, mode, submitting]
);
useEffect(() => { useEffect(() => {
if (regions.length === 0) { if (regions.length === 0) {
if (activeRegionId) setActiveRegionId(null); if (activeRegionId) setActiveRegionId(null);
@ -1385,10 +1403,10 @@ function DetailResultLocalEditDialog({
target?.resultModeType === "detail_replacement" target?.resultModeType === "detail_replacement"
? "处理完成后会更新当前套详情结果图。" ? "处理完成后会更新当前套详情结果图。"
: "处理完成后会加入 AI详情结果区。"; : "处理完成后会加入 AI详情结果区。";
const dialogTitle = isScaleAdjustMode ? "比例调整详情图" : "局部编辑详情图"; const dialogTitle = "编辑详情图";
const dialogDescription = isScaleAdjustMode const dialogDescription = isScaleAdjustMode
? "先框选要调整比例的物体,再框选目标大小和位置后生成。" ? "比例模式:先框主体,再框目标大小和位置。"
: "在图片上拖拽框选编辑位置,可添加多个区域,并为每个区域上传专属参考图。"; : "局部模式:框选要修改的位置,填写提示词,并可添加参考图。";
return ( return (
<Dialog open={Boolean(target)} onOpenChange={(open) => (!open ? onClose() : undefined)}> <Dialog open={Boolean(target)} onOpenChange={(open) => (!open ? onClose() : undefined)}>
@ -1398,6 +1416,36 @@ function DetailResultLocalEditDialog({
<DialogDescription className="text-white/50"> <DialogDescription className="text-white/50">
{dialogDescription} {dialogDescription}
</DialogDescription> </DialogDescription>
{!activePreviewResult ? (
<div className="mt-3 inline-flex w-fit items-center gap-1 rounded-xl border border-white/10 bg-white/[0.05] p-1">
<button
className={cn(
"h-8 rounded-lg px-3 text-sm font-semibold transition",
!isScaleAdjustMode
? "bg-white text-black"
: "text-white/55 hover:bg-white/[0.08] hover:text-white"
)}
disabled={submitting}
onClick={() => handleModeChange("local_edit")}
type="button"
>
局部
</button>
<button
className={cn(
"h-8 rounded-lg px-3 text-sm font-semibold transition",
isScaleAdjustMode
? "bg-white text-black"
: "text-white/55 hover:bg-white/[0.08] hover:text-white"
)}
disabled={submitting}
onClick={() => handleModeChange("scale_adjust")}
type="button"
>
比例
</button>
</div>
) : null}
</DialogHeader> </DialogHeader>
<div className="grid gap-4 md:grid-cols-[minmax(0,1fr)_340px]"> <div className="grid gap-4 md:grid-cols-[minmax(0,1fr)_340px]">
<div className="flex min-h-[520px] items-center justify-center overflow-hidden rounded-2xl border border-white/10 bg-black/35 p-3"> <div className="flex min-h-[520px] items-center justify-center overflow-hidden rounded-2xl border border-white/10 bg-black/35 p-3">
@ -1676,20 +1724,20 @@ function DetailResultLocalEditDialog({
<div className="flex min-h-0 flex-col gap-3"> <div className="flex min-h-0 flex-col gap-3">
<div className="rounded-2xl border border-white/10 bg-white/[0.04] p-3 text-sm text-white/58"> <div className="rounded-2xl border border-white/10 bg-white/[0.04] p-3 text-sm text-white/58">
{isScaleAdjustMode {isScaleAdjustMode
? `先拖拽框选主体,再拖拽青色目标框设置大小和位置,最多 ${LOCAL_EDIT_MAX_REGIONS} 个区域。${completionCopy}` ? `先框主体,再框目标大小和位置。最多 ${LOCAL_EDIT_MAX_REGIONS} 个区域。${completionCopy}`
: `拖拽图片添加区域。最多 ${LOCAL_EDIT_MAX_REGIONS} 个区域,每个区域最多 ${LOCAL_EDIT_MAX_REFERENCE_IMAGES_PER_REGION} 张参考图。${completionCopy}`} : `框选要局部修改的位置,填写提示词;可为每个区域添加参考图。最多 ${LOCAL_EDIT_MAX_REGIONS} 个区域。${completionCopy}`}
</div> </div>
{!activePreviewResult && isScaleAdjustMode ? ( {!activePreviewResult && isScaleAdjustMode ? (
<div className="rounded-2xl border border-white/10 bg-white/[0.035] p-3 text-sm text-white/58"> <div className="rounded-2xl border border-white/10 bg-white/[0.035] p-3 text-sm text-white/58">
<div className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-white/38"> <div className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-white/38">
Target Box 目标框
</div> </div>
<div className="leading-6"> <div className="leading-6">
{pendingScaleTargetRegion {pendingScaleTargetRegion
? `继续在左侧为区域 ${pendingScaleTargetRegion.index} 拖拽青色目标框。` ? `请为区域 ${pendingScaleTargetRegion.index} 框选目标大小和位置。`
: regions.length > 0 : regions.length > 0
? "目标框已补齐,可拖动或拉伸青色框继续调整位置和大小。" ? "目标框已补齐,可拖动或拉伸继续调整。"
: "先在左侧拖拽框选要调整比例的主体。"} : "先在左侧框选要调整比例的主体。"}
</div> </div>
</div> </div>
) : null} ) : null}
@ -1706,7 +1754,7 @@ function DetailResultLocalEditDialog({
) : regions.length === 0 ? ( ) : regions.length === 0 ? (
<div className="flex min-h-[260px] items-center justify-center rounded-2xl border border-dashed border-white/12 bg-white/[0.02] px-5 text-center text-sm text-white/38"> <div className="flex min-h-[260px] items-center justify-center rounded-2xl border border-dashed border-white/12 bg-white/[0.02] px-5 text-center text-sm text-white/38">
{isScaleAdjustMode {isScaleAdjustMode
? "在左侧图片上先框主体,再框青色目标大小和位置。" ? "先框主体,再框目标大小和位置。"
: "在左侧图片上拖拽框选后,这里会显示区域提示词和参考图。"} : "在左侧图片上拖拽框选后,这里会显示区域提示词和参考图。"}
</div> </div>
) : isScaleAdjustMode ? null : ( ) : isScaleAdjustMode ? null : (
@ -9701,36 +9749,18 @@ export function AgentGenerationWorkspaceDarkV2({
"inline-flex items-center gap-1.5 disabled:cursor-not-allowed disabled:opacity-45" "inline-flex items-center gap-1.5 disabled:cursor-not-allowed disabled:opacity-45"
)} )}
> >
{isDetailLocalEditBusy && !isDetailScaleAdjusting ? ( {isDetailLocalEditBusy ? (
<Loader2 className="h-3.5 w-3.5 animate-spin" /> <Loader2 className="h-3.5 w-3.5 animate-spin" />
) : ( ) : (
<Wand2 className="h-3.5 w-3.5" /> <Wand2 className="h-3.5 w-3.5" />
)} )}
<span>{isDetailLocalEditing ? "编辑中" : "局部编辑"}</span> <span>
</button> {isDetailLocalEditBusy
<button ? isDetailScaleAdjusting
type="button" ? "调整中"
disabled={isDetailLocalEditBusy} : "编辑中"
onClick={() => { : "局部编辑"}
setDetailLocalEditTarget({ </span>
cardId: card.id,
imageUrl: card.resultUrl!,
mode: "scale_adjust",
title: `${detailReferenceSourceLabel}结果图 ${card.index + 1}`,
resultModeType: "detail_replacement",
});
}}
className={cn(
IMAGE_OVERLAY_ACTION_CLASS,
"inline-flex items-center gap-1.5 disabled:cursor-not-allowed disabled:opacity-45"
)}
>
{isDetailScaleAdjusting ? (
<Loader2 className="h-3.5 w-3.5 animate-spin" />
) : (
<Maximize2 className="h-3.5 w-3.5" />
)}
<span>{isDetailScaleAdjusting ? "调整中" : "比例调整"}</span>
</button> </button>
<button <button
type="button" type="button"
@ -10560,37 +10590,18 @@ export function AgentGenerationWorkspaceDarkV2({
"inline-flex items-center gap-1.5 disabled:cursor-not-allowed disabled:opacity-45" "inline-flex items-center gap-1.5 disabled:cursor-not-allowed disabled:opacity-45"
)} )}
> >
{isDetailLocalEditBusy && !isDetailScaleAdjusting ? ( {isDetailLocalEditBusy ? (
<Loader2 className="h-3.5 w-3.5 animate-spin" /> <Loader2 className="h-3.5 w-3.5 animate-spin" />
) : ( ) : (
<Wand2 className="h-3.5 w-3.5" /> <Wand2 className="h-3.5 w-3.5" />
)} )}
<span>{isDetailLocalEditing ? "编辑中" : "局部编辑"}</span> <span>
</button> {isDetailLocalEditBusy
<button ? isDetailScaleAdjusting
type="button" ? "调整中"
disabled={isDetailLocalEditBusy} : "编辑中"
onClick={(event) => { : "局部编辑"}
event.stopPropagation(); </span>
setDetailLocalEditTarget({
cardId: card.id,
imageUrl: card.url!,
mode: "scale_adjust",
title: `AI详情 ${card.index + 1}`,
resultModeType: "detail_generation",
});
}}
className={cn(
IMAGE_OVERLAY_ACTION_CLASS,
"inline-flex items-center gap-1.5 disabled:cursor-not-allowed disabled:opacity-45"
)}
>
{isDetailScaleAdjusting ? (
<Loader2 className="h-3.5 w-3.5 animate-spin" />
) : (
<Maximize2 className="h-3.5 w-3.5" />
)}
<span>{isDetailScaleAdjusting ? "调整中" : "比例调整"}</span>
</button> </button>
<button <button
type="button" type="button"