From 81c5c9c36cc970afe8c2f6557f6a9a02ffc150b8 Mon Sep 17 00:00:00 2001 From: jollygrin Date: Sat, 30 Mar 2024 21:39:21 +0100 Subject: [PATCH 1/4] add page --- pages/offline.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 pages/offline.tsx diff --git a/pages/offline.tsx b/pages/offline.tsx new file mode 100644 index 0000000..261786f --- /dev/null +++ b/pages/offline.tsx @@ -0,0 +1,15 @@ +import { useLocalDeckStorage } from "@/lib/hooks"; +import { Box } from "@chakra-ui/react"; + +const Offline = () => { + const { star, decks } = useLocalDeckStorage(); + const deck = decks?.find((deck) => deck.id === star); + + return ( + + dhjska + + ); +}; + +export default Offline; From b55b731b1b974a2d4ba2b4199b2963546b0ebe7e Mon Sep 17 00:00:00 2001 From: jollygrin Date: Sat, 30 Mar 2024 22:41:47 +0100 Subject: [PATCH 2/4] refactor to reuse components --- components/Game/Hand/hand.container.tsx | 12 ++++- pages/game.tsx | 24 +++++++++- pages/offline.tsx | 58 ++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/components/Game/Hand/hand.container.tsx b/components/Game/Hand/hand.container.tsx index 069e67b..4b95c7a 100644 --- a/components/Game/Hand/hand.container.tsx +++ b/components/Game/Hand/hand.container.tsx @@ -9,7 +9,6 @@ import { newPool, shuffleDeck, } from "@/components/DeckPool/PoolFns"; -import { useWebGame } from "@/lib/contexts/WebGameProvider"; import { useLocalDeckStorage } from "@/lib/hooks/useLocalStorage"; import { Box, Flex, Grid } from "@chakra-ui/react"; import { useRouter } from "next/router"; @@ -19,17 +18,26 @@ import styled from "@emotion/styled"; import { flow } from "lodash"; import { ModalType } from "@/pages/game"; import { CloseIcon } from "@chakra-ui/icons"; +import { WebsocketMessage } from "@/lib/gamesocket/message"; + +type GameData = { + gameState: WebsocketMessage | undefined; + setPlayerState: () => (props: { pool: PoolType }) => void; +}; export const HandContainer = ({ setModal, + gameState, + setPlayerState, }: { setModal: (type: ModalType) => void; + gameState: GameData["gameState"]; + setPlayerState: GameData["setPlayerState"]; }) => { const localName = useRouter().query?.name; const player = Array.isArray(localName) ? localName[0] : localName; const { starredDeck } = useLocalDeckStorage(); - const { gameState, setPlayerState } = useWebGame(); const players = gameState?.content?.players as Record< string, { pool?: PoolType } diff --git a/pages/game.tsx b/pages/game.tsx index 3aa7ef2..0aa3a33 100644 --- a/pages/game.tsx +++ b/pages/game.tsx @@ -11,7 +11,13 @@ import { WebGameProvider, useWebGame } from "@/lib/contexts/WebGameProvider"; import useDelayedTrue from "@/lib/hooks/useDelay"; import { Box, useDisclosure } from "@chakra-ui/react"; import { useRouter } from "next/router"; -import { useCallback, useEffect, useState } from "react"; +import { + Dispatch, + SetStateAction, + useCallback, + useEffect, + useState, +} from "react"; export type ModalType = "hand" | "discard" | "deck" | "commit" | false; @@ -55,7 +61,7 @@ const GamePage = () => { /> {isReady && } - + @@ -63,6 +69,20 @@ const GamePage = () => { ); }; +/** + * Quick hack to reuse hand-container for offline + * */ +const HandWrapper = ({ + setModalType, +}: { + setModalType: Dispatch>; +}) => { + const { gameState, setPlayerState } = useWebGame(); + return ( + + ); +}; + export default GamePage; const BoardContainer = ({ self }: { self: string }) => { diff --git a/pages/offline.tsx b/pages/offline.tsx index 261786f..8e88cb6 100644 --- a/pages/offline.tsx +++ b/pages/offline.tsx @@ -1,13 +1,69 @@ +import { HandContainer } from "@/components/Game"; import { useLocalDeckStorage } from "@/lib/hooks"; import { Box } from "@chakra-ui/react"; +import { useEffect, useMemo, useState } from "react"; +import { ModalType } from "./game"; +import { PoolType, newPool } from "@/components/DeckPool/PoolFns"; +import { GameState, WebsocketMessage } from "@/lib/gamesocket/message"; +import { DeckImportType } from "@/components/DeckPool/deck-import.type"; +import { useRouter } from "next/router"; + +const initGamestate: GameState = { + last_updated: "foobar", + gid: "offline", + players: { + offline: { pool: undefined }, + }, +}; +const init: WebsocketMessage = { + error: "", + msgtype: "offline", + content: initGamestate, +}; const Offline = () => { + const { push, query } = useRouter(); const { star, decks } = useLocalDeckStorage(); const deck = decks?.find((deck) => deck.id === star); + const newDeck = useMemo(() => (deck ? newPool(deck) : undefined), [deck]); + + const [gameState, setGameState] = useState(init); + + const [modalType, setModalType] = useState(); + + function setPlayerState() { + console.log("1"); + return (props: { pool: PoolType }) => { + console.log("2"); + setGameState((prev) => ({ + ...prev, + content: { + ...prev.content, + players: { + offline: { pool: props.pool }, + }, + } as GameState, + })); + }; + } + + useEffect(() => { + if (query.name) return; + push({ query: { name: "offline" } }); + }, []); + + useEffect(() => { + if (!newDeck) return; + setPlayerState()({ pool: newDeck }); + }, [newDeck]); return ( - dhjska + ); }; From cdd90d866a9200db983a6015fd641bb30cb81a63 Mon Sep 17 00:00:00 2001 From: jollygrin Date: Sat, 30 Mar 2024 23:31:02 +0100 Subject: [PATCH 3/4] barely working offline page --- components/Game/game.modal-template.tsx | 7 ++- pages/game.tsx | 17 ++++- pages/offline.tsx | 82 ++++++++++++++++++++++--- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/components/Game/game.modal-template.tsx b/components/Game/game.modal-template.tsx index 6426846..9761816 100644 --- a/components/Game/game.modal-template.tsx +++ b/components/Game/game.modal-template.tsx @@ -27,20 +27,24 @@ import { useRouter } from "next/router"; import { DeckImportCardType } from "../DeckPool/deck-import.type"; import { flow } from "lodash"; import { toast } from "react-hot-toast"; +import { WebsocketMessage } from "@/lib/gamesocket/message"; type ModalTemplateType = { isOpen: boolean; modalType: ModalType; setModalType: (type: ModalType) => void; + gameState: WebsocketMessage | undefined; + setPlayerState: () => (props: { pool: PoolType }) => void; }; export const ModalContainer: React.FC = ({ isOpen, modalType, setModalType, + gameState, + setPlayerState, }) => { const isCommit = modalType === "commit"; const player = useRouter().query?.name as string; - const { gameState, setPlayerState } = useWebGame(); const players = gameState?.content?.players as Record< string, { pool?: PoolType } @@ -117,6 +121,7 @@ export const ModalContainer: React.FC = ({ }), ); + console.log({ modalType, isOpen }); return ( <> !isCommit && onClose()}> diff --git a/pages/game.tsx b/pages/game.tsx index 0aa3a33..9fc9331 100644 --- a/pages/game.tsx +++ b/pages/game.tsx @@ -54,7 +54,7 @@ const GamePage = () => { - void; +}) => { + const { gameState, setPlayerState } = useWebGame(); + return ( + + ); +}; + export default GamePage; const BoardContainer = ({ self }: { self: string }) => { diff --git a/pages/offline.tsx b/pages/offline.tsx index 8e88cb6..1025de7 100644 --- a/pages/offline.tsx +++ b/pages/offline.tsx @@ -1,11 +1,19 @@ -import { HandContainer } from "@/components/Game"; +import { HandContainer, ModalContainer } from "@/components/Game"; import { useLocalDeckStorage } from "@/lib/hooks"; -import { Box } from "@chakra-ui/react"; +import { + Box, + Button, + Divider, + HStack, + Input, + Text, + VStack, + useDisclosure, +} from "@chakra-ui/react"; import { useEffect, useMemo, useState } from "react"; import { ModalType } from "./game"; import { PoolType, newPool } from "@/components/DeckPool/PoolFns"; import { GameState, WebsocketMessage } from "@/lib/gamesocket/message"; -import { DeckImportType } from "@/components/DeckPool/deck-import.type"; import { useRouter } from "next/router"; const initGamestate: GameState = { @@ -28,13 +36,17 @@ const Offline = () => { const newDeck = useMemo(() => (deck ? newPool(deck) : undefined), [deck]); const [gameState, setGameState] = useState(init); + const players = gameState?.content?.players as Record< + string, + { pool?: PoolType } + >; + const playerState = players?.["offline"]?.pool; - const [modalType, setModalType] = useState(); + const [modalType, setModalType] = useState(false); + const disclosure = useDisclosure(); function setPlayerState() { - console.log("1"); return (props: { pool: PoolType }) => { - console.log("2"); setGameState((prev) => ({ ...prev, content: { @@ -57,14 +69,64 @@ const Offline = () => { setPlayerState()({ pool: newDeck }); }, [newDeck]); + useEffect(() => { + if (modalType) { + disclosure.onOpen(); + } else { + disclosure.onClose(); + } + }, [modalType, disclosure]); + return ( - - + - + + + + + {playerState?.hero?.name} + hp:{playerState?.hero?.hp} + move:{playerState?.hero?.move} + {playerState?.hero?.isRanged ? "Ranged" : "Melee"} + + + {playerState?.sidekick?.name} + hp:{playerState?.sidekick?.hp} + quantity:{playerState?.sidekick?.quantity} + {playerState?.sidekick?.isRanged ? "Ranged" : "Melee"} + + {playerState?.hero?.specialAbility} + {playerState?.sidekick?.quote} + + + + + + + + + + ); +}; + +const HpButton = (props: { state?: number }) => { + const [hp, setHp] = useState(props?.state ?? 0); + return ( + + + + + ); }; From 048d2334f0a1c43dc85b888b03d6a87fb443b717 Mon Sep 17 00:00:00 2001 From: jollygrin Date: Sat, 30 Mar 2024 23:33:05 +0100 Subject: [PATCH 4/4] add offline connect --- components/Connect/index.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/Connect/index.tsx b/components/Connect/index.tsx index 3a63f37..25e7224 100644 --- a/components/Connect/index.tsx +++ b/components/Connect/index.tsx @@ -27,6 +27,7 @@ import styled from "@emotion/styled"; import { PlusSquareIcon } from "@chakra-ui/icons"; import { useCopyToClipboard } from "@/lib/hooks/useCopyToClipboard"; import { toast } from "react-hot-toast"; +import Link from "next/link"; export const ConnectPage = () => { const router = useRouter(); @@ -111,6 +112,9 @@ export const ConnectPage = () => { {loading && } Connect to Game + {sharedDeckId === undefined && (