move handlers into useChessGame hook

This commit is contained in:
2026-06-01 15:29:39 +02:00
parent 324e4eac31
commit b964e12f0e
3 changed files with 86 additions and 72 deletions
+77
View File
@@ -0,0 +1,77 @@
import { type ChangeEvent, useReducer, useRef } from "react";
import { gameReducer, initialGameState } from "#/reducers/gameReducer.ts";
import { buildPgnString, getHeaders } from "#/utils/pgnUtils.ts";
import { downloadString } from "#/utils/stringUtils.ts";
export const useChessGame = () => {
const [gameState, gameDispatch] = useReducer(gameReducer, initialGameState);
const fileInputRef = useRef<HTMLInputElement | null>(null);
const handleSavePgn = () => {
const pgnString = buildPgnString(gameState);
downloadString(pgnString, "game.pgn");
};
const handleSavePdf = () => {
console.log("Save PDF");
};
const handleClearGame = () => {
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
gameDispatch({
type: "CLEAR_GAME",
});
};
const handleLoadPgn = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
const selectedFile = e.target.files?.[0];
if (selectedFile?.name.endsWith(".pgn")) {
const reader = new FileReader();
reader.onload = (event) => {
const pgnData = event.target?.result;
let pgnString = "";
if (pgnData) {
if (typeof pgnData === "string") {
pgnString = pgnData;
} else {
pgnString = new TextDecoder().decode(pgnData);
}
}
if (pgnString) {
const headers = {
...getHeaders(pgnString),
title: "",
subtitle: "",
};
gameDispatch({
type: "SET_GAME",
payload: { pgn: pgnString, headers: headers },
});
} else {
e.target.files = null;
handleClearGame();
}
};
reader.readAsText(selectedFile);
} else {
handleClearGame();
}
};
return {
gameState,
fileInputRef,
handleSavePgn,
handleSavePdf,
handleClearGame,
handleLoadPgn,
};
};
+8 -71
View File
@@ -1,80 +1,17 @@
import { type ChangeEvent, useReducer, useRef } from "react";
import { useChessGame } from "#/hooks/useChessGame.ts";
import Chessboard from "#/pages/Chessboard.tsx";
import { gameReducer, initialGameState } from "#/reducers/gameReducer.ts";
import { buildPgnString, getHeaders } from "#/utils/pgnUtils.ts";
import { downloadString } from "#/utils/stringUtils.ts";
const ChessboardContainer = () => {
const [gameState, gameDispatch] = useReducer(gameReducer, initialGameState);
const fileInputRef = useRef<HTMLInputElement | null>(null);
const handleSavePgn = () => {
const pgnString = buildPgnString(gameState);
downloadString(pgnString, "game.pgn");
};
const handleSavePdf = () => {
console.log("Save PDF");
};
const handleClearGame = () => {
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
gameDispatch({
type: "CLEAR_GAME",
});
};
const handleLoadPgn = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
const selectedFile = e.target.files?.[0];
if (selectedFile?.name.endsWith(".pgn")) {
const reader = new FileReader();
reader.onload = (event) => {
const pgnData = event.target?.result;
let pgnString = "";
if (pgnData) {
if (typeof pgnData === "string") {
pgnString = pgnData;
} else {
pgnString = new TextDecoder().decode(pgnData);
}
}
if (pgnString) {
const headers = {
...getHeaders(pgnString),
title: "",
subtitle: "",
};
gameDispatch({
type: "SET_GAME",
payload: { pgn: pgnString, headers: headers },
});
} else {
e.target.files = null;
handleClearGame();
}
};
reader.readAsText(selectedFile);
} else {
handleClearGame();
}
};
const chessGameProps = useChessGame();
return (
<Chessboard
gameState={gameState}
handleLoadPgn={handleLoadPgn}
handleClearGame={handleClearGame}
handleSavePgn={handleSavePgn}
handleSavePdf={handleSavePdf}
fileInputRef={fileInputRef}
gameState={chessGameProps.gameState}
handleLoadPgn={chessGameProps.handleLoadPgn}
handleClearGame={chessGameProps.handleClearGame}
handleSavePgn={chessGameProps.handleSavePgn}
handleSavePdf={chessGameProps.handleSavePdf}
fileInputRef={chessGameProps.fileInputRef}
/>
);
};
+1 -1
View File
@@ -28,7 +28,7 @@ export interface IGameState {
}
type GameAction =
| { type: "SET_GAME"; payload: { pgn: string; headers: "" } }
| { type: "SET_GAME"; payload: { pgn: string; headers: IHeader } }
| { type: "CLEAR_GAME" }
| { type: "SET_HEADERS"; payload: IHeader }
| { type: "ADD_DIAGRAM"; payload: IDiagrams }