Use React Context as in the first place
This commit is contained in:
parent
f97b3a622a
commit
2ed943857e
4 changed files with 56 additions and 18 deletions
|
@ -4,23 +4,21 @@ import useGameState from "@lib/hooks/useGameState"
|
||||||
import { Fragment, useEffect, useState } from "react"
|
import { Fragment, useEffect, useState } from "react"
|
||||||
|
|
||||||
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
||||||
const { gameProps } = useGameState()
|
const { payload } = useGameState().gameProps
|
||||||
const [dots, setDots] = useState(1)
|
const [dots, setDots] = useState(1)
|
||||||
|
|
||||||
const { gamePin, player1, player2 } = gameProps.payload
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (player2) return
|
if (payload?.player2) return
|
||||||
const interval = setInterval(() => setDots((e) => (e % 3) + 1), 1000)
|
const interval = setInterval(() => setDots((e) => (e % 3) + 1), 1000)
|
||||||
return () => clearInterval(interval)
|
return () => clearInterval(interval)
|
||||||
}, [player2])
|
}, [payload?.player2])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-32 flex flex-col self-stretch rounded-3xl bg-gray-400">
|
<div className="mx-32 flex flex-col self-stretch rounded-3xl bg-gray-400">
|
||||||
<div className="flex items-center justify-between border-b-2 border-slate-900">
|
<div className="flex items-center justify-between border-b-2 border-slate-900">
|
||||||
<Icon src="speech_bubble.png">Chat</Icon>
|
<Icon src="speech_bubble.png">Chat</Icon>
|
||||||
<h1 className="font-farro text-5xl font-medium">
|
<h1 className="font-farro text-5xl font-medium">
|
||||||
Game-PIN: <span className="underline">{gamePin?.pin}</span>
|
Game-PIN: <span className="underline">{payload?.gamePin?.pin}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<Icon src="gear.png" onClick={openSettings}>
|
<Icon src="gear.png" onClick={openSettings}>
|
||||||
Settings
|
Settings
|
||||||
|
@ -29,13 +27,16 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
||||||
<div className="flex items-center justify-around">
|
<div className="flex items-center justify-around">
|
||||||
<Player
|
<Player
|
||||||
src="player_blue.png"
|
src="player_blue.png"
|
||||||
text={player1?.name ?? "Spieler 1 (Du)"}
|
text={payload?.player1?.name ?? "Spieler 1 (Du)"}
|
||||||
primary={true}
|
primary={true}
|
||||||
edit={true}
|
edit={true}
|
||||||
/>
|
/>
|
||||||
<p className="font-farro m-4 text-6xl font-semibold">VS</p>
|
<p className="font-farro m-4 text-6xl font-semibold">VS</p>
|
||||||
{player2 ? (
|
{payload?.player2 ? (
|
||||||
<Player src="player_red.png" text={player2.name ?? "Spieler 2"} />
|
<Player
|
||||||
|
src="player_red.png"
|
||||||
|
text={payload?.player2.name ?? "Spieler 2"}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<p className="font-farro w-96 text-center text-4xl font-medium">
|
<p className="font-farro w-96 text-center text-4xl font-medium">
|
||||||
Warte auf Spieler 2 {Array.from(Array(dots), () => ".").join("")}
|
Warte auf Spieler 2 {Array.from(Array(dots), () => ".").join("")}
|
||||||
|
|
|
@ -1,14 +1,49 @@
|
||||||
import { GamePropsSchema } from "@lib/zodSchemas"
|
import { GamePropsSchema } from "@lib/zodSchemas"
|
||||||
import { useSession } from "next-auth/react"
|
import { useSession } from "next-auth/react"
|
||||||
import { useEffect, useState } from "react"
|
import {
|
||||||
|
Dispatch,
|
||||||
|
ReactNode,
|
||||||
|
SetStateAction,
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
useMemo,
|
||||||
|
} from "react"
|
||||||
import { toast } from "react-toastify"
|
import { toast } from "react-toastify"
|
||||||
|
|
||||||
function useGameState(initial?: GamePropsSchema) {
|
const initialValue = { payload: null, hash: null }
|
||||||
const [gameProps, setGameProps] = useState<GamePropsSchema>(
|
|
||||||
initial ?? { payload: {}, hash: "" }
|
interface gameContext {
|
||||||
|
gameProps: GamePropsSchema
|
||||||
|
setGameProps: Dispatch<SetStateAction<GamePropsSchema>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const gameContext = createContext<gameContext>({
|
||||||
|
gameProps: initialValue,
|
||||||
|
setGameProps: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
|
export function GameContextProvider({ children }: { children: ReactNode }) {
|
||||||
|
const [gameProps, setGameProps] = useState<GamePropsSchema>(initialValue)
|
||||||
|
|
||||||
|
const value = useMemo<gameContext>(
|
||||||
|
() => ({ gameProps, setGameProps }),
|
||||||
|
[gameProps, setGameProps]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return <gameContext.Provider value={value}>{children}</gameContext.Provider>
|
||||||
|
}
|
||||||
|
|
||||||
|
function useGameState(initial?: GamePropsSchema) {
|
||||||
|
const { gameProps, setGameProps } = useContext(gameContext)
|
||||||
const { data: session, status } = useSession()
|
const { data: session, status } = useSession()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!initial) return
|
||||||
|
setGameProps(initial)
|
||||||
|
}, [initial, setGameProps])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (status === "loading") return
|
if (status === "loading") return
|
||||||
if (!session)
|
if (!session)
|
||||||
|
|
|
@ -22,8 +22,8 @@ export const CreateSchema = z
|
||||||
.strict()
|
.strict()
|
||||||
|
|
||||||
export const GamePropsSchema = z.object({
|
export const GamePropsSchema = z.object({
|
||||||
payload: CreateSchema,
|
payload: CreateSchema.nullable(),
|
||||||
hash: z.string(),
|
hash: z.string().nullable(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type GamePropsSchema = z.infer<typeof GamePropsSchema>
|
export type GamePropsSchema = z.infer<typeof GamePropsSchema>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import "../styles/App.scss"
|
||||||
import "../styles/globals.scss"
|
import "../styles/globals.scss"
|
||||||
import "../styles/grid2.scss"
|
import "../styles/grid2.scss"
|
||||||
import "../styles/grid.scss"
|
import "../styles/grid.scss"
|
||||||
import { CreateSchema } from "@lib/zodSchemas"
|
import { GameContextProvider } from "@lib/hooks/useGameState"
|
||||||
import { SessionProvider } from "next-auth/react"
|
import { SessionProvider } from "next-auth/react"
|
||||||
import type { AppProps } from "next/app"
|
import type { AppProps } from "next/app"
|
||||||
import { ToastContainer } from "react-toastify"
|
import { ToastContainer } from "react-toastify"
|
||||||
|
@ -14,8 +14,10 @@ export default function App({
|
||||||
}: AppProps) {
|
}: AppProps) {
|
||||||
return (
|
return (
|
||||||
<SessionProvider session={session}>
|
<SessionProvider session={session}>
|
||||||
<Component {...pageProps} />
|
<GameContextProvider>
|
||||||
<ToastContainer />
|
<Component {...pageProps} />
|
||||||
|
<ToastContainer />
|
||||||
|
</GameContextProvider>
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue