Game settings and better socket performance

- Added game settings
- Reworked GamePropsSchema for only relevant information
-> Prisma schema and zod object
- Imporved toast notifications
- No duplicate socket connections anymore
- Using now Zustand for the gameProps instead of React Context & State
This commit is contained in:
aronmal 2023-05-10 20:54:52 +02:00
parent 12295b316f
commit 61ae4b901d
Signed by: aronmal
GPG key ID: 816B7707426FC612
31 changed files with 652 additions and 350 deletions

View file

@ -3,38 +3,69 @@ import {
faToggleLargeOn,
} from "@fortawesome/pro-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { useGameProps } from "@hooks/useGameProps"
import { socket } from "@lib/socket"
import classNames from "classnames"
import { ReactNode, useMemo } from "react"
import { toast } from "react-toastify"
type GameSettingKeys =
| "allowSpectators"
| "allowSpecials"
| "allowChat"
| "allowMarkDraw"
export type GameSettings = { [key in GameSettingKeys]?: boolean }
export const gameSetting = (payload: GameSettings) => {
socket.emit("gameSetting", payload, ({ ack }) => {
if (ack) return
toast.warn("Something is wrong... ", {
toastId: "st_wrong",
theme: "colored",
})
})
}
function Setting({
props: { key, state, onClick },
children,
prop,
}: {
props: {
key: string
state: boolean
onClick: () => void
}
children: ReactNode
prop: GameSettingKeys
}) {
const { payload, setSetting } = useGameProps()
const state = useMemo(() => payload?.game?.[prop], [payload?.game, prop])
return (
<label className="flex items-center justify-between" htmlFor={key}>
<label className="flex items-center justify-between" htmlFor={prop}>
<span className="col-span-2 w-96 select-none text-5xl text-white drop-shadow-md">
{key}
{children}
</span>
<FontAwesomeIcon
className={classNames(
"text-md mx-auto w-24 rounded-full px-4 drop-shadow-md transition-all",
"text-md mx-auto rounded-full px-4 drop-shadow-md transition-all",
state ? "text-blue-500" : "text-gray-800",
{
"bg-gray-300 ": state,
}
)}
size="3x"
icon={state ? faToggleLargeOn : faToggleLargeOff}
/>
<input
className="bg-none"
checked={state}
type="checkbox"
id={key}
onChange={onClick}
id={prop}
onChange={() => {
const payload = {
[prop]: !state,
}
setSetting(payload)
gameSetting(payload)
}}
hidden={true}
/>
</label>