Some repatches
This commit is contained in:
parent
dab3abdda2
commit
c895bcef19
10 changed files with 106 additions and 42 deletions
|
@ -1,18 +1,17 @@
|
||||||
import { gameContext } from "../../pages/_app"
|
|
||||||
import Icon from "./Icon"
|
import Icon from "./Icon"
|
||||||
import Player from "./Player"
|
import Player from "./Player"
|
||||||
import { Fragment, useContext, useEffect, useState } from "react"
|
import useGameState from "@lib/hooks/useGameState"
|
||||||
|
import { Fragment, useEffect, useState } from "react"
|
||||||
|
|
||||||
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
||||||
const [gameProps, setGameProps] = useContext(gameContext)
|
const { gameProps } = useGameState()
|
||||||
const { enemy } = gameProps
|
|
||||||
const [dots, setDots] = useState(1)
|
const [dots, setDots] = useState(1)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (enemy) return
|
if (gameProps.enemy) 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)
|
||||||
}, [enemy])
|
}, [gameProps.enemy])
|
||||||
|
|
||||||
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">
|
||||||
|
@ -33,8 +32,11 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
|
||||||
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>
|
||||||
{enemy ? (
|
{gameProps.enemy ? (
|
||||||
<Player src="player_red.png" text={enemy.name ?? "Spieler 2"} />
|
<Player
|
||||||
|
src="player_red.png"
|
||||||
|
text={gameProps.enemy.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,4 +1,4 @@
|
||||||
import logging, { Logging } from "../logging"
|
import logging, { Logging } from "./logging"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
|
||||||
export interface Result<T> {
|
export interface Result<T> {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { GameState } from "@prisma/client"
|
||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
export const createSchema = z.object({
|
export const createSchema = z.object({
|
||||||
|
@ -5,7 +6,7 @@ export const createSchema = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
createdAt: z.date(),
|
createdAt: z.date(),
|
||||||
updatedAt: z.date(),
|
updatedAt: z.date(),
|
||||||
running: z.boolean(),
|
state: z.nativeEnum(GameState),
|
||||||
}),
|
}),
|
||||||
pin: z.string().optional(),
|
pin: z.string().optional(),
|
||||||
player: z.object({
|
player: z.object({
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import "../styles/App.scss"
|
import "../styles/App.scss"
|
||||||
import "../styles/globals.css"
|
import "../styles/globals.scss"
|
||||||
import "../styles/grid2.scss"
|
import "../styles/grid2.scss"
|
||||||
import "../styles/grid.scss"
|
import "../styles/grid.scss"
|
||||||
import { SessionProvider } from "next-auth/react"
|
import { SessionProvider } from "next-auth/react"
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
uniqueNamesGenerator,
|
uniqueNamesGenerator,
|
||||||
Config,
|
Config,
|
||||||
adjectives,
|
adjectives,
|
||||||
colors,
|
|
||||||
animals,
|
animals,
|
||||||
NumberDictionary,
|
NumberDictionary,
|
||||||
} from "unique-names-generator"
|
} from "unique-names-generator"
|
||||||
|
@ -22,7 +21,6 @@ const customConfig: Config = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const options: NextAuthOptions = {
|
const options: NextAuthOptions = {
|
||||||
debug: true,
|
|
||||||
providers: [
|
providers: [
|
||||||
EmailProvider({
|
EmailProvider({
|
||||||
server: process.env.EMAIL_SERVER,
|
server: process.env.EMAIL_SERVER,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { authOptions } from "../auth/[...nextauth]"
|
import { authOptions } from "../auth/[...nextauth]"
|
||||||
|
import { getAnyRunningGame } from "./running"
|
||||||
import sendResponse from "@backend/sendResponse"
|
import sendResponse from "@backend/sendResponse"
|
||||||
|
import { rejectionErrors } from "@lib/backend/errors"
|
||||||
import prisma from "@lib/prisma"
|
import prisma from "@lib/prisma"
|
||||||
import { createSchema } from "@lib/zodSchemas"
|
import { createSchema } from "@lib/zodSchemas"
|
||||||
import type { NextApiRequest, NextApiResponse } from "next"
|
import type { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
@ -14,20 +16,8 @@ export default async function create(
|
||||||
) {
|
) {
|
||||||
const session = await getServerSession(req, res, authOptions)
|
const session = await getServerSession(req, res, authOptions)
|
||||||
|
|
||||||
if (!session) {
|
if (!session?.user) {
|
||||||
return sendResponse(req, res, {
|
return sendResponse(req, res, rejectionErrors.unauthorized)
|
||||||
message: "Unauthorized",
|
|
||||||
statusCode: 401,
|
|
||||||
type: ["error"],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!session.user) {
|
|
||||||
return sendResponse(req, res, {
|
|
||||||
message: "Unauthorized - No User",
|
|
||||||
statusCode: 401,
|
|
||||||
type: ["error"],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
const { email, id, name } = session.user
|
const { email, id, name } = session.user
|
||||||
|
|
||||||
|
@ -38,20 +28,7 @@ export default async function create(
|
||||||
|
|
||||||
let created = false
|
let created = false
|
||||||
|
|
||||||
let game = await prisma.game.findFirst({
|
let game = await getAnyRunningGame(id)
|
||||||
where: {
|
|
||||||
running: true,
|
|
||||||
users: {
|
|
||||||
some: {
|
|
||||||
userId: id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
gamePin: true,
|
|
||||||
users: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (!game) {
|
if (!game) {
|
||||||
created = true
|
created = true
|
||||||
game = await prisma.game.create({
|
game = await prisma.game.create({
|
||||||
|
|
58
leaky-ships/pages/api/game/running.ts
Normal file
58
leaky-ships/pages/api/game/running.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import { authOptions } from "../auth/[...nextauth]"
|
||||||
|
import sendResponse from "@backend/sendResponse"
|
||||||
|
import { rejectionErrors } from "@lib/backend/errors"
|
||||||
|
import prisma from "@lib/prisma"
|
||||||
|
import { Game } from "@prisma/client"
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
import { getServerSession } from "next-auth"
|
||||||
|
|
||||||
|
type Data = { game: Game }
|
||||||
|
|
||||||
|
export const getAnyRunningGame = (id: string) =>
|
||||||
|
prisma.game.findFirst({
|
||||||
|
where: {
|
||||||
|
NOT: {
|
||||||
|
state: "ended",
|
||||||
|
},
|
||||||
|
users: {
|
||||||
|
some: {
|
||||||
|
userId: id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
gamePin: true,
|
||||||
|
users: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default async function create(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse<Data>
|
||||||
|
) {
|
||||||
|
const session = await getServerSession(req, res, authOptions)
|
||||||
|
|
||||||
|
if (!session?.user) {
|
||||||
|
return sendResponse(req, res, rejectionErrors.unauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { email, id } = session.user
|
||||||
|
|
||||||
|
const game = await getAnyRunningGame(id)
|
||||||
|
|
||||||
|
if (!game)
|
||||||
|
return sendResponse(req, res, {
|
||||||
|
message: `User <${email}> is in no game.`,
|
||||||
|
statusCode: 204,
|
||||||
|
type: ["debug", "infoCyan"],
|
||||||
|
})
|
||||||
|
|
||||||
|
return sendResponse(req, res, {
|
||||||
|
message: `User <${email}> asked for game: ${game.id}`,
|
||||||
|
statusCode: 200,
|
||||||
|
body: {
|
||||||
|
game,
|
||||||
|
},
|
||||||
|
type: ["debug", "infoCyan"],
|
||||||
|
})
|
||||||
|
}
|
|
@ -35,6 +35,19 @@ export function isAuthenticated(res: Response) {
|
||||||
return Promise.reject()
|
return Promise.reject()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleConfirmation = () => {
|
||||||
|
const toastId = "confirm"
|
||||||
|
toast.warn(
|
||||||
|
<div id="toast-confirm">
|
||||||
|
<h4>You are already in another round, do you want to:</h4>
|
||||||
|
<button onClick={() => toast.dismiss(toastId)}>Join</button>
|
||||||
|
or
|
||||||
|
<button onClick={() => toast.dismiss(toastId)}>Leave</button>
|
||||||
|
</div>,
|
||||||
|
{ autoClose: false, toastId }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default function Home({ q }: Props) {
|
export default function Home({ q }: Props) {
|
||||||
const [otp, setOtp] = useState("")
|
const [otp, setOtp] = useState("")
|
||||||
const { gameProps, setGameProps } = useGameState()
|
const { gameProps, setGameProps } = useGameState()
|
||||||
|
|
|
@ -69,11 +69,17 @@ enum TokenType {
|
||||||
ACCESS
|
ACCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GameState {
|
||||||
|
launching
|
||||||
|
running
|
||||||
|
ended
|
||||||
|
}
|
||||||
|
|
||||||
model Game {
|
model Game {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
running Boolean @default(true)
|
state GameState @default(launching)
|
||||||
gamePin Gamepin?
|
gamePin Gamepin?
|
||||||
users User_Game[]
|
users User_Game[]
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,15 @@ button {
|
||||||
cursor: none;
|
cursor: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#toast-confirm {
|
||||||
|
button {
|
||||||
|
margin: 0 1rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
border: 2px solid gray;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (pointer: fine) {
|
@media (pointer: fine) {
|
||||||
button {
|
button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
Loading…
Add table
Add a link
Reference in a new issue