From f7836a331775bff8a8da2868ea1c28d5de5fc104 Mon Sep 17 00:00:00 2001 From: ymmot239 Date: Tue, 9 Sep 2025 10:42:38 -0500 Subject: [PATCH 01/11] Added pause dialogs added pause dialogs and messages to handle the client-side pause notification --- src/client/game/admin-dialogs.tsx | 31 +++++++++++++++++++++++++++++++ src/client/game/game.tsx | 28 ++++++++++++++++++++++++---- src/common/game-end-reasons.ts | 2 ++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 src/client/game/admin-dialogs.tsx diff --git a/src/client/game/admin-dialogs.tsx b/src/client/game/admin-dialogs.tsx new file mode 100644 index 00000000..d969431a --- /dev/null +++ b/src/client/game/admin-dialogs.tsx @@ -0,0 +1,31 @@ +import { Dialog, DialogBody, NonIdealState } from "@blueprintjs/core"; +import { useState } from "react"; +import { bgColor, textColor } from "../check-dark-mode"; + +interface DrawDialogProps { + dialogText: string; +} + +/** + * Shows a paused dialog that cannot be closed + * @param props - dialog text + * @returns - draw dialog + */ +export function PauseDialog(props: DrawDialogProps) { + const [isOpen, setIsOpen] = useState(true); + return ( + setIsOpen(false)} + canOutsideClickClose={false} + canEscapeKeyClose={false} + > + + +

{props.dialogText || "Game Paused"}

+
+
+
+ ); +} \ No newline at end of file diff --git a/src/client/game/game.tsx b/src/client/game/game.tsx index 74c0dcb0..57a4f66b 100644 --- a/src/client/game/game.tsx +++ b/src/client/game/game.tsx @@ -27,6 +27,7 @@ import { NonIdealState, Spinner } from "@blueprintjs/core"; import { AcceptDrawDialog, OfferDrawDialog } from "./draw-dialog"; import { bgColor } from "../check-dark-mode"; import "../colors.css"; +import { PauseDialog } from "./admin-dialogs"; /** * Creates a MessageHandler function to handle move messages and game interruptions. @@ -40,6 +41,7 @@ function getMessageHandler( setGameInterruptedReason: Dispatch, setGameEndedReason: Dispatch, setGameHoldReason: Dispatch, + setPaused : Dispatch, ): MessageHandler { return (message) => { if (message instanceof MoveMessage) { @@ -62,6 +64,11 @@ function getMessageHandler( setGameEndedReason(message.reason); } else if (message instanceof GameHoldMessage) { setGameHoldReason(message.reason); + if(message.reason === GameHoldReason.GAME_PAUSED){ + setPaused(true); + } else if(message.reason === GameHoldReason.GAME_UNPAUSED){ + setPaused(false); + } } }; } @@ -77,6 +84,7 @@ export function Game(): JSX.Element { const [gameEndedReason, setGameEndedReason] = useState(); const [gameHoldReason, setGameHoldReason] = useState(); const [rotation, setRotation] = useState(0); + const [paused, setPause] = useState(false); /** send any messages using our defined message handler inside a message socket for handling */ const sendMessage = useSocket( @@ -86,6 +94,7 @@ export function Game(): JSX.Element { setGameInterruptedReason, setGameEndedReason, setGameHoldReason, + setPause, ), ); @@ -136,6 +145,7 @@ export function Game(): JSX.Element { gameEndReason !== undefined ? : null; + const gameOfferDialog = gameHoldReason !== undefined ? gameHoldReason === GameHoldReason.DRAW_CONFIRMATION ? @@ -150,11 +160,20 @@ export function Game(): JSX.Element { : null : null; + const gamePauseDialog = + gameHoldReason !== undefined ? + gameHoldReason === GameHoldReason.GAME_PAUSED ? + + : null + : null; + /** make moves by making a copy of the chessboard and sending the move message */ - const handleMove = (move: Move): void => { - setChess(chess.copy(move)); - sendMessage(new MoveMessage(move)); - }; + const handleMove = paused? + (move: Move): void => { + setChess(chess.copy(move)); + sendMessage(new MoveMessage(move)); + } + : (move:Move):void => {move;}; //send a do-nothing function if game is paused // return the chessboard wrapper, navbar, and potential end dialog return ( @@ -176,6 +195,7 @@ export function Game(): JSX.Element { {gameEndDialog} {gameOfferDialog} {gameAcceptDialog} + {gamePauseDialog} diff --git a/src/common/game-end-reasons.ts b/src/common/game-end-reasons.ts index 8a20a22a..7b6c67cc 100644 --- a/src/common/game-end-reasons.ts +++ b/src/common/game-end-reasons.ts @@ -40,4 +40,6 @@ export enum GameHoldReason { DRAW_OFFERED = "draw-offered", DRAW_CONFIRMATION = "draw-confirmation", DRAW_DENIED = "draw-denied", + GAME_PAUSED = "game-paused", + GAME_UNPAUSED = "game-unpaused", } From cafcf45e66a71f6bbd1a6f8e5c81830da2e095fb Mon Sep 17 00:00:00 2001 From: ymmot239 Date: Tue, 9 Sep 2025 10:53:33 -0500 Subject: [PATCH 02/11] Notification dialog Added a notification dialog to give the user information eg. game has been unpaused, puzzle info, line changes, etc. --- src/client/game/admin-dialogs.tsx | 63 ++++++++++++++++++++++++++++--- src/client/game/game.tsx | 12 +++++- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/client/game/admin-dialogs.tsx b/src/client/game/admin-dialogs.tsx index d969431a..b5e6346f 100644 --- a/src/client/game/admin-dialogs.tsx +++ b/src/client/game/admin-dialogs.tsx @@ -1,15 +1,21 @@ -import { Dialog, DialogBody, NonIdealState } from "@blueprintjs/core"; +import { + Button, + Dialog, + DialogBody, + DialogFooter, + NonIdealState, +} from "@blueprintjs/core"; import { useState } from "react"; -import { bgColor, textColor } from "../check-dark-mode"; +import { bgColor, buttonColor, textColor } from "../check-dark-mode"; interface DrawDialogProps { - dialogText: string; + dialogText?: string; } /** * Shows a paused dialog that cannot be closed * @param props - dialog text - * @returns - draw dialog + * @returns - pause dialog */ export function PauseDialog(props: DrawDialogProps) { const [isOpen, setIsOpen] = useState(true); @@ -23,9 +29,54 @@ export function PauseDialog(props: DrawDialogProps) { > -

{props.dialogText || "Game Paused"}

+

+ {props.dialogText || "Game Paused"} +

+
+
+ + ); +} + +interface NotificationDialogProps { + dialogText: string; +} + +/** + * SHows a closable notification dialog + * @param props - dialog text + * @returns - notification dialog + */ +export function NotificationDialog(props: NotificationDialogProps) { + const [isOpen, setIsOpen] = useState(true); + + /** okay button */ + const actions = ( +