teletilt #3

Merged
gavin merged 20 commits from teletilt into trunk 2025-07-03 14:40:35 -04:00
3 changed files with 63 additions and 35 deletions
Showing only changes of commit 1c28a603b7 - Show all commits

View File

@@ -1,14 +1,62 @@
'use client'; 'use client';
import { createContext, useContext, useState, ReactNode } from 'react'; import { createContext, useContext, useState, ReactNode } from 'react';
import type { AppContext, Tilt } from '@/types'; import useSocket from '@/hooks/useSocket';
import type { GameUpdate, Tilt } from '@/types';
const AppContext = createContext<AppContext | undefined>(undefined); const AppContext = createContext<AppContext | undefined>(undefined);
const gameStart: GameUpdate = {
dmID: '',
spectatorID: '',
cards: [],
settings: {
positionBack: false,
positionFront: false,
prophecy: false,
notes: false,
cardStyle: 'color',
},
};
export interface AppContext {
gameData: GameUpdate;
noGame: boolean;
tilts: Tilt[];
flipCard: (cardIndex: number) => void;
handleSettings: (gameData: GameUpdate) => void;
redraw: (cardIndex: number) => void;
select: (cardIndex: number, cardID: string) => void;
setGameID: (gameID: string) => void;
setTilts: (tilts: Tilt[]) => void;
}
export function AppProvider({ children }: { children: ReactNode }) { export function AppProvider({ children }: { children: ReactNode }) {
const [gameID, setGameID] = useState('');
const [noGame, setNoGame] = useState(false);
const [gameData, setGameData] = useState<GameUpdate>(gameStart);
const { flipCard, redraw, select, handleSettings } = useSocket({
gameID,
setGameData,
setNoGame,
});
const [tilts, setTilts] = useState<Tilt[]>([]); const [tilts, setTilts] = useState<Tilt[]>([]);
return <AppContext.Provider value={{ tilts, setTilts }}>{children}</AppContext.Provider>; const appInterface = {
gameData,
noGame,
tilts,
flipCard,
handleSettings,
redraw,
select,
setGameID,
setTilts,
};
return <AppContext.Provider value={appInterface}>{children}</AppContext.Provider>;
} }
export function useAppContext(): AppContext { export function useAppContext(): AppContext {

View File

@@ -2,7 +2,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import useSocket from '@/hooks/useSocket'; import { useAppContext } from '@/app/AppContext';
import { Eye } from 'lucide-react'; import { Eye } from 'lucide-react';
import Card from '@/components/Card'; import Card from '@/components/Card';
@@ -14,43 +14,28 @@ import CardSelect from '@/components/CardSelect';
import { cardMap, layout } from '@/constants/tarokka'; import { cardMap, layout } from '@/constants/tarokka';
import type { Deck, GameUpdate } from '@/types'; import type { Deck } from '@/types';
export default function GamePage() { export default function GamePage() {
const { gameID: gameIDParam } = useParams(); const { gameData, noGame, flipCard, handleSettings, redraw, select, setGameID } = useAppContext();
const { gameID } = useParams();
const [gameID, setGameID] = useState('');
const [noGame, setNoGame] = useState(false);
const [selectCard, setSelectCard] = useState(-1); const [selectCard, setSelectCard] = useState(-1);
const [gameData, setGameData] = useState<GameUpdate>({
dmID: '',
spectatorID: '',
cards: [],
settings: {
positionBack: false,
positionFront: false,
prophecy: false,
notes: false,
cardStyle: 'color',
},
});
const { dmID, cards, settings } = gameData; const { dmID, cards, settings } = gameData;
const isDM = !!dmID; const isDM = !!dmID;
const selectDeck: Deck | null = selectCard >= 0 ? cards[selectCard].deck : null; const selectDeck: Deck | null = selectCard >= 0 ? cards[selectCard].deck : null;
const socket = useSocket({ gameID, setGameData, setNoGame });
useEffect(() => { useEffect(() => {
if (gameIDParam) { if (gameID) {
setGameID(Array.isArray(gameIDParam) ? gameIDParam[0] : gameIDParam); setGameID(Array.isArray(gameID) ? gameID[0] : gameID);
} }
}, [gameIDParam]); }, [gameID]);
const select = (cardIndex: number, cardID: string) => { const handleSelect = (cardIndex: number, cardID: string) => {
setSelectCard(-1); setSelectCard(-1);
socket.select(cardIndex, cardID); select(cardIndex, cardID);
}; };
// map our five Tarokka cards to their proper locations in a 3x3 grid // map our five Tarokka cards to their proper locations in a 3x3 grid
@@ -72,7 +57,7 @@ export default function GamePage() {
/> />
)} )}
{isDM && <Settings gameData={gameData} changeAction={socket.handleSettings} />} {isDM && <Settings gameData={gameData} changeAction={handleSettings} />}
<div className="grid grid-cols-3 grid-rows-3 gap-8 w-fit mx-auto"> <div className="grid grid-cols-3 grid-rows-3 gap-8 w-fit mx-auto">
{Array.from({ length: 9 }) {Array.from({ length: 9 })
.map(arrangeCards) .map(arrangeCards)
@@ -84,8 +69,8 @@ export default function GamePage() {
card={card} card={card}
position={layout[cardMap[index]]} position={layout[cardMap[index]]}
settings={settings} settings={settings}
flipAction={() => socket.flipCard(cardMap[index])} flipAction={() => flipCard(cardMap[index])}
redrawAction={() => socket.redraw(cardMap[index])} redrawAction={() => redraw(cardMap[index])}
selectAction={() => setSelectCard(cardMap[index])} selectAction={() => setSelectCard(cardMap[index])}
/> />
)} )}
@@ -98,7 +83,7 @@ export default function GamePage() {
hand={cards} hand={cards}
settings={settings} settings={settings}
closeAction={() => setSelectCard(-1)} closeAction={() => setSelectCard(-1)}
selectAction={(cardID) => select(selectCard, cardID)} selectAction={(cardID) => handleSelect(selectCard, cardID)}
/> />
</main> </main>
) : null; ) : null;

View File

@@ -109,8 +109,3 @@ export interface Tilt {
rotateX: number; rotateX: number;
rotateY: number; rotateY: number;
} }
export interface AppContext {
tilts: Tilt[];
setTilts: (tilts: Tilt[]) => void;
}