fix(studio): the repair belongs to the frame, so a look loaded over it leaves it standing
This commit is contained in:
@@ -220,6 +220,23 @@ type DevPanel = 'wb' | 'tone' | 'presence' | 'effects';
|
||||
type StripKey = GroupKey | ToolStrip | DevPanel;
|
||||
const WM_SUBGROUPS: StripKey[] = ['wmColor', 'wmSize', 'wmFont', 'gpsColor', 'gpsName', 'gpsTime', 'gpsFont'];
|
||||
const isWmPanel = (g: StripKey | null) => g === 'wm' || (g !== null && WM_SUBGROUPS.includes(g));
|
||||
|
||||
// A look is colour and tone. HEAL's dust spots, FX's mosaic and the gradient
|
||||
// masks are drawn by hand on the frame standing on the stage — they belong to
|
||||
// that frame, not to whichever look is loaded next. A preset, a recent or a
|
||||
// .rcp file carries none of them, so laying one down must not take the
|
||||
// session's brushing with it: the marks already on the stage win, and a
|
||||
// recipe's own marks only land when the stage has none (a frame reopened from
|
||||
// the catalogue arrives with its own). UNDO is untouched by this — a snapshot
|
||||
// holds the whole recipe, marks included.
|
||||
function layLook(next: Recipe['adjustments'], prev: Recipe['adjustments']): Recipe['adjustments'] {
|
||||
return {
|
||||
...next,
|
||||
heal: prev.heal?.length ? prev.heal : next.heal,
|
||||
mosaic: prev.mosaic?.length ? prev.mosaic : next.mosaic,
|
||||
masks: prev.masks?.length ? prev.masks : next.masks,
|
||||
};
|
||||
}
|
||||
// A slider row opened from a strip returns to it with "<" (COLOR TEMP -> TEMP).
|
||||
// Every knob LIGHT owns names the panel it was opened from, so its ruler's back
|
||||
// reopens that panel's strip rather than dropping the strip off the screen.
|
||||
@@ -1435,7 +1452,8 @@ export function Workspace() {
|
||||
const applyRecipe = useCallback(
|
||||
(next: Recipe) => {
|
||||
remember();
|
||||
setRecipe(next);
|
||||
// The look arrives, the frame's own marks stay (see layLook).
|
||||
setRecipe((prev) => ({ ...next, adjustments: layLook(next.adjustments, prev.adjustments) }));
|
||||
setSimId(next.isCustom ? null : next.id);
|
||||
// A recipe filed by SAVE RECENT carries the frame it was saved with;
|
||||
// a bundled preset carries none, and then the frame on the stage stays.
|
||||
@@ -1882,7 +1900,13 @@ export function Workspace() {
|
||||
// the recipe can be judged before saving. No undo entry — this is a draft, and
|
||||
// SAVE/EXPORT is what commits it.
|
||||
const previewCreatedRecipe = useCallback((draft: Pick<Recipe, 'baseFilter' | 'adjustments'>) => {
|
||||
setRecipe((prev) => ({ ...prev, ...draft, isCustom: true }));
|
||||
setRecipe((prev) => ({
|
||||
...prev,
|
||||
...draft,
|
||||
// The draft is a look being judged; the frame's marks stay put (see layLook).
|
||||
adjustments: layLook(draft.adjustments, prev.adjustments),
|
||||
isCustom: true,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// The phone's encrypted .recipe envelope (`shared/utils/recipeShare` is the
|
||||
|
||||
Reference in New Issue
Block a user