diff --git a/README.md b/README.md index caa47fa..bd0c694 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,6 @@ This aims to recreate unbrewed.xyz but with ~~webrtc~~ and typescript. ~~This wi Update: ditching pure p2p and now instead making the gameserver easily deployable by anyone, and be able to change gameserver in settings. -- [x] setup typescript: to auto-document code -- [x] setup jest (unit tests): to make refactoring and PRs easier -- [x] add interactive board -- [x] add card template -- [x] add board state (hand, discard, deck) -- [x] add game actions -- [x] add backpack (to load decks/maps in localstorage) -- [x] add optional api server for loading decks from unmatched (add fallback if url breaks and ability to load a different server url) -- [x] add websocket for board piece movements (dragging pawns across the board) -- [x] add ability to add your own game board svgs -- [ ] add landing page with instructions how to use tool, even if have never touched terminal -- [ ] improve docs ## Run Locally @@ -55,9 +43,9 @@ Want to deploy a gameserver that exists 24/7? Add an issue to github or PR so we - [JonG](https://github.com/JonathanGuberman), creator of [ unmatched.cards](https://unmatched.cards/) (create your own unmatched deck), [created the styling for the card template](https://github.com/JonathanGuberman/unmatched_maker/blob/a7e96b69559461bfac7d3203d8d3899d4af36398/src/components/UnmatchedCard.vue) - [Michal Wrzosek](https://github.com/michal-wrzosek), creator of [pitu pitu chat](https://michal-wrzosek.github.io/p2p-chat/) -# Goals +--- -## Journal +# Journal ### 2024-03-13 diff --git a/lib/hooks/useUnmatchedDeck.ts b/lib/hooks/useUnmatchedDeck.ts index c1ee82c..c143e2d 100644 --- a/lib/hooks/useUnmatchedDeck.ts +++ b/lib/hooks/useUnmatchedDeck.ts @@ -1,9 +1,11 @@ import { DeckImportType } from "@/components/DeckPool/deck-import.type"; import { useQuery } from "@tanstack/react-query"; import axios from "axios"; -import { useState } from "react"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { useDebounce } from "use-debounce"; +import { useLocalDeckStorage } from "./useLocalStorage"; export const useUnmatchedDeck = () => { const [deckId, setDeckId] = useState(); @@ -41,3 +43,53 @@ export const useUnmatchedDeck = () => { setApiUrl, }; }; + +/** + * Load the deckId from router.query and star it + * useful for quickly loading and jumping into a game + * this can be dropped in without props as it pulls from the url bar + * and manipulates localstorage + * */ +export const useLoadRouterDeck = () => { + const { query } = useRouter(); + const deckId = query.deckId as string | undefined; + + const { data, setDeckId } = useUnmatchedDeck(); + const { decks, pushDeck, setStar, star } = useLocalDeckStorage(); + + useEffect(() => { + if (!deckId) return; + + // check if query.deckId is one of the existing local decks + const deckIdsInStorage = decks + ?.map((deck) => [deck.id, deck.version_id]) + .flat(); + if (deckIdsInStorage?.includes(deckId)) { + // if it is, check the local decks for a matching id + const localDeck = decks?.find( + (deck) => deck.version_id === deckId || deck.id === deckId, + ); + + if (localDeck?.version_id !== deckId) { + toast.success("Refresh the page if you do not see your new deck"); + } + // star the local deck + if (localDeck) setStar(localDeck.id); + return; + } + + // if there's no local deck, set the deckId to fetch from api + setDeckId(deckId); + }, [deckId]); + + useEffect(() => { + if (!data) return; + if (!deckId) return; + console.log({ data, deckId }); + + // once api data is available, push the deck to local storage and star it + pushDeck(data); + setStar(data.id); + toast.success("Refresh the page if you do not see your new deck"); + }, [data]); +}; diff --git a/pages/404.tsx b/pages/404.tsx new file mode 100644 index 0000000..5678b01 --- /dev/null +++ b/pages/404.tsx @@ -0,0 +1,39 @@ +import { Grid, Text, VStack } from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { useEffect } from "react"; + +export default function Custom404() { + const router = useRouter(); + + // Handles the redirect from the old unbrewed online router + useEffect(() => { + const [_, online, lobby, user] = router.asPath.split("/"); + if (online !== "online") return; + const [username, deckId] = user?.split("?deck="); + router.push({ + pathname: "connect", + query: { + lobby, + username, + deckId, + }, + }); + }, [router.asPath]); + + return ( + + + + Whoops! + + This page does not exist! + + + ); +} +// online/fds/fds?deck=B4ZIGdn diff --git a/pages/connect.tsx b/pages/connect.tsx index bd1f3b6..7c55ced 100644 --- a/pages/connect.tsx +++ b/pages/connect.tsx @@ -21,6 +21,7 @@ import { import Link from "next/link"; import { SettingsModal } from "@/components/Settings/settings.modal"; import { toast } from "react-hot-toast"; +import { useLoadRouterDeck } from "@/lib/hooks"; const ConnectToGamePage = () => { return ; @@ -33,6 +34,8 @@ const ConnectPage = () => { const gidRef = useRef(null); const { isOpen, onClose, onOpen } = useDisclosure(); + useLoadRouterDeck(); + // the useQuery loading props not working on repeat visits const [loading, setLoading] = useState(false); @@ -124,8 +127,16 @@ const ConnectPage = () => { - - + +