From 33ec49c4c22d629901f5d6964d169dba43666f85 Mon Sep 17 00:00:00 2001 From: latenitecoding Date: Tue, 30 Jan 2024 11:38:29 -0600 Subject: [PATCH] feat: adds undo button --- src/components/react/ChessStudy.tsx | 63 ++++++++++++++++++++++-- src/components/react/PgnViewer/index.tsx | 9 +++- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/components/react/ChessStudy.tsx b/src/components/react/ChessStudy.tsx index db1b136..c7300b1 100644 --- a/src/components/react/ChessStudy.tsx +++ b/src/components/react/ChessStudy.tsx @@ -42,6 +42,7 @@ export interface GameState { export type GameActions = | { type: 'ADD_MOVE_TO_HISTORY'; move: Move } + | { type: 'REMOVE_LAST_MOVE_FROM_HISTORY' } | { type: 'DISPLAY_NEXT_MOVE_IN_HISTORY' } | { type: 'DISPLAY_PREVIOUS_MOVE_IN_HISTORY' } | { type: 'DISPLAY_SELECTED_MOVE_IN_HISTORY'; moveId: string } @@ -81,7 +82,7 @@ export const ChessStudy = ({ (draft, action) => { switch (action.type) { case 'DISPLAY_NEXT_MOVE_IN_HISTORY': { - if (!chessView) return draft; + if (!chessView || !draft || draft.study.moves.length == 0) return draft; displayMoveInHistory(draft, chessView, setChessLogic, { offset: 1, @@ -91,7 +92,7 @@ export const ChessStudy = ({ return draft; } case 'DISPLAY_PREVIOUS_MOVE_IN_HISTORY': { - if (!chessView) return draft; + if (!chessView || !draft || draft.study.moves.length == 0) return draft; displayMoveInHistory(draft, chessView, setChessLogic, { offset: -1, @@ -100,8 +101,57 @@ export const ChessStudy = ({ return draft; } + case 'REMOVE_LAST_MOVE_FROM_HISTORY': { + if (!chessView || !draft || draft.study.moves.length == 0) return draft; + + let moves = draft.study.moves; + + const currentMoveId = draft.currentMove?.moveId; + + const { variant, moveIndex } = findMoveIndex(moves, currentMoveId); + + if (variant) { + const parent = moves[variant.parentMoveIndex]; + const variantMoves = parent.variants[variant.variantIndex].moves; + + const isLastMove = moveIndex === variantMoves.length - 1; + + if (isLastMove) { + displayMoveInHistory(draft, chessView, setChessLogic, { + offset: -1, + selectedMoveId: currentMoveId, + }); + } + + variantMoves.pop(); + if (variantMoves.length == 0) { + parent.variants.splice(variant.variantIndex, 1); + } + + if (isLastMove) { + draft.currentMove = (variantMoves.length > 0) ? variantMoves[variantMoves.length - 1] : moves[variant.parentMoveIndex]; + } + } else { + const isLastMove = moveIndex === moves.length - 1; + + if (isLastMove) { + displayMoveInHistory(draft, chessView, setChessLogic, { + offset: -1, + selectedMoveId: currentMoveId, + }); + } + + moves.pop(); + + if (isLastMove) { + draft.currentMove = (moves.length > 0) ? moves[moves.length - 1] : null; + } + } + + return draft; + } case 'DISPLAY_SELECTED_MOVE_IN_HISTORY': { - if (!chessView) return draft; + if (!chessView || !draft || draft.study.moves.length == 0) return draft; const selectedMoveId = action.moveId; @@ -113,6 +163,8 @@ export const ChessStudy = ({ return draft; } case 'SYNC_SHAPES': { + if (!chessView || !draft || draft.study.moves.length == 0) return draft; + const move = getCurrentMove(draft); move.shapes = action.shapes; @@ -121,6 +173,8 @@ export const ChessStudy = ({ return draft; } case 'SYNC_COMMENT': { + if (!chessView || !draft || draft.study.moves.length == 0) return draft; + const move = getCurrentMove(draft); move.comment = action.comment; @@ -258,6 +312,9 @@ export const ChessStudy = ({ + dispatch({ type: 'REMOVE_LAST_MOVE_FROM_HISTORY' }) + } onBackButtonClick={() => dispatch({ type: 'DISPLAY_PREVIOUS_MOVE_IN_HISTORY' }) } diff --git a/src/components/react/PgnViewer/index.tsx b/src/components/react/PgnViewer/index.tsx index d4066dd..0dea7e9 100644 --- a/src/components/react/PgnViewer/index.tsx +++ b/src/components/react/PgnViewer/index.tsx @@ -1,4 +1,4 @@ -import { ArrowLeft, ArrowRight, Save } from 'lucide-react'; +import { ArrowLeft, ArrowRight, Save, Undo2 } from 'lucide-react'; import * as React from 'react'; import { ReactNode, useEffect, useMemo, useRef } from 'react'; import { ChessStudyMove } from 'src/lib/storage'; @@ -108,6 +108,7 @@ export const PgnViewer = React.memo( ({ history, currentMoveId, + onUndoButtonClick, onBackButtonClick, onForwardButtonClick, onMoveItemClick, @@ -115,6 +116,7 @@ export const PgnViewer = React.memo( }: { history: ChessStudyMove[]; currentMoveId: string; + onUndoButtonClick: () => void; onBackButtonClick: () => void; onForwardButtonClick: () => void; onMoveItemClick: (moveId: string) => void; @@ -268,12 +270,17 @@ export const PgnViewer = React.memo(
+ +
+