2023-10-16 07:10:43 -04:00
|
|
|
import { FC, useEffect, useState } from 'react'
|
2023-11-27 06:26:06 -05:00
|
|
|
import LoadingBranded from '@/shared/components/loading-branded'
|
|
|
|
import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n'
|
2023-10-16 07:10:43 -04:00
|
|
|
import getMeta from '@/utils/meta'
|
2023-11-27 06:26:06 -05:00
|
|
|
import { useConnectionContext } from '../context/connection-context'
|
|
|
|
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
2024-10-10 03:38:08 -04:00
|
|
|
import { LoadingError, LoadingErrorProps } from './loading-error'
|
2023-10-16 07:10:43 -04:00
|
|
|
|
2023-11-27 06:26:06 -05:00
|
|
|
type Part = 'initial' | 'render' | 'connection' | 'translations' | 'project'
|
2023-10-16 07:10:43 -04:00
|
|
|
|
2023-11-27 06:26:06 -05:00
|
|
|
const initialParts = new Set<Part>(['initial'])
|
2023-10-16 07:10:43 -04:00
|
|
|
|
2023-11-27 06:26:06 -05:00
|
|
|
const totalParts = new Set<Part>([
|
|
|
|
'initial',
|
|
|
|
'render',
|
|
|
|
'connection',
|
|
|
|
'translations',
|
|
|
|
'project',
|
|
|
|
])
|
2023-10-16 07:10:43 -04:00
|
|
|
|
2023-11-27 06:26:06 -05:00
|
|
|
export const Loading: FC<{
|
|
|
|
setLoaded: (value: boolean) => void
|
|
|
|
}> = ({ setLoaded }) => {
|
|
|
|
const [loadedParts, setLoadedParts] = useState(initialParts)
|
|
|
|
|
|
|
|
const progress = (loadedParts.size / totalParts.size) * 100
|
2023-10-16 07:10:43 -04:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-11-27 06:26:06 -05:00
|
|
|
setLoaded(progress === 100)
|
|
|
|
}, [progress, setLoaded])
|
|
|
|
|
|
|
|
const { connectionState, isConnected } = useConnectionContext()
|
|
|
|
const i18n = useWaitForI18n()
|
|
|
|
const { projectJoined } = useIdeReactContext()
|
2023-10-16 07:10:43 -04:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-11-27 06:26:06 -05:00
|
|
|
setLoadedParts(value => new Set(value).add('render'))
|
2023-10-16 07:10:43 -04:00
|
|
|
}, [])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isConnected) {
|
2023-11-27 06:26:06 -05:00
|
|
|
setLoadedParts(value => new Set(value).add('connection'))
|
|
|
|
}
|
|
|
|
}, [isConnected])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (i18n.isReady) {
|
|
|
|
setLoadedParts(value => new Set(value).add('translations'))
|
2023-10-16 07:10:43 -04:00
|
|
|
}
|
2023-11-27 06:26:06 -05:00
|
|
|
}, [i18n.isReady])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (projectJoined) {
|
|
|
|
setLoadedParts(value => new Set(value).add('project'))
|
|
|
|
}
|
|
|
|
}, [projectJoined])
|
|
|
|
|
|
|
|
// Use loading text from the server, because i18n will not be ready initially
|
|
|
|
const label = getMeta('ol-loadingText')
|
2023-10-16 07:10:43 -04:00
|
|
|
|
2024-10-10 03:38:08 -04:00
|
|
|
const errorCode = connectionState.error ?? (i18n.error ? 'i18n-error' : '')
|
2023-12-15 07:21:00 -05:00
|
|
|
|
2024-10-10 03:38:08 -04:00
|
|
|
return <LoadingUI progress={progress} label={label} errorCode={errorCode} />
|
|
|
|
}
|
|
|
|
|
|
|
|
type LoadingUiProps = {
|
|
|
|
progress: number
|
|
|
|
label: string
|
|
|
|
errorCode: LoadingErrorProps['errorCode']
|
|
|
|
}
|
|
|
|
|
|
|
|
export const LoadingUI: FC<LoadingUiProps> = ({
|
|
|
|
progress,
|
|
|
|
label,
|
|
|
|
errorCode,
|
|
|
|
}) => {
|
2023-11-27 06:26:06 -05:00
|
|
|
return (
|
2023-10-16 07:10:43 -04:00
|
|
|
<div className="loading-screen">
|
2023-12-15 07:21:00 -05:00
|
|
|
<LoadingBranded
|
|
|
|
loadProgress={progress}
|
|
|
|
label={label}
|
2024-10-10 03:38:08 -04:00
|
|
|
hasError={Boolean(errorCode)}
|
2023-12-15 07:21:00 -05:00
|
|
|
/>
|
2024-10-10 03:38:08 -04:00
|
|
|
{Boolean(errorCode) && <LoadingError errorCode={errorCode} />}
|
2023-10-16 07:10:43 -04:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|