update lms app runtime integration
This commit is contained in:
@@ -77,14 +77,12 @@
|
||||
<script>
|
||||
document.getElementById('splash-image').src = './assets/splash.png'
|
||||
|
||||
const texts = ['학습 환경 준비 중...', '커리큘럼 불러오는 중...']
|
||||
const el = document.getElementById('loading-text')
|
||||
let index = 0
|
||||
|
||||
setInterval(() => {
|
||||
index = (index + 1) % texts.length
|
||||
el.textContent = texts[index]
|
||||
}, 1200)
|
||||
window.setSplashStatus = (message) => {
|
||||
if (typeof message === 'string' && message.trim()) {
|
||||
el.textContent = message
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2662,6 +2662,18 @@ function LocalPcWorkspaceMockup({
|
||||
)
|
||||
}
|
||||
|
||||
function BootLoadingOverlay({ message }: { message: string }): React.JSX.Element {
|
||||
return (
|
||||
<div className="fixed inset-0 z-[200] grid place-items-center bg-black/24 backdrop-blur-[3px]">
|
||||
<section className="w-[324px] rounded-xl border border-white/14 bg-[rgba(18,24,36,0.78)] px-6 py-5 text-center shadow-[0_24px_80px_rgba(0,0,0,0.42),inset_0_1px_0_rgba(255,255,255,0.10)] backdrop-blur-2xl">
|
||||
<div className="mx-auto mb-4 h-9 w-9 animate-spin rounded-full border-2 border-white/12 border-t-[#4f8dff]" />
|
||||
<p className="text-[14px] font-bold text-white">Autonomy Studio LMS</p>
|
||||
<p className="mt-2 text-[12px] font-semibold text-white/58">{message}</p>
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function App(): React.JSX.Element {
|
||||
const restoredStudioSessionRef = useRef<StudioRuntimeSessionState | null>(readStudioRuntimeSessionState())
|
||||
const previousWeekStateRef = useRef<Record<number, CurriculumWeek['state']>>({})
|
||||
@@ -2683,6 +2695,8 @@ export default function App(): React.JSX.Element {
|
||||
const [authSession, setAuthSession] = useState<LmsAuthSession | null>(null)
|
||||
const authSessionRef = useRef<LmsAuthSession | null>(null)
|
||||
const [authReady, setAuthReady] = useState(false)
|
||||
const [studentCoursesLoading, setStudentCoursesLoading] = useState(false)
|
||||
const [curriculumLoading, setCurriculumLoading] = useState(false)
|
||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
||||
const [userSidebarCollapsed, setUserSidebarCollapsed] = useState(false)
|
||||
const [platformModalOpen, setPlatformModalOpen] = useState(false)
|
||||
@@ -2939,6 +2953,7 @@ export default function App(): React.JSX.Element {
|
||||
const loadStudentCourses = useCallback(async (options: { autoSelectSingle?: boolean } = {}): Promise<void> => {
|
||||
if (!authReady || !authSession?.accessToken) return
|
||||
|
||||
setStudentCoursesLoading(true)
|
||||
try {
|
||||
const courses = await fetchStudentCourses(fetchWithFreshAuth)
|
||||
|
||||
@@ -2967,6 +2982,8 @@ export default function App(): React.JSX.Element {
|
||||
setStudentCourses([])
|
||||
setStudentCoursesLoaded(true)
|
||||
setCourseSelectionVisible(true)
|
||||
} finally {
|
||||
setStudentCoursesLoading(false)
|
||||
}
|
||||
}, [authReady, authSession?.accessToken, fetchWithFreshAuth])
|
||||
|
||||
@@ -2982,6 +2999,7 @@ export default function App(): React.JSX.Element {
|
||||
const loadCurriculum = useCallback(async (): Promise<void> => {
|
||||
if (!authReady || !studentCoursesLoaded || courseSelectionVisible || !selectedCourseId) return
|
||||
|
||||
setCurriculumLoading(true)
|
||||
try {
|
||||
const payload = await fetchCurriculum(fetchWithFreshAuth, selectedCourseId)
|
||||
const nextWeeks = payload?.weeks ?? []
|
||||
@@ -3023,6 +3041,8 @@ export default function App(): React.JSX.Element {
|
||||
setLearningStats([])
|
||||
setPlatformOptions([])
|
||||
setSelectedWeekState(null)
|
||||
} finally {
|
||||
setCurriculumLoading(false)
|
||||
}
|
||||
}, [authReady, authSession?.accessToken, courseSelectionVisible, fetchWithFreshAuth, selectedCourseId, selectedWeekState?.week, studentCoursesLoaded])
|
||||
|
||||
@@ -3924,6 +3944,22 @@ export default function App(): React.JSX.Element {
|
||||
setMaterialDownloadingResourceIds((current) => current.filter((id) => id !== resource.id))
|
||||
}
|
||||
}
|
||||
const bootLoadingMessage = !authReady
|
||||
? '로그인 세션 확인 중...'
|
||||
: authSession?.accessToken && (!studentCoursesLoaded || studentCoursesLoading)
|
||||
? '강좌 정보 불러오는 중...'
|
||||
: authSession?.accessToken && curriculumLoading
|
||||
? '커리큘럼 및 플랫폼 정보 가져오는 중...'
|
||||
: ''
|
||||
const bootLoadingVisible = Boolean(bootLoadingMessage)
|
||||
useEffect(() => {
|
||||
if (bootLoadingMessage) {
|
||||
window.lmsBootSplash?.status(bootLoadingMessage)
|
||||
return
|
||||
}
|
||||
|
||||
window.lmsBootSplash?.done()
|
||||
}, [bootLoadingMessage])
|
||||
|
||||
return (
|
||||
<div className="h-screen w-screen overflow-hidden bg-[#0a0b0e]">
|
||||
@@ -4219,6 +4255,7 @@ export default function App(): React.JSX.Element {
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
{bootLoadingVisible && <BootLoadingOverlay message={bootLoadingMessage} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -37,6 +37,10 @@ interface Window {
|
||||
handoffToken: string | null
|
||||
audienceApp: string
|
||||
}
|
||||
lmsBootSplash?: {
|
||||
status: (message: string) => void
|
||||
done: () => void
|
||||
}
|
||||
titlebar: {
|
||||
minimize: () => void
|
||||
maximize: () => void
|
||||
|
||||
Reference in New Issue
Block a user