Apply the CREATE form's knobs to the photo in realtime

Every row now feeds the open render as it is typed, so a recipe's effect is
visible before it is saved. The draft is not an undo step: SAVE/EXPORT stays the
only thing that commits it, and merely opening the tab changes nothing.
This commit is contained in:
2026-09-17 19:05:59 +07:00
parent a684b178b6
commit 1446e852b1
2 changed files with 25 additions and 1 deletions
+17 -1
View File
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { ChipRow, type ChipDef } from './ChipColumn';
import { useI18n } from '../i18n/I18nProvider';
import { DEFAULT_ADJUSTMENTS, FILM_SIMS } from '../../shared/utils/defaultRecipes';
@@ -55,12 +55,14 @@ export function RecipeCreatePanel({
currentBase,
current,
signedIn,
onPreview,
onSave,
onExport,
}: {
currentBase?: BaseFilter;
current?: ColorAdjustments | null;
signedIn: boolean;
onPreview: (draft: Pick<Recipe, 'baseFilter' | 'adjustments'>) => void;
onSave: (draft: RecipeDraft) => void;
onExport: (draft: RecipeDraft) => void;
}) {
@@ -153,6 +155,20 @@ export function RecipeCreatePanel({
return { name: name.trim() || 'NEW RECIPE', baseFilter: sim, adjustments, frameId: 'none', useGeotag: true };
};
// Realtime: every knob applies to the photo on screen as it is typed, so the
// effect of the recipe is visible before saving it. Opening the tab is not an
// edit — the first run (the seeded values) is skipped.
const first = useRef(true);
useEffect(() => {
if (first.current) {
first.current = false;
return;
}
const { baseFilter, adjustments } = build();
onPreview({ baseFilter, adjustments });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sim, dr, grain, cc, ccb, wbKey, wbRed, wbBlue, fHigh, fShadow, fColor, fNr, fSharp, fClarity, fEv]);
const opts = (
prefix: string,
options: { v: string; d: string }[],