feat: refine candidate handling in generation commands and update UI interactions
This commit is contained in:
@@ -28,7 +28,6 @@ export type GenerationApplyCandidateAsLayerPayload = {
|
||||
candidateId: string;
|
||||
assetId: AssetId;
|
||||
layerId: LayerId;
|
||||
variant?: boolean;
|
||||
};
|
||||
|
||||
export type GenerationReplaceCandidatePixelsPayload = {
|
||||
@@ -105,18 +104,13 @@ export const generationRemoveCandidateCommand: Command<GenerationRemoveCandidate
|
||||
name: "Remove generation candidate",
|
||||
history: { mode: "ignore" },
|
||||
execute({ state }, payload) {
|
||||
const candidates = state.editor.generation.candidates.filter((candidate) => candidate.id !== payload.candidateId);
|
||||
if (candidates.length === state.editor.generation.candidates.length) return state;
|
||||
const selectedCandidateId = state.editor.generation.selectedCandidateId === payload.candidateId ? candidates[0]?.id : state.editor.generation.selectedCandidateId;
|
||||
const generation = removeGenerationCandidate(state.editor.generation, payload.candidateId);
|
||||
if (generation === state.editor.generation) return state;
|
||||
return {
|
||||
...state,
|
||||
editor: {
|
||||
...state.editor,
|
||||
generation: {
|
||||
candidates,
|
||||
selectedCandidateId,
|
||||
compareMode: candidates.length > 0 ? state.editor.generation.compareMode : "result",
|
||||
},
|
||||
generation,
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -149,16 +143,16 @@ export const generationApplyCandidateAsLayerCommand: Command<GenerationApplyCand
|
||||
|
||||
const asset: Asset = {
|
||||
id: payload.assetId,
|
||||
name: payload.variant ? `${candidate.placement.layerName} variant` : candidate.placement.layerName,
|
||||
name: candidate.placement.layerName,
|
||||
mimeType: candidate.mimeType,
|
||||
source: candidate.source,
|
||||
intrinsicSize: { ...candidate.intrinsicSize },
|
||||
provenance: generationProvenance(candidate, payload.variant ? "variant-layer" : "layer"),
|
||||
provenance: generationProvenance(candidate, "layer"),
|
||||
};
|
||||
const layer: ImageLayer = {
|
||||
id: payload.layerId,
|
||||
type: "image",
|
||||
name: payload.variant ? `${candidate.placement.layerName} variant` : candidate.placement.layerName,
|
||||
name: candidate.placement.layerName,
|
||||
visible: true,
|
||||
locked: false,
|
||||
opacity: 1,
|
||||
@@ -175,7 +169,7 @@ export const generationApplyCandidateAsLayerCommand: Command<GenerationApplyCand
|
||||
document: insertLayerAtTop({ ...state.document, assets: [...state.document.assets, asset] }, candidate.placement.artboardId, layer),
|
||||
editor: {
|
||||
...state.editor,
|
||||
generation: clearCommittedGenerationPreview(state.editor.generation),
|
||||
generation: removeGenerationCandidate(state.editor.generation, candidate.id),
|
||||
selection: { artboardId: candidate.placement.artboardId, layerIds: [layer.id] },
|
||||
},
|
||||
};
|
||||
@@ -209,7 +203,7 @@ export const generationReplaceCandidatePixelsCommand: Command<GenerationReplaceC
|
||||
},
|
||||
editor: {
|
||||
...state.editor,
|
||||
generation: clearCommittedGenerationPreview(state.editor.generation),
|
||||
generation: removeGenerationCandidate(state.editor.generation, candidate.id),
|
||||
selection: { artboardId: targetLayerLocation.artboardId, layerIds: [candidate.inpaint.targetLayerId] },
|
||||
},
|
||||
};
|
||||
@@ -257,9 +251,23 @@ function findLayerInTree(layers: readonly Layer[], layerId: LayerId): Layer | un
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function clearCommittedGenerationPreview(generation: GenerationState): GenerationState {
|
||||
if (generation.candidates.length === 0 && !generation.selectedCandidateId && generation.compareMode === "result") return generation;
|
||||
return { candidates: [], selectedCandidateId: undefined, compareMode: "result" };
|
||||
function removeGenerationCandidate(generation: GenerationState, candidateId: string): GenerationState {
|
||||
const removedIndex = generation.candidates.findIndex((candidate) => candidate.id === candidateId);
|
||||
if (removedIndex < 0) return generation;
|
||||
|
||||
const candidates = generation.candidates.filter((candidate) => candidate.id !== candidateId);
|
||||
const selectionStillExists = generation.selectedCandidateId
|
||||
? candidates.some((candidate) => candidate.id === generation.selectedCandidateId)
|
||||
: false;
|
||||
const selectedCandidateId = selectionStillExists
|
||||
? generation.selectedCandidateId
|
||||
: candidates[Math.min(removedIndex, candidates.length - 1)]?.id;
|
||||
|
||||
return {
|
||||
candidates,
|
||||
selectedCandidateId,
|
||||
compareMode: candidates.length > 0 ? generation.compareMode : "result",
|
||||
};
|
||||
}
|
||||
|
||||
function generationProvenance(candidate: GenerationCandidate, acceptance: GeneratedAssetAcceptance): AssetGenerationProvenance {
|
||||
|
||||
Reference in New Issue
Block a user