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 && (
(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/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 3aa7ef2..9fc9331 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;
@@ -48,14 +54,14 @@ const GamePage = () => {
-
{isReady && }
-
+
@@ -63,6 +69,35 @@ const GamePage = () => {
);
};
+/**
+ * Quick hack to reuse hand-container for offline
+ * */
+const HandWrapper = ({
+ setModalType,
+}: {
+ setModalType: Dispatch>;
+}) => {
+ const { gameState, setPlayerState } = useWebGame();
+ return (
+
+ );
+};
+
+const ModalWrapper = (props: {
+ isOpen: boolean;
+ modalType: ModalType;
+ setModalType: (type: ModalType) => void;
+}) => {
+ const { gameState, setPlayerState } = useWebGame();
+ return (
+
+ );
+};
+
export default GamePage;
const BoardContainer = ({ self }: { self: string }) => {
diff --git a/pages/offline.tsx b/pages/offline.tsx
new file mode 100644
index 0000000..1025de7
--- /dev/null
+++ b/pages/offline.tsx
@@ -0,0 +1,133 @@
+import { HandContainer, ModalContainer } from "@/components/Game";
+import { useLocalDeckStorage } from "@/lib/hooks";
+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 { 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 players = gameState?.content?.players as Record<
+ string,
+ { pool?: PoolType }
+ >;
+ const playerState = players?.["offline"]?.pool;
+
+ const [modalType, setModalType] = useState(false);
+ const disclosure = useDisclosure();
+
+ function setPlayerState() {
+ return (props: { pool: PoolType }) => {
+ 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]);
+
+ 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 (
+
+
+
+
+
+ );
+};
+
+export default Offline;