fix(studio): preserve composed media treatments

This commit is contained in:
ukimsanov
2026-07-24 18:42:37 -07:00
parent 39c2341c4d
commit d5c7d3ee16
3 changed files with 54 additions and 17 deletions
@@ -490,15 +490,27 @@ describe("useColorGradingController", () => {
vi.useRealTimers(); vi.useRealTimers();
}); });
it("resetGrading returns to the neutral preset", () => { it("resetGrading resets Grade fields without clearing Effects or Palette", () => {
const { root, getState } = renderHook(vi.fn()); const { root, getState } = renderHook(vi.fn());
const grading = normalizeHfColorGrading({
preset: "bright-pop",
lut: { src: "assets/luts/custom.cube", intensity: 0.6 },
effects: { pixelate: 0.5 },
palette: ["#112233", "#ffffff"],
});
if (!grading) throw new Error("expected grading to normalize");
act(() => { act(() => {
getState().commitColorGrading(brightPopGrading()); getState().commitColorGrading(grading);
}); });
act(() => { act(() => {
getState().resetGrading(); getState().resetGrading();
}); });
expect(getState().grading.preset).toBe("neutral"); expect(getState().grading).toMatchObject({
preset: "neutral",
lut: null,
effects: { pixelate: 0.5 },
palette: ["#112233", "#ffffff"],
});
act(() => root.unmount()); act(() => root.unmount());
}); });
@@ -542,6 +542,13 @@ export function useColorGradingController({
commitCompare, commitCompare,
setApplyScope, setApplyScope,
applyToScope, applyToScope,
resetGrading: () => commitColorGrading(defaultColorGrading()), resetGrading: () => {
const neutral = defaultColorGrading();
commitColorGrading({
...neutral,
effects: latestGradingRef.current.effects,
palette: latestGradingRef.current.palette,
});
},
}; };
} }
+31 -13
View File
@@ -6,33 +6,51 @@ import {
resolveBlockCategory, resolveBlockCategory,
} from "../utils/blockCategories"; } from "../utils/blockCategories";
export type CatalogItem = RegistryItem & { type CatalogItem = RegistryItem & {
category: BlockCategory; category: BlockCategory;
}; };
let catalogCache: CatalogItem[] | null = null;
let catalogRequest: Promise<CatalogItem[]> | null = null;
function loadCatalog(): Promise<CatalogItem[]> {
catalogRequest ??= fetch("/api/registry/blocks")
.then((response) => {
if (!response.ok) throw new Error("Failed to load catalog");
return response.json() as Promise<RegistryItem[]>;
})
.then((items) => {
catalogCache = items
.map((item) => ({ ...item, category: resolveBlockCategory(item.tags) }))
.sort((a, b) => {
const aIndex = BLOCK_CATEGORIES.findIndex((category) => category.id === a.category);
const bIndex = BLOCK_CATEGORIES.findIndex((category) => category.id === b.category);
return (aIndex === -1 ? 99 : aIndex) - (bIndex === -1 ? 99 : bIndex);
});
return catalogCache;
})
.catch((error: unknown) => {
catalogRequest = null;
throw error;
});
return catalogRequest;
}
export function useBlockCatalog() { export function useBlockCatalog() {
const [blocks, setBlocks] = useState<CatalogItem[]>([]); const [blocks, setBlocks] = useState<CatalogItem[]>(() => catalogCache ?? []);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(catalogCache === null);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [category, setCategory] = useState<BlockCategory | null>(null); const [category, setCategory] = useState<BlockCategory | null>(null);
// fallow-ignore-next-line complexity // fallow-ignore-next-line complexity
useEffect(() => { useEffect(() => {
if (catalogCache) return;
let cancelled = false; let cancelled = false;
(async () => { (async () => {
try { try {
const res = await fetch("/api/registry/blocks"); const items = await loadCatalog();
if (!res.ok) throw new Error("Failed to load catalog");
const data = (await res.json()) as RegistryItem[];
if (cancelled) return; if (cancelled) return;
const items = data
.map((b) => ({ ...b, category: resolveBlockCategory(b.tags) }))
.sort((a, b) => {
const ia = BLOCK_CATEGORIES.findIndex((c) => c.id === a.category);
const ib = BLOCK_CATEGORIES.findIndex((c) => c.id === b.category);
return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
});
setBlocks(items); setBlocks(items);
} catch (err) { } catch (err) {
if (cancelled) return; if (cancelled) return;