|
|
@@ -3927,6 +3927,7 @@ function LocalPcWorkspaceMockup({
|
|
|
|
export default function App(): React.JSX.Element {
|
|
|
|
export default function App(): React.JSX.Element {
|
|
|
|
const restoredStudioSessionRef = useRef<StudioRuntimeSessionState | null>(readStudioRuntimeSessionState())
|
|
|
|
const restoredStudioSessionRef = useRef<StudioRuntimeSessionState | null>(readStudioRuntimeSessionState())
|
|
|
|
const previousWeekStateRef = useRef<Record<number, CurriculumWeek['state']>>({})
|
|
|
|
const previousWeekStateRef = useRef<Record<number, CurriculumWeek['state']>>({})
|
|
|
|
|
|
|
|
const curriculumLoadRequestRef = useRef(0)
|
|
|
|
const controlExpiryHandledRef = useRef<Set<string>>(new Set())
|
|
|
|
const controlExpiryHandledRef = useRef<Set<string>>(new Set())
|
|
|
|
const stopRunningWorkspaceModulesRef = useRef<(() => Promise<void>) | null>(null)
|
|
|
|
const stopRunningWorkspaceModulesRef = useRef<(() => Promise<void>) | null>(null)
|
|
|
|
const getRunningWorkspaceModuleNamesRef = useRef<(() => string[]) | null>(null)
|
|
|
|
const getRunningWorkspaceModuleNamesRef = useRef<(() => string[]) | null>(null)
|
|
|
@@ -4386,10 +4387,12 @@ export default function App(): React.JSX.Element {
|
|
|
|
const loadCurriculum = useCallback(async (): Promise<void> => {
|
|
|
|
const loadCurriculum = useCallback(async (): Promise<void> => {
|
|
|
|
if (!authReady || !studentCoursesLoaded || courseSelectionVisible || !selectedCourseId) return
|
|
|
|
if (!authReady || !studentCoursesLoaded || courseSelectionVisible || !selectedCourseId) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const requestId = ++curriculumLoadRequestRef.current
|
|
|
|
const curriculumLoadingStartedAt = Date.now()
|
|
|
|
const curriculumLoadingStartedAt = Date.now()
|
|
|
|
setCurriculumLoading(true)
|
|
|
|
setCurriculumLoading(true)
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const payload = await fetchCurriculum(fetchWithFreshAuth, selectedCourseId)
|
|
|
|
const payload = await fetchCurriculum(fetchWithFreshAuth, selectedCourseId)
|
|
|
|
|
|
|
|
if (requestId !== curriculumLoadRequestRef.current) return
|
|
|
|
const nextWeeks = payload?.weeks ?? []
|
|
|
|
const nextWeeks = payload?.weeks ?? []
|
|
|
|
const serverActiveWeek = payload?.activeWeek ?? null
|
|
|
|
const serverActiveWeek = payload?.activeWeek ?? null
|
|
|
|
const previousWeekStates = previousWeekStateRef.current
|
|
|
|
const previousWeekStates = previousWeekStateRef.current
|
|
|
@@ -4407,7 +4410,7 @@ export default function App(): React.JSX.Element {
|
|
|
|
setCompletedCurriculumNotice(newlyCompletedWeek)
|
|
|
|
setCompletedCurriculumNotice(newlyCompletedWeek)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
previousWeekStateRef.current = Object.fromEntries(nextWeeks.map((week) => [week.week, week.state]))
|
|
|
|
previousWeekStateRef.current = Object.fromEntries(nextWeeks.map((week) => [week.week, week.state]))
|
|
|
|
setCourseKey(payload?.course?.id ?? payload?.course?.slug ?? 'default-course')
|
|
|
|
setCourseKey(selectedCourseId)
|
|
|
|
setStudentGroup(payload?.studentGroup ?? null)
|
|
|
|
setStudentGroup(payload?.studentGroup ?? null)
|
|
|
|
setCurriculumWeeks(nextWeeks)
|
|
|
|
setCurriculumWeeks(nextWeeks)
|
|
|
|
setActiveLearningStep(payload?.activeLearningStep ?? null)
|
|
|
|
setActiveLearningStep(payload?.activeLearningStep ?? null)
|
|
|
@@ -4425,6 +4428,7 @@ export default function App(): React.JSX.Element {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
setSelectedWeekState(nextSelectedWeek)
|
|
|
|
setSelectedWeekState(nextSelectedWeek)
|
|
|
|
} catch {
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
if (requestId !== curriculumLoadRequestRef.current) return
|
|
|
|
setCurriculumWeeks([])
|
|
|
|
setCurriculumWeeks([])
|
|
|
|
setCourseKey('default-course')
|
|
|
|
setCourseKey('default-course')
|
|
|
|
setLearningStats([])
|
|
|
|
setLearningStats([])
|
|
|
@@ -4432,6 +4436,7 @@ export default function App(): React.JSX.Element {
|
|
|
|
setStudentGroup(null)
|
|
|
|
setStudentGroup(null)
|
|
|
|
setSelectedWeekState(null)
|
|
|
|
setSelectedWeekState(null)
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
if (requestId !== curriculumLoadRequestRef.current) return
|
|
|
|
const remainingMs = Math.max(0, 500 - (Date.now() - curriculumLoadingStartedAt))
|
|
|
|
const remainingMs = Math.max(0, 500 - (Date.now() - curriculumLoadingStartedAt))
|
|
|
|
if (remainingMs) await new Promise<void>((resolve) => window.setTimeout(resolve, remainingMs))
|
|
|
|
if (remainingMs) await new Promise<void>((resolve) => window.setTimeout(resolve, remainingMs))
|
|
|
|
setCurriculumLoading(false)
|
|
|
|
setCurriculumLoading(false)
|
|
|
@@ -4813,6 +4818,7 @@ export default function App(): React.JSX.Element {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (selectedCourseStorageKey) window.localStorage.setItem(selectedCourseStorageKey, courseId)
|
|
|
|
if (selectedCourseStorageKey) window.localStorage.setItem(selectedCourseStorageKey, courseId)
|
|
|
|
|
|
|
|
setCourseKey(courseId)
|
|
|
|
setSelectedCourseId(courseId)
|
|
|
|
setSelectedCourseId(courseId)
|
|
|
|
setCourseSelectionVisible(false)
|
|
|
|
setCourseSelectionVisible(false)
|
|
|
|
setLocalPcLayoutOpen(false)
|
|
|
|
setLocalPcLayoutOpen(false)
|
|
|
@@ -5637,7 +5643,7 @@ export default function App(): React.JSX.Element {
|
|
|
|
{studioEntered && workspaceWeekState && workspacePlatform && (
|
|
|
|
{studioEntered && workspaceWeekState && workspacePlatform && (
|
|
|
|
<div className={localPcLayoutOpen ? 'h-full' : 'hidden h-full'}>
|
|
|
|
<div className={localPcLayoutOpen ? 'h-full' : 'hidden h-full'}>
|
|
|
|
<LocalPcWorkspaceMockup
|
|
|
|
<LocalPcWorkspaceMockup
|
|
|
|
key={workspacePlatform?.id ?? 'local-pc-workspace'}
|
|
|
|
key={`${workspacePlatform?.id ?? 'local-pc-workspace'}:${courseKey}:${workspaceWeek.week}`}
|
|
|
|
onClose={() => {
|
|
|
|
onClose={() => {
|
|
|
|
closeLocalPcWorkspace()
|
|
|
|
closeLocalPcWorkspace()
|
|
|
|
setOuterView('curriculum')
|
|
|
|
setOuterView('curriculum')
|
|
|
|