diff --git a/src/main.jsx b/src/main.jsx index ea609d2..8f98b78 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -106,24 +106,27 @@ function App() { const [previewLine, setPreviewLine] = useState(null); const [previewStep, setPreviewStep] = useState(0); const [previewPlaying, setPreviewPlaying] = useState(false); + const [previewDetachedFen, setPreviewDetachedFen] = useState(null); + const [previewManualMove, setPreviewManualMove] = useState(null); const [settings, setSettings] = useState(() => { try { return { ...defaultSettings, ...JSON.parse(localStorage.getItem('atelier64-settings')) }; } catch { return defaultSettings; } }); const game = useMemo(() => new Chess(fen), [fen]); - const targets = selected ? game.moves({ square: selected, verbose: true }).map((m) => m.to) : []; const bestMove = showHint ? analysis[0]?.pv?.[0] : null; const lastMove = moves.at(-1)?.uci; const previewVariation = previewLine === null ? null : analysis[previewLine]; const previewGame = useMemo(() => { + if (previewDetachedFen) return new Chess(previewDetachedFen); const replay = new Chess(fen); for (const move of previewVariation?.moves?.slice(0, previewStep) || []) { try { replay.move({ from: move.uci.slice(0, 2), to: move.uci.slice(2, 4), promotion: move.uci[4] || 'q' }); } catch { break; } } return replay; - }, [fen, previewVariation, previewStep]); + }, [fen, previewVariation, previewStep, previewDetachedFen]); const displayedGame = previewVariation ? previewGame : game; - const previewLastMove = previewVariation?.moves?.[previewStep - 1]?.uci; - const previewNextMove = previewVariation?.moves?.[previewStep]?.uci; + const targets = selected ? displayedGame.moves({ square: selected, verbose: true }).map((m) => m.to) : []; + const previewLastMove = previewDetachedFen ? previewManualMove : previewVariation?.moves?.[previewStep - 1]?.uci; + const previewNextMove = previewDetachedFen ? null : previewVariation?.moves?.[previewStep]?.uci; useEffect(() => { const controller = new AbortController(); @@ -151,21 +154,25 @@ function App() { }, [previewPlaying, previewStep, previewVariation]); useEffect(() => { - setPreviewLine(null); setPreviewStep(0); setPreviewPlaying(false); + setPreviewLine(null); setPreviewStep(0); setPreviewPlaying(false); setPreviewDetachedFen(null); setPreviewManualMove(null); }, [fen]); function openVariation(index) { - setPreviewLine(index); setPreviewStep(1); setPreviewPlaying(true); setSelected(null); + setPreviewLine(index); setPreviewStep(0); setPreviewPlaying(false); setPreviewDetachedFen(null); setPreviewManualMove(null); setSelected(null); } function closeVariation() { - setPreviewLine(null); setPreviewStep(0); setPreviewPlaying(false); + setPreviewLine(null); setPreviewStep(0); setPreviewPlaying(false); setPreviewDetachedFen(null); setPreviewManualMove(null); setSelected(null); } function attemptMove(from, to) { - const next = new Chess(fen); + const next = new Chess(previewVariation ? displayedGame.fen() : fen); try { const move = next.move({ from, to, promotion: 'q' }); + if (previewVariation) { + setPreviewDetachedFen(next.fen()); setPreviewManualMove(`${move.from}${move.to}${move.promotion || ''}`); setPreviewPlaying(false); setSelected(null); + return; + } setHistory([...history, { fen, moves }]); setMoves([...moves, { san: move.san, uci: `${move.from}${move.to}${move.promotion || ''}`, color: move.color }]); setFen(next.fen()); setSelected(null); setShowHint(true); @@ -173,13 +180,13 @@ function App() { } function onSquare(square, draggedFrom) { - if (game.isGameOver()) return; + if (displayedGame.isGameOver()) return; if (draggedFrom) return attemptMove(draggedFrom, square); if (selected) { if (selected === square) return setSelected(null); if (targets.includes(square)) return attemptMove(selected, square); } - setSelected(game.get(square)?.color === game.turn() ? square : null); + setSelected(displayedGame.get(square)?.color === displayedGame.turn() ? square : null); } function undo() { @@ -219,8 +226,8 @@ function App() {
PARTIE LIBRE · DEUX CÔTÉS

{status}

{game.turn() === 'w' ? 'BLANCS' : 'NOIRS'}
{scoreLabel(rawScore)}
- {previewVariation &&
VARIANTE {String(previewLine + 1).padStart(2, '0')}{previewStep}/{previewVariation.moves.length}
} - {} : onSquare}/> + {previewVariation &&
VARIANTE {String(previewLine + 1).padStart(2, '0')}{previewDetachedFen ? 'EXPLORATION LIBRE' : `${previewStep}/${previewVariation.moves.length}`}
} +
@@ -240,10 +247,10 @@ function App() {
VARIANTES PRINCIPALESÉVAL.
{analysis.slice(0, 3).map((line, index) => )} {previewVariation &&
- - - - {previewStep ? previewVariation.moves[previewStep - 1]?.san : 'Position initiale'} + + + + {previewDetachedFen ? 'Exploration libre' : previewStep ? previewVariation.moves[previewStep - 1]?.san : 'En pause · premier coup indiqué'}
}