fix: preserve manual detail cutlines

This commit is contained in:
Your Name 2026-06-01 15:06:17 +08:00
parent a3c291a1e0
commit 00ae2d4e59

View File

@ -197,6 +197,12 @@ export function AgentDetailReferenceStitchDialog({
const [warningText, setWarningText] = useState<string | null>(null); const [warningText, setWarningText] = useState<string | null>(null);
const [previewImageLoadFailed, setPreviewImageLoadFailed] = useState(false); const [previewImageLoadFailed, setPreviewImageLoadFailed] = useState(false);
const [passthroughSegmentIndexes, setPassthroughSegmentIndexes] = useState<number[]>([]); const [passthroughSegmentIndexes, setPassthroughSegmentIndexes] = useState<number[]>([]);
const hasManualCutLineChangesRef = useRef(false);
const onPreparedRef = useRef(onPrepared);
useEffect(() => {
onPreparedRef.current = onPrepared;
}, [onPrepared]);
const validCards = useMemo( const validCards = useMemo(
() => () =>
@ -210,8 +216,8 @@ export function AgentDetailReferenceStitchDialog({
() => () =>
validCards validCards
.map( .map(
(card) => (card, index) =>
`${card.id}::${String(card.imageUrl || "").trim()}::${String(card.previewUrl || "").trim()}::${card.width || ""}x${card.height || ""}` `${card.id}::${String(card.imageUrl || "").trim()}::${card.sortOrder ?? index}`
) )
.join("|"), .join("|"),
[validCards] [validCards]
@ -265,12 +271,14 @@ export function AgentDetailReferenceStitchDialog({
setWarningText(null); setWarningText(null);
setPreviewImageLoadFailed(false); setPreviewImageLoadFailed(false);
setPassthroughSegmentIndexes([]); setPassthroughSegmentIndexes([]);
hasManualCutLineChangesRef.current = false;
return; return;
} }
if (setupCards.length === 0) { if (setupCards.length === 0) {
setSnapshot(null); setSnapshot(null);
setCutLines([]); setCutLines([]);
hasManualCutLineChangesRef.current = false;
setIsLoading(false); setIsLoading(false);
setIsPreparing(false); setIsPreparing(false);
setErrorText(`当前没有可拼合的${sourceLabel}`); setErrorText(`当前没有可拼合的${sourceLabel}`);
@ -282,6 +290,7 @@ export function AgentDetailReferenceStitchDialog({
setSnapshot(optimisticSnapshot); setSnapshot(optimisticSnapshot);
setCutLines(optimisticSnapshot.defaultCutLines); setCutLines(optimisticSnapshot.defaultCutLines);
hasManualCutLineChangesRef.current = false;
setPassthroughSegmentIndexes([]); setPassthroughSegmentIndexes([]);
setErrorText(null); setErrorText(null);
setWarningText(null); setWarningText(null);
@ -341,12 +350,15 @@ export function AgentDetailReferenceStitchDialog({
}; };
setSnapshot(preciseSnapshot); setSnapshot(preciseSnapshot);
setPreviewImageLoadFailed(!previewUrl); setPreviewImageLoadFailed(!previewUrl);
setCutLines((current) => setCutLines((current) => {
areCutLinesEqual(current, optimisticSnapshot.defaultCutLines) if (hasManualCutLineChangesRef.current) {
return scaleCutLines(current, optimisticSnapshot.height, height);
}
return areCutLinesEqual(current, optimisticSnapshot.defaultCutLines)
? defaultCutLines ? defaultCutLines
: scaleCutLines(current, optimisticSnapshot.height, height) : scaleCutLines(current, optimisticSnapshot.height, height);
); });
if (onPrepared) { if (onPreparedRef.current) {
const dimensionByCardId = new Map( const dimensionByCardId = new Map(
sourceSegments.map((segment) => [ sourceSegments.map((segment) => [
segment.card.id, segment.card.id,
@ -357,7 +369,7 @@ export function AgentDetailReferenceStitchDialog({
}, },
]) ])
); );
onPrepared( onPreparedRef.current(
setupCards.map((card, index) => { setupCards.map((card, index) => {
const dimensions = dimensionByCardId.get(card.id); const dimensions = dimensionByCardId.get(card.id);
return { return {
@ -394,7 +406,7 @@ export function AgentDetailReferenceStitchDialog({
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [onPrepared, open, setupCards, sourceLabel]); }, [open, setupCards, sourceLabel]);
useEffect(() => { useEffect(() => {
const validIndexes = new Set(sliceSegments.map((segment) => segment.index)); const validIndexes = new Set(sliceSegments.map((segment) => segment.index));
@ -532,10 +544,12 @@ export function AgentDetailReferenceStitchDialog({
const handleResetCutLines = useCallback(() => { const handleResetCutLines = useCallback(() => {
if (!snapshot) return; if (!snapshot) return;
hasManualCutLineChangesRef.current = false;
setCutLines(snapshot.defaultCutLines); setCutLines(snapshot.defaultCutLines);
}, [snapshot]); }, [snapshot]);
const handleClearCutLines = useCallback(() => { const handleClearCutLines = useCallback(() => {
hasManualCutLineChangesRef.current = true;
setCutLines([]); setCutLines([]);
setDraggingLineIndex(null); setDraggingLineIndex(null);
setIsAddingCutLine(false); setIsAddingCutLine(false);
@ -543,6 +557,7 @@ export function AgentDetailReferenceStitchDialog({
}, []); }, []);
const handleRemoveCutLine = useCallback((index: number) => { const handleRemoveCutLine = useCallback((index: number) => {
hasManualCutLineChangesRef.current = true;
setCutLines((current) => current.filter((_, currentIndex) => currentIndex !== index)); setCutLines((current) => current.filter((_, currentIndex) => currentIndex !== index));
}, []); }, []);
@ -573,6 +588,7 @@ export function AgentDetailReferenceStitchDialog({
toast.error("当前位置无法添加切线,请换一个位置"); toast.error("当前位置无法添加切线,请换一个位置");
return; return;
} }
hasManualCutLineChangesRef.current = true;
setCutLines((current) => [...current, Math.round(nextY)].sort((left, right) => left - right)); setCutLines((current) => [...current, Math.round(nextY)].sort((left, right) => left - right));
setIsAddingCutLine(false); setIsAddingCutLine(false);
setPreviewCutLineY(null); setPreviewCutLineY(null);
@ -589,6 +605,7 @@ export function AgentDetailReferenceStitchDialog({
} catch { } catch {
// Older browsers may not support pointer capture for this target. // Older browsers may not support pointer capture for this target.
} }
hasManualCutLineChangesRef.current = true;
setDraggingLineIndex(index); setDraggingLineIndex(index);
}, },
[] []