MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / StudioApp

Function StudioApp

packages/studio/src/App.tsx:62–597  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

60type CanvasRect = { left: number; top: number; width: number; height: number };
61// fallow-ignore-next-line complexity
62export function StudioApp() {
63 const { projectId, resolving, waitingForServer } = useServerConnection();
64 const initialUrlStateRef = useRef(readStudioUrlStateFromWindow());
65 const viewModeValue = useViewModeState();
66
67 // sessionStorage-backed: fires once per tab, survives HMR remounts
68 useEffect(() => {
69 if (resolving || waitingForServer) return;
70 if (hasFiredSessionStart()) return;
71 markSessionStartFired();
72 trackStudioSessionStart({ has_project: projectId != null });
73 }, [projectId, resolving, waitingForServer]);
74
75 const [activeCompPath, setActiveCompPath] = useState<string | null>(null);
76 const [activeCompPathHydrated, setActiveCompPathHydrated] = useState(
77 () => initialUrlStateRef.current.activeCompPath == null,
78 );
79 const [compIdToSrc, setCompIdToSrc] = useState<Map<string, string>>(new Map());
80 const [previewIframe, setPreviewIframe] = useState<HTMLIFrameElement | null>(null);
81 const [compositionLoading, setCompositionLoading] = useState(true);
82 const [refreshKey, setRefreshKey] = useState(0);
83 const [previewDocumentVersion, setPreviewDocumentVersion] = useState(0);
84 const [blockPreview, setBlockPreview] = useState<BlockPreviewInfo | null>(null);
85 const previewIframeRef = useRef<HTMLIFrameElement | null>(null);
86 const activeCompPathRef = useRef(activeCompPath);
87 activeCompPathRef.current = activeCompPath;
88 const leftSidebarRef = useRef<LeftSidebarHandle>(null);
89 const renderQueue = useRenderQueue(projectId);
90 const captionEditMode = useCaptionStore((s) => s.isEditMode);
91 const captionHasSelection = useCaptionStore((s) => s.selectedSegmentIds.size > 0);
92 const captionSync = useCaptionSync(projectId);
93 const timelineElements = usePlayerStore((s) => s.elements);
94 const setSelectedTimelineElementId = usePlayerStore((s) => s.setSelectedElementId);
95 const timelineDuration = usePlayerStore((s) => s.duration);
96 const isPlaying = usePlayerStore((s) => s.isPlaying);
97 const isMasterView = !activeCompPath || activeCompPath === "index.html";
98 const activePreviewUrl = activeCompPath
99 ? `/api/projects/${projectId}/preview/comp/${activeCompPath}`
100 : null;
101 const effectiveTimelineDuration = useMemo(() => {
102 const maxEnd =
103 timelineElements.length > 0
104 ? Math.max(...timelineElements.map((el) => el.start + el.duration))
105 : 0;
106 return Math.max(timelineDuration, maxEnd);
107 }, [timelineDuration, timelineElements]);
108 const refreshTimersRef = useRef<number[]>([]);
109 const refreshPreviewDocumentVersion = useCallback(() => {
110 for (const id of refreshTimersRef.current) clearTimeout(id);
111 refreshTimersRef.current = [];
112 setPreviewDocumentVersion((v) => v + 1);
113 refreshTimersRef.current.push(
114 window.setTimeout(() => setPreviewDocumentVersion((v) => v + 1), 80),
115 window.setTimeout(() => setPreviewDocumentVersion((v) => v + 1), 300),
116 );
117 }, []);
118 useEffect(
119 () => () => {

Callers

nothing calls this directly

Calls 15

useServerConnectionFunction · 0.90
useViewModeStateFunction · 0.90
hasFiredSessionStartFunction · 0.90
markSessionStartFiredFunction · 0.90
trackStudioSessionStartFunction · 0.90
useRenderQueueFunction · 0.90
useCaptionSyncFunction · 0.90
readStudioUiPreferencesFunction · 0.90
writeStudioUiPreferencesFunction · 0.90
useToastFunction · 0.90
usePanelLayoutFunction · 0.90

Tested by

no test coverage detected