fix: preset saving and global pipeline selection

- Use pipelineStore.globalConfig instead of DEFAULT_PIPELINE_CONFIG for
  image processing, so global preset changes affect images
- Fix preset saving from modal to save actual edited config, not global
- Add local preset selection tracking in PipelinePanel for modal context
- Prevent modal config reset when store changes using untrack()
- Derive editingImage from store to always get latest data
- Fix ImagePreview to compare against lastProcessedConfig, not initial
- Preserve custom image overrides when global preset changes
- Clean up unused store functions (updateConfig, updateStep, isModified,
  getEffectiveConfig)
- Use clonePipelineConfig consistently instead of JSON.parse/stringify

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 08:08:44 -04:00
parent e37dd6f25d
commit d9d10cd6fb
6 changed files with 89 additions and 73 deletions

View File

@@ -32,7 +32,12 @@
let showCustomModal = $state(false);
let showEditModal = $state(false);
let editingImage = $state<ImageEntry | null>(null);
let editingImageId = $state<string | null>(null);
// Derive the editing image from the store to always get the latest data
const editingImage = $derived(
editingImageId ? imagesStore.images.find((img) => img.id === editingImageId) ?? null : null
);
// View mode for image comparison
let viewMode = $state<ViewMode>('compare');
@@ -50,16 +55,17 @@
}
});
// Watch for pipeline preset changes and reprocess
// Watch for pipeline preset changes and reprocess images without custom overrides
$effect(() => {
const currentPresetId = pipelineStore.selectedPresetId;
if (currentPresetId !== previousPresetId && imagesStore.hasImages) {
previousPresetId = currentPresetId;
// Clear all image overrides and reprocess with new global config
// Only reprocess images that don't have custom overrides
for (const img of imagesStore.images) {
imagesStore.setPipelineOverride(img.id, null);
if (!img.pipelineOverride) {
imagesStore.reprocessImage(img.id, deviceStore.selected);
}
}
imagesStore.reprocessAll(deviceStore.selected);
}
});
@@ -77,23 +83,20 @@
}
function handleEditImage(id: string): void {
const image = imagesStore.images.find((img) => img.id === id);
if (image) {
editingImage = image;
showEditModal = true;
}
editingImageId = id;
showEditModal = true;
}
function closeEditModal(): void {
showEditModal = false;
editingImage = null;
editingImageId = null;
}
function handleApplyPipeline(imageId: string, config: PipelineConfig, processedDataUrl: string | null): void {
function handleApplyPipeline(imageId: string, config: PipelineConfig, processedDataUrl: string | null, processedBlob: Blob | null): void {
imagesStore.setPipelineOverride(imageId, config);
if (processedDataUrl) {
if (processedDataUrl && processedBlob) {
// Use the already-processed preview directly
imagesStore.updateImage(imageId, { processedDataUrl });
imagesStore.updateImage(imageId, { processedDataUrl, processedBlob });
} else {
// Fallback: reprocess if no preview available
imagesStore.reprocessImage(imageId, deviceStore.selected);