mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
feat(studio): persist per-element-type pinned groups in studioUiPreferences
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
384fe5934a
commit
0d7a60a525
@@ -88,3 +88,48 @@ describe("timeline zoom pin persistence", () => {
|
||||
expect(prefs.timelineManualZoomPercent).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
function fakeStorage(): Storage {
|
||||
const map = new Map<string, string>();
|
||||
return {
|
||||
getItem: (k) => map.get(k) ?? null,
|
||||
setItem: (k, v) => void map.set(k, v),
|
||||
removeItem: (k) => void map.delete(k),
|
||||
clear: () => map.clear(),
|
||||
key: () => null,
|
||||
get length() {
|
||||
return map.size;
|
||||
},
|
||||
} as Storage;
|
||||
}
|
||||
|
||||
describe("pinnedGroupsByElementType", () => {
|
||||
it("round-trips a per-element-type pin map", () => {
|
||||
const storage = fakeStorage();
|
||||
writeStudioUiPreferences(
|
||||
{ pinnedGroupsByElementType: { text: ["motion"], media: ["grade"] } },
|
||||
storage,
|
||||
);
|
||||
const read = readStudioUiPreferences(storage);
|
||||
expect(read.pinnedGroupsByElementType).toEqual({ text: ["motion"], media: ["grade"] });
|
||||
});
|
||||
|
||||
it("ignores a malformed pinnedGroupsByElementType (non-object, or non-string-array values)", () => {
|
||||
const storage = fakeStorage();
|
||||
storage.setItem(
|
||||
"hf-studio-ui-preferences",
|
||||
JSON.stringify({ pinnedGroupsByElementType: { text: "not-an-array", media: [1, 2] } }),
|
||||
);
|
||||
const read = readStudioUiPreferences(storage);
|
||||
expect(read.pinnedGroupsByElementType).toEqual({ media: [] });
|
||||
});
|
||||
|
||||
it("merges a pin-map patch without clobbering other preferences", () => {
|
||||
const storage = fakeStorage();
|
||||
writeStudioUiPreferences({ audioMuted: true }, storage);
|
||||
writeStudioUiPreferences({ pinnedGroupsByElementType: { text: ["style"] } }, storage);
|
||||
const read = readStudioUiPreferences(storage);
|
||||
expect(read.audioMuted).toBe(true);
|
||||
expect(read.pinnedGroupsByElementType).toEqual({ text: ["style"] });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,6 +28,7 @@ export interface StudioUiPreferences {
|
||||
timelineZoomMode?: "fit" | "manual";
|
||||
/** Manual timeline zoom percent, paired with `timelineZoomMode: "manual"`. */
|
||||
timelineManualZoomPercent?: number;
|
||||
pinnedGroupsByElementType?: Record<string, string[]>;
|
||||
}
|
||||
|
||||
const STUDIO_UI_PREFERENCES_KEY = "hf-studio-ui-preferences";
|
||||
@@ -115,6 +116,15 @@ function readStorage(storage: Storage | null): StudioUiPreferences {
|
||||
) {
|
||||
preferences.timelineManualZoomPercent = parsed.timelineManualZoomPercent;
|
||||
}
|
||||
if (isRecord(parsed.pinnedGroupsByElementType)) {
|
||||
const map: Record<string, string[]> = {};
|
||||
for (const [kind, ids] of Object.entries(parsed.pinnedGroupsByElementType)) {
|
||||
if (Array.isArray(ids)) {
|
||||
map[kind] = ids.filter((id): id is string => typeof id === "string");
|
||||
}
|
||||
}
|
||||
preferences.pinnedGroupsByElementType = map;
|
||||
}
|
||||
return preferences;
|
||||
} catch {
|
||||
return {};
|
||||
|
||||
Reference in New Issue
Block a user