79 lines
1.8 KiB
TypeScript
79 lines
1.8 KiB
TypeScript
'use client'
|
|
|
|
import { useLocalStorage } from '@/hooks/useLocalStorage'
|
|
import SHA256 from 'crypto-js/sha256'
|
|
import { useEffect, useRef, useState } from 'react'
|
|
import { Scorm12API } from 'scorm-again/scorm12'
|
|
|
|
const settings = {
|
|
autocommit: true
|
|
// mastery_override: true
|
|
// logLevel: 2,
|
|
}
|
|
|
|
export function ScormPlayer({
|
|
scormState,
|
|
scormContentPath,
|
|
className
|
|
}: {
|
|
scormState: object
|
|
scormContentPath: string
|
|
className: string
|
|
}) {
|
|
const [iframeLoaded, setIframeLoaded] = useState(false)
|
|
const scormApiRef = useRef<Scorm12API | null>(null)
|
|
const hash = SHA256(scormContentPath).toString()
|
|
const [_, setScormState] = useLocalStorage(`scormState.${hash}`, {})
|
|
|
|
useEffect(() => {
|
|
const scormApi = new Scorm12API(settings)
|
|
scormApi.loadFromFlattenedJSON(scormState)
|
|
|
|
scormApi.on('LMSCommit', function () {
|
|
console.log('Committed')
|
|
|
|
setScormState(scormApi.renderCommitCMI(true))
|
|
})
|
|
|
|
scormApiRef.current = scormApi
|
|
window.API = scormApi
|
|
setIframeLoaded(true)
|
|
|
|
return () => {
|
|
scormApiRef.current = null
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (!scormApiRef.current) {
|
|
return
|
|
}
|
|
|
|
const scormApi = scormApiRef.current
|
|
let unloaded = false
|
|
|
|
function unload() {
|
|
if (unloaded || scormApi.isTerminated()) {
|
|
return
|
|
}
|
|
|
|
scormApi.LMSSetValue('cmi.core.exit', 'suspend')
|
|
scormApi.LMSCommit()
|
|
scormApi.LMSFinish()
|
|
unloaded = true
|
|
}
|
|
|
|
window.addEventListener('beforeunload', unload)
|
|
window.addEventListener('unload', unload)
|
|
|
|
return () => {
|
|
window.removeEventListener('beforeunload', unload)
|
|
window.removeEventListener('unload', unload)
|
|
}
|
|
}, [])
|
|
|
|
if (iframeLoaded) {
|
|
return <iframe src={`/proxy/${scormContentPath}`} className={className} />
|
|
}
|
|
}
|