fix: merge detail edit scale modes
This commit is contained in:
parent
df0daf4d27
commit
9bc887eee1
@ -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"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user