loading.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { FC, useEffect, useState } from 'react'
  2. import LoadingBranded from '@/shared/components/loading-branded'
  3. import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n'
  4. import getMeta from '@/utils/meta'
  5. import { useConnectionContext } from '../context/connection-context'
  6. import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
  7. type Part = 'initial' | 'render' | 'connection' | 'translations' | 'project'
  8. const initialParts = new Set<Part>(['initial'])
  9. const totalParts = new Set<Part>([
  10. 'initial',
  11. 'render',
  12. 'connection',
  13. 'translations',
  14. 'project',
  15. ])
  16. export const Loading: FC<{
  17. setLoaded: (value: boolean) => void
  18. }> = ({ setLoaded }) => {
  19. const [loadedParts, setLoadedParts] = useState(initialParts)
  20. const progress = (loadedParts.size / totalParts.size) * 100
  21. useEffect(() => {
  22. setLoaded(progress === 100)
  23. }, [progress, setLoaded])
  24. const { connectionState, isConnected } = useConnectionContext()
  25. const i18n = useWaitForI18n()
  26. const { projectJoined } = useIdeReactContext()
  27. useEffect(() => {
  28. setLoadedParts(value => new Set(value).add('render'))
  29. }, [])
  30. useEffect(() => {
  31. if (isConnected) {
  32. setLoadedParts(value => new Set(value).add('connection'))
  33. }
  34. }, [isConnected])
  35. useEffect(() => {
  36. if (i18n.isReady) {
  37. setLoadedParts(value => new Set(value).add('translations'))
  38. }
  39. }, [i18n.isReady])
  40. useEffect(() => {
  41. if (projectJoined) {
  42. setLoadedParts(value => new Set(value).add('project'))
  43. }
  44. }, [projectJoined])
  45. const error =
  46. connectionState.error ||
  47. (i18n.error ? getMeta('ol-translationLoadErrorMessage') : '')
  48. // Use loading text from the server, because i18n will not be ready initially
  49. const label = getMeta('ol-loadingText')
  50. return (
  51. <div className="loading-screen">
  52. <LoadingBranded loadProgress={progress} label={label} error={error} />
  53. </div>
  54. )
  55. }