mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-13 00:16:09 +00:00
Module frontend/src/i18n : le texte français sert de clé, dictionnaires anglais par zone, langue du navigateur puis choix mémorisé, ?lang=en pour forcer. Bascule dans le menu du compte, la pastille visiteur, le menu Plus, l'écran d'accès et la connexion. Démo traduite (noms et lieux gardés). Liens d'aide et de vie privée selon la langue. Textes français sans accents corrigés. Test : chaque texte passé à t() a sa traduction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
1.7 KiB
React
51 lines
1.7 KiB
React
import { useEffect, useRef, useState } from 'react'
|
|
import { useBooting } from '../bootSignal.js'
|
|
import PzMark from './PzMark.jsx'
|
|
import { t } from '../i18n/index.js'
|
|
|
|
// N'apparaît que si l'attente dépasse SHOW_AFTER, reste au moins MIN_VISIBLE pour ne pas
|
|
// clignoter, puis les points se rejoignent et l'écran s'efface sur ce qui est prêt dessous.
|
|
const SHOW_AFTER = 400
|
|
const MIN_VISIBLE = 900
|
|
const MERGE = 420
|
|
const FADE = 200
|
|
|
|
export default function BootLoader() {
|
|
const booting = useBooting()
|
|
const [phase, setPhase] = useState('hidden') // hidden | rest | loading | merging | out
|
|
const shownAt = useRef(0)
|
|
|
|
useEffect(() => {
|
|
const timers = []
|
|
const later = (fn, ms) => timers.push(setTimeout(fn, ms))
|
|
|
|
if (booting) {
|
|
later(() => {
|
|
shownAt.current = performance.now()
|
|
setPhase('rest')
|
|
// une image au repos d'abord, pour que la division en trois points se voie
|
|
requestAnimationFrame(() => requestAnimationFrame(() => setPhase('loading')))
|
|
}, SHOW_AFTER)
|
|
} else if (shownAt.current) {
|
|
const wait = Math.max(0, MIN_VISIBLE - (performance.now() - shownAt.current))
|
|
later(() => setPhase('merging'), wait)
|
|
later(() => setPhase('out'), wait + MERGE)
|
|
later(() => {
|
|
setPhase('hidden')
|
|
shownAt.current = 0
|
|
}, wait + MERGE + FADE)
|
|
}
|
|
return () => timers.forEach(clearTimeout)
|
|
}, [booting])
|
|
|
|
if (phase === 'hidden') return null
|
|
|
|
const markState = phase === 'out' ? 'merging' : phase
|
|
return (
|
|
<div className={`pz-boot${phase === 'out' ? ' is-out' : ''}`} role="status">
|
|
<PzMark state={markState} />
|
|
<span className="pz-sr">{booting ? t("Ouverture de l'arbre") : t('Arbre prêt')}</span>
|
|
</div>
|
|
)
|
|
}
|