teletilt #3
@@ -26,14 +26,16 @@ export interface AppContext {
|
|||||||
flipCard: (cardIndex: number) => void;
|
flipCard: (cardIndex: number) => void;
|
||||||
handleSettings: (gameData: GameUpdate) => void;
|
handleSettings: (gameData: GameUpdate) => void;
|
||||||
redraw: (cardIndex: number) => void;
|
redraw: (cardIndex: number) => void;
|
||||||
select: (cardIndex: number, cardID: string) => void;
|
select: (cardID: string) => void;
|
||||||
setGameID: (gameID: string) => void;
|
setGameID: (gameID: string) => void;
|
||||||
|
setSelectCardIndex: (cardIndex: number) => void;
|
||||||
setTilts: (tilts: Tilt[]) => void;
|
setTilts: (tilts: Tilt[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AppProvider({ children }: { children: ReactNode }) {
|
export function AppProvider({ children }: { children: ReactNode }) {
|
||||||
const [gameID, setGameID] = useState('');
|
const [gameID, setGameID] = useState('');
|
||||||
const [noGame, setNoGame] = useState(false);
|
const [noGame, setNoGame] = useState(false);
|
||||||
|
const [selectCardIndex, setSelectCardIndex] = useState(-1);
|
||||||
const [gameData, setGameData] = useState<GameUpdate>(gameStart);
|
const [gameData, setGameData] = useState<GameUpdate>(gameStart);
|
||||||
|
|
||||||
const { flipCard, redraw, select, handleSettings } = useSocket({
|
const { flipCard, redraw, select, handleSettings } = useSocket({
|
||||||
@@ -44,6 +46,12 @@ export function AppProvider({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
const [tilts, setTilts] = useState<Tilt[]>([]);
|
const [tilts, setTilts] = useState<Tilt[]>([]);
|
||||||
|
|
||||||
|
const handleSelect = (cardID: string) => {
|
||||||
|
setSelectCardIndex(-1);
|
||||||
|
|
||||||
|
select(selectCardIndex, cardID);
|
||||||
|
};
|
||||||
|
|
||||||
const appInterface = {
|
const appInterface = {
|
||||||
gameData,
|
gameData,
|
||||||
noGame,
|
noGame,
|
||||||
@@ -51,8 +59,9 @@ export function AppProvider({ children }: { children: ReactNode }) {
|
|||||||
flipCard,
|
flipCard,
|
||||||
handleSettings,
|
handleSettings,
|
||||||
redraw,
|
redraw,
|
||||||
select,
|
select: handleSelect,
|
||||||
setGameID,
|
setGameID,
|
||||||
|
setSelectCardIndex,
|
||||||
setTilts,
|
setTilts,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,17 @@ import { useParams } from 'next/navigation';
|
|||||||
import { useAppContext } from '@/app/AppContext';
|
import { useAppContext } from '@/app/AppContext';
|
||||||
import { Eye } from 'lucide-react';
|
import { Eye } from 'lucide-react';
|
||||||
|
|
||||||
import Card from '@/components/Card';
|
import CardSelect from '@/components/CardSelect';
|
||||||
import CopyButton from '@/components/CopyButton';
|
import CopyButton from '@/components/CopyButton';
|
||||||
import Notes from '@/components/Notes';
|
import Notes from '@/components/Notes';
|
||||||
import NotFound from '@/components/NotFound';
|
import NotFound from '@/components/NotFound';
|
||||||
import Settings from '@/components/Settings';
|
import Settings from '@/components/Settings';
|
||||||
import CardSelect from '@/components/CardSelect';
|
import TarokkaGrid from '@/components/TarokkaGrid';
|
||||||
|
|
||||||
import { cardMap, layout } from '@/constants/tarokka';
|
|
||||||
|
|
||||||
import type { Deck } from '@/types';
|
import type { Deck } from '@/types';
|
||||||
|
|
||||||
export default function GamePage() {
|
export default function GamePage() {
|
||||||
const { gameData, noGame, flipCard, handleSettings, redraw, select, setGameID } = useAppContext();
|
const { gameData, noGame, handleSettings, select, setGameID } = useAppContext();
|
||||||
const { gameID } = useParams();
|
const { gameID } = useParams();
|
||||||
|
|
||||||
const [selectCard, setSelectCard] = useState(-1);
|
const [selectCard, setSelectCard] = useState(-1);
|
||||||
@@ -32,17 +30,6 @@ export default function GamePage() {
|
|||||||
}
|
}
|
||||||
}, [gameID]);
|
}, [gameID]);
|
||||||
|
|
||||||
const handleSelect = (cardIndex: number, cardID: string) => {
|
|
||||||
setSelectCard(-1);
|
|
||||||
|
|
||||||
select(cardIndex, cardID);
|
|
||||||
};
|
|
||||||
|
|
||||||
// map our five Tarokka cards to their proper locations in a 3x3 grid
|
|
||||||
// common deck cards: left, top, and right
|
|
||||||
// high deck cards: bottom and center
|
|
||||||
const arrangeCards = (_cell: unknown, index: number) => cards[cardMap[index]];
|
|
||||||
|
|
||||||
return noGame ? (
|
return noGame ? (
|
||||||
<NotFound />
|
<NotFound />
|
||||||
) : cards ? (
|
) : cards ? (
|
||||||
@@ -58,32 +45,14 @@ export default function GamePage() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{isDM && <Settings gameData={gameData} changeAction={handleSettings} />}
|
{isDM && <Settings gameData={gameData} changeAction={handleSettings} />}
|
||||||
<div className="grid grid-cols-3 grid-rows-3 gap-8 w-fit mx-auto">
|
<TarokkaGrid />
|
||||||
{Array.from({ length: 9 })
|
|
||||||
.map(arrangeCards)
|
|
||||||
.map((card, index) => (
|
|
||||||
<div key={index} className="aspect-[2/3]}">
|
|
||||||
{card && (
|
|
||||||
<Card
|
|
||||||
dm={isDM}
|
|
||||||
card={card}
|
|
||||||
position={layout[cardMap[index]]}
|
|
||||||
settings={settings}
|
|
||||||
flipAction={() => flipCard(cardMap[index])}
|
|
||||||
redrawAction={() => redraw(cardMap[index])}
|
|
||||||
selectAction={() => setSelectCard(cardMap[index])}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<Notes gameData={gameData} show={cards.every(({ flipped }) => flipped)} />
|
<Notes gameData={gameData} show={cards.every(({ flipped }) => flipped)} />
|
||||||
<CardSelect
|
<CardSelect
|
||||||
show={selectDeck}
|
show={selectDeck}
|
||||||
hand={cards}
|
hand={cards}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
closeAction={() => setSelectCard(-1)}
|
closeAction={() => setSelectCard(-1)}
|
||||||
selectAction={(cardID) => handleSelect(selectCard, cardID)}
|
selectAction={select}
|
||||||
/>
|
/>
|
||||||
</main>
|
</main>
|
||||||
) : null;
|
) : null;
|
||||||
|
|||||||
@@ -1,43 +1,37 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useAppContext } from '@/app/AppContext';
|
||||||
import TiltCard from '@/components/TiltCard';
|
import TiltCard from '@/components/TiltCard';
|
||||||
import ToolTip from '@/components/ToolTip';
|
import ToolTip from '@/components/ToolTip';
|
||||||
import StackTheDeck from '@/components/StackTheDeck';
|
import StackTheDeck from '@/components/StackTheDeck';
|
||||||
import tarokkaCards from '@/constants/tarokkaCards';
|
|
||||||
import getCardInfo from '@/tools/getCardInfo';
|
import getCardInfo from '@/tools/getCardInfo';
|
||||||
import getURL from '@/tools/getURL';
|
import getURL from '@/tools/getURL';
|
||||||
|
|
||||||
import { Layout, Settings, TarokkaGameCard } from '@/types';
|
import tarokkaCards from '@/constants/tarokkaCards';
|
||||||
|
import { layout } from '@/constants/tarokka';
|
||||||
|
|
||||||
|
import { Settings, TarokkaGameCard } from '@/types';
|
||||||
|
|
||||||
const cardBack = tarokkaCards.find((card) => card.back)!;
|
const cardBack = tarokkaCards.find((card) => card.back)!;
|
||||||
|
|
||||||
type CardProps = {
|
type CardProps = {
|
||||||
dm: boolean;
|
dm: boolean;
|
||||||
card: TarokkaGameCard;
|
card: TarokkaGameCard;
|
||||||
position: Layout;
|
cardIndex: number;
|
||||||
settings: Settings;
|
settings: Settings;
|
||||||
flipAction: () => void;
|
|
||||||
redrawAction: () => void;
|
|
||||||
selectAction: () => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Card({
|
export default function Card({ dm, card, cardIndex, settings }: CardProps) {
|
||||||
dm,
|
|
||||||
card,
|
|
||||||
position,
|
|
||||||
settings,
|
|
||||||
flipAction,
|
|
||||||
redrawAction,
|
|
||||||
selectAction,
|
|
||||||
}: CardProps) {
|
|
||||||
const [tooltip, setTooltip] = useState<React.ReactNode>(null);
|
const [tooltip, setTooltip] = useState<React.ReactNode>(null);
|
||||||
|
const { flipCard, redraw, setSelectCardIndex } = useAppContext();
|
||||||
|
|
||||||
const { aria, flipped } = card;
|
const { aria, flipped } = card;
|
||||||
|
const position = layout[cardIndex];
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (dm) {
|
if (dm) {
|
||||||
flipAction();
|
flipCard(cardIndex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,8 +78,8 @@ export default function Card({
|
|||||||
/>
|
/>
|
||||||
{dm && !flipped && (
|
{dm && !flipped && (
|
||||||
<StackTheDeck
|
<StackTheDeck
|
||||||
onRedraw={redrawAction}
|
onRedraw={() => redraw(cardIndex)}
|
||||||
onSelect={() => selectAction()}
|
onSelect={() => setSelectCardIndex(cardIndex)}
|
||||||
onHover={setTooltip}
|
onHover={setTooltip}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
30
components/TarokkaGrid.tsx
Normal file
30
components/TarokkaGrid.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useAppContext } from '@/app/AppContext';
|
||||||
|
import Card from '@/components/Card';
|
||||||
|
import { cardMap } from '@/constants/tarokka';
|
||||||
|
import type {} from '@/types';
|
||||||
|
|
||||||
|
export default function TarokkaGrid() {
|
||||||
|
const { gameData } = useAppContext();
|
||||||
|
|
||||||
|
const { dmID, cards, settings } = gameData;
|
||||||
|
const isDM = !!dmID;
|
||||||
|
|
||||||
|
// map our five Tarokka cards to their proper locations in a 3x3 grid
|
||||||
|
// common deck cards: left, top, and right
|
||||||
|
// high deck cards: bottom and center
|
||||||
|
const arrangeCards = (_cell: unknown, index: number) => cards[cardMap[index]];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-3 grid-rows-3 gap-8 w-fit mx-auto">
|
||||||
|
{Array.from({ length: 9 })
|
||||||
|
.map(arrangeCards)
|
||||||
|
.map((card, index) => (
|
||||||
|
<div key={index} className="aspect-[2/3]}">
|
||||||
|
{card && <Card dm={isDM} card={card} cardIndex={cardMap[index]} settings={settings} />}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user