mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
fix(studio): shell UX — data-loss guards, error surfacing, dialog contracts, toasts (#1964)
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { useCallback } from "react";
|
||||
|
||||
/**
|
||||
* Loads a composition file's content for the source editor when a composition
|
||||
* is selected. Content stays null until the fetch resolves — the source editor
|
||||
* must not mount on a null-content file, or its autosave would overwrite the
|
||||
* real file with an empty document. Load failures surface as an error toast
|
||||
* instead of silently rendering an empty (and autosave-armed) editor.
|
||||
*/
|
||||
export function useCompositionContentLoader({
|
||||
projectId,
|
||||
setEditingFile,
|
||||
setActiveCompPath,
|
||||
showToast,
|
||||
}: {
|
||||
projectId: string | null;
|
||||
setEditingFile: (file: { path: string; content: string | null }) => void;
|
||||
setActiveCompPath: (path: string | null) => void;
|
||||
showToast: (message: string, tone?: "error" | "info") => void;
|
||||
}) {
|
||||
return useCallback(
|
||||
(comp: string) => {
|
||||
setActiveCompPath(comp.endsWith(".html") ? comp : null);
|
||||
setEditingFile({ path: comp, content: null });
|
||||
fetch(`/api/projects/${projectId}/files/${comp}`)
|
||||
.then(async (r) => {
|
||||
if (!r.ok) throw new Error(`Failed to load ${comp} (${r.status})`);
|
||||
return r.json();
|
||||
})
|
||||
.then((data: { content?: string }) => {
|
||||
if (typeof data.content !== "string") throw new Error(`No content returned for ${comp}`);
|
||||
setEditingFile({ path: comp, content: data.content });
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(err instanceof Error ? err.message : `Failed to load ${comp}`, "error");
|
||||
});
|
||||
},
|
||||
[projectId, setEditingFile, setActiveCompPath, showToast],
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user