diff --git a/src/hooks/useChessGame.ts b/src/hooks/useChessGame.ts new file mode 100644 index 0000000..d52969f --- /dev/null +++ b/src/hooks/useChessGame.ts @@ -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(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) => { + 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, + }; +}; diff --git a/src/pages/Chessboard.container.tsx b/src/pages/Chessboard.container.tsx index ef6f687..fdb3c15 100644 --- a/src/pages/Chessboard.container.tsx +++ b/src/pages/Chessboard.container.tsx @@ -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(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) => { - 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 ( ); }; diff --git a/src/reducers/gameReducer.ts b/src/reducers/gameReducer.ts index c253ec7..761f12d 100644 --- a/src/reducers/gameReducer.ts +++ b/src/reducers/gameReducer.ts @@ -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 }