mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-02 20:18:35 +00:00
fix(studio): preserve composed media treatments
This commit is contained in:
@@ -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,
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user