move the pgn viewer related logic into a hook and type the ref

This commit is contained in:
2026-06-03 19:48:40 +02:00
parent 459b79535b
commit 1d9ee25e1f
3 changed files with 80 additions and 76 deletions
+3 -75
View File
@@ -1,5 +1,4 @@
import LichessPgnViewer from "lichess-pgn-viewer";
import { useEffect, useRef } from "react";
import { useLichessPgnViewer } from "#/hooks/useLichessPgnViewer.ts";
import type { IPosition } from "#/interfaces.ts";
interface IProps {
@@ -8,80 +7,9 @@ interface IProps {
}
const PgnViewer = ({ gamePgn, handlePlyChange }: IProps) => {
const containerRef = useRef<HTMLDivElement | null>(null);
const viewerRef = useRef(null);
useLichessPgnViewer({ gamePgn, handlePlyChange });
// TODO make thin, and pull functions out
useEffect(() => {
const element: HTMLElement | null = document.querySelector(".lpv-board");
if (!element) return;
viewerRef.current = LichessPgnViewer(element, {
pgn: gamePgn,
scrollToMove: false,
});
// set initial position - TODO change to on file load
// handlePlyChange({
// ply: 0,
// fen: viewerRef.current?.curData().fen,
// });
const boardButtons = document.querySelectorAll(".lpv__controls");
const movesList = document.querySelectorAll(".lpv__moves");
if (!boardButtons || !movesList) return;
const clickHandlerDelay = () => {
setTimeout(() => handleClick(), 250);
};
// Hack using DOM manipulation
const boardEventListener = () => {
const variationTags = document.querySelector("variation");
const moves = [...document.querySelectorAll("move")].filter((m) => {
if (!variationTags) return m.className !== "empty";
return (
m.parentNode?.querySelector("variation") && m.className !== "empty"
);
});
const ply = moves.findIndex((m) => m.classList.contains("current")) + 1;
return { moves, ply };
};
const handleClick = () => {
const { ply } = boardEventListener();
const fen = viewerRef.current?.curData().fen;
handlePlyChange({ ply, fen });
};
boardButtons.forEach((button) => {
button.addEventListener("click", handleClick);
button.addEventListener("touchstart", handleClick);
});
movesList.forEach((move) => {
move.addEventListener("click", clickHandlerDelay);
move.addEventListener("touchstart", clickHandlerDelay);
});
return () => {
if (containerRef.current) {
containerRef.current = null;
}
boardButtons.forEach((button) => {
button.removeEventListener("click", handleClick);
button.removeEventListener("touchstart", handleClick);
});
movesList.forEach((move) => {
move.removeEventListener("click", clickHandlerDelay);
move.removeEventListener("touchstart", clickHandlerDelay);
});
};
}, [gamePgn, handlePlyChange]);
return <div ref={containerRef} className="lpv-board" />;
return <div className="lpv-board" />;
};
export default PgnViewer;