diff --git a/app/AppContext.tsx b/app/AppContext.tsx new file mode 100644 index 0000000..bffbcd9 --- /dev/null +++ b/app/AppContext.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { createContext, useContext, useState, ReactNode } from 'react'; +import type { AppContext, Tilt } from '@/types'; + +const AppContext = createContext(undefined); + +export function AppProvider({ children }: { children: ReactNode }) { + const [tilts, setTilts] = useState([]); + + return {children}; +} + +export function useAppContext(): AppContext { + const context = useContext(AppContext); + if (!context) throw new Error('useAppContext must be used within AppProvider'); + return context; +} diff --git a/app/layout.tsx b/app/layout.tsx index 7dfc1d0..7d38c1d 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import type { Metadata } from 'next'; import { Pirata_One, Eagle_Lake, Cinzel_Decorative } from 'next/font/google'; +import { AppProvider } from '@/app/AppContext'; import './globals.css'; const pirataOne = Pirata_One({ @@ -40,7 +41,9 @@ export default function RootLayout({ lang="en" className={`${pirataOne.variable} ${eagleLake.variable} ${cinzel.variable} antialiased`} > - {children} + + {children} + ); } diff --git a/components/Card.tsx b/components/Card.tsx index cbbf34d..52c979e 100644 --- a/components/Card.tsx +++ b/components/Card.tsx @@ -60,10 +60,11 @@ export default function Card({
{dm && ( diff --git a/components/TiltCard.tsx b/components/TiltCard.tsx index 8c16b54..8d80e08 100644 --- a/components/TiltCard.tsx +++ b/components/TiltCard.tsx @@ -1,18 +1,39 @@ -import { useRef } from 'react'; +import { useEffect, useRef } from 'react'; +import { useAppContext } from '@/app/AppContext'; export default function TiltCard({ children, + cardID, className = '', - onClick = () => {}, }: { children: React.ReactNode; + cardID: string; className?: string; - onClick: (event: React.MouseEvent) => void; }) { const cardRef = useRef(null); + const { tilts, setTilts } = useAppContext(); + + const card = cardRef.current; + + useEffect(() => { + if (!card) return; + + const tilt = tilts.find((tilt) => tilt.cardID === cardID); + if (!tilt) { + card.style.transform = `rotateX(0deg) rotateY(0deg)`; + return; + } + + const { rotateX, rotateY } = tilt; + + if (rotateX || rotateY) { + card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; + } else { + card.style.transform = `rotateX(0deg) rotateY(0deg)`; + } + }, [tilts]); const handleMouseMove = (e: React.MouseEvent) => { - const card = cardRef.current; if (!card) return; const rect = card.getBoundingClientRect(); @@ -24,22 +45,17 @@ export default function TiltCard({ const rotateX = ((y - centerY) / centerY) * -20; const rotateY = ((x - centerX) / centerX) * 20; - card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; + setTilts([...tilts.filter((tilt) => tilt.cardID !== cardID), { cardID, rotateX, rotateY }]); }; const handleMouseLeave = () => { - const card = cardRef.current; if (!card) return; - card.style.transform = `rotateX(0deg) rotateY(0deg)`; + + setTilts(tilts.filter((tilt) => tilt.cardID !== cardID)); }; return ( -
+
{children}
diff --git a/server.ts b/server.ts index 26890bc..8be15ff 100644 --- a/server.ts +++ b/server.ts @@ -4,7 +4,7 @@ import { Server as SocketIOServer, type Socket } from 'socket.io'; import GameStore from '@/lib/GameStore'; import omit from '@/tools/omit'; -import type { ClientUpdate, GameUpdate } from '@/types'; +import type { ClientUpdate, GameUpdate, Tilt } from '@/types'; const dev = process.env.NODE_ENV !== 'production'; const hostname = '0.0.0.0'; @@ -119,6 +119,16 @@ app.prepare().then(() => { } }); + socket.on('tilt', ({ gameID, tilt }: { gameID: string; tilt: Tilt }) => { + try { + const gameState = gameStore.getGame(gameID); + broadcast('tilt', gameState); + } catch (e) { + const error = e instanceof Error ? e.message : e; + console.error(Date.now(), 'Error[tilt]', error); + } + }); + socket.on('disconnect', () => { try { const game = gameStore.playerExit(socket.id); diff --git a/types/index.ts b/types/index.ts index cdfd8a8..3d9fca1 100644 --- a/types/index.ts +++ b/types/index.ts @@ -103,3 +103,14 @@ export interface Layout { name: string; text: string; } + +export interface Tilt { + cardID: string; + rotateX: number; + rotateY: number; +} + +export interface AppContext { + tilts: Tilt[]; + setTilts: (tilts: Tilt[]) => void; +}