Skip to content

Commit

Permalink
chore: bit of refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasgriffintn committed Dec 6, 2024
1 parent 08d54c3 commit 0d1b9da
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 68 deletions.
11 changes: 1 addition & 10 deletions apps/web/components/AnyoneCanDraw/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import { onGenerateDrawing } from '@/components/ChatInterface/actions';

export function AnyoneCanDraw() {
const [result, setResult] = useState<string | null>(null);
// TODO: make this dynamic
const playerId = 'anonymous';
const playerName = 'Anonymous';

const handleSubmit = async (drawingData: string): Promise<any> => {
try {
Expand All @@ -23,12 +20,6 @@ export function AnyoneCanDraw() {
};

return (
<DrawingCanvas
onSubmit={handleSubmit}
result={result}
gameMode={true}
playerId={playerId}
playerName={playerName}
/>
<DrawingCanvas onSubmit={handleSubmit} result={result} gameMode={true} />
);
}
38 changes: 38 additions & 0 deletions apps/web/components/DrawingCanvas/Components/Chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { GameState } from '../types';

export default function Chat({
gameState,
onGuess,
isDrawer,
}: {
gameState: GameState;
onGuess?: (guess: string) => Promise<any>;
isDrawer: boolean;
}) {
const handleGuess = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const guess = formData.get('guess') as string;
await onGuess?.(guess);
};

return (
<div className="bg-muted p-4 rounded-lg flex-1">
<h3 className="font-medium mb-2">Game Guesses:</h3>
<div className="space-y-2 max-h-[400px] overflow-y-auto">
{gameState.guesses.map((guess, index) => (
<div
key={index}
className={`text-sm p-2 rounded ${
guess.correct ? 'bg-green-100 dark:bg-green-900' : 'bg-background'
}`}
>
<span className="font-medium">{guess.playerName}:</span>{' '}
{guess.guess}
</div>
))}
{!isDrawer && <span>TODO: Put a form here to guess</span>}
</div>
</div>
);
}
42 changes: 42 additions & 0 deletions apps/web/components/DrawingCanvas/Components/GenerateDrawing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Loader2 } from 'lucide-react';

import { Button } from '../../ui/button';
import { GameState } from '../types';

export function GenerateDrawing({
handleSubmit,
loading,
gameState,
}: {
handleSubmit: () => void;
loading: boolean;
gameState: GameState;
}) {
return (
<div className="bg-card p-4 rounded-lg border shadow-sm">
<div className="prose dark:prose-invert mb-4">
<h3 className="text-lg font-medium">Generate AI Art</h3>
<p className="text-sm text-muted-foreground">
Draw anything you like and get an AI-generated painting based on your
drawing.
</p>
</div>
<Button
onClick={handleSubmit}
disabled={loading || gameState.isActive}
className="w-full"
size="lg"
variant="default"
>
{loading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Generating...
</>
) : (
'Submit Drawing'
)}
</Button>
</div>
);
}
20 changes: 20 additions & 0 deletions apps/web/components/DrawingCanvas/hooks/useGameState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,25 @@ export function useGameState(
[gameState.gameId, playerId]
);

const submitGuess = useCallback(
async (guess: string) => {
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
console.error('WebSocket not connected');
return;
}

wsRef.current.send(
JSON.stringify({
action: 'guess',
gameId: gameState.gameId,
playerId,
guess,
})
);
},
[gameState.gameId, playerId]
);

return {
isConnected,
gameState,
Expand All @@ -264,5 +283,6 @@ export function useGameState(
endGame,
leaveGame,
updateDrawing,
submitGuess,
};
}
73 changes: 18 additions & 55 deletions apps/web/components/DrawingCanvas/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client';

import { useRef, useState, useEffect } from 'react';
import { Loader2 } from 'lucide-react';

import { Button } from '@/components/ui/button';

Expand All @@ -14,15 +13,14 @@ import { Result } from './Components/Result';
import { Canvas } from './Components/Canvas';
import { useGameState } from './hooks/useGameState';
import { GameStatus } from './Components/GameStatus';
import Chat from './Components/Chat';
import { GenerateDrawing } from './Components/GenerateDrawing';

export function DrawingCanvas({
onSubmit,
onGuess,
result,
gameMode,
gameId,
playerId,
playerName,
}: DrawingCanvasProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [loading, setLoading] = useState(false);
Expand Down Expand Up @@ -129,6 +127,10 @@ export function DrawingCanvas({
}
};

// TODO: make this dynamic (user should enter them)
const playerId = 'anonymous';
const playerName = 'Anonymous';

const {
isConnected,
gameState,
Expand All @@ -140,12 +142,8 @@ export function DrawingCanvas({
endGame,
leaveGame,
updateDrawing,
} = useGameState(
gameId,
playerId || 'anonymous',
playerName || 'Anonymous',
clearCanvas
);
submitGuess,
} = useGameState(gameId, playerId, playerName, clearCanvas);

const handleDrawingComplete = async () => {
if (
Expand Down Expand Up @@ -220,31 +218,11 @@ export function DrawingCanvas({

<div className="lg:w-80 flex flex-col gap-4">
{!gameState.isActive && (
<div className="bg-card p-4 rounded-lg border shadow-sm">
<div className="prose dark:prose-invert mb-4">
<h3 className="text-lg font-medium">Generate AI Art</h3>
<p className="text-sm text-muted-foreground">
Draw anything you like and get an AI-generated painting
based on your drawing.
</p>
</div>
<Button
onClick={handleSubmit}
disabled={loading || gameState.isActive}
className="w-full"
size="lg"
variant="default"
>
{loading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Generating...
</>
) : (
'Submit Drawing'
)}
</Button>
</div>
<GenerateDrawing
handleSubmit={handleSubmit}
loading={loading}
gameState={gameState}
/>
)}

{gameMode && (
Expand All @@ -265,26 +243,11 @@ export function DrawingCanvas({
</div>

{gameState.isActive && (
<div className="bg-muted p-4 rounded-lg flex-1">
<h3 className="font-medium mb-2">Game Guesses:</h3>
<div className="space-y-2 max-h-[400px] overflow-y-auto">
{gameState.guesses.map((guess, index) => (
<div
key={index}
className={`text-sm p-2 rounded ${
guess.correct
? 'bg-green-100 dark:bg-green-900'
: 'bg-background'
}`}
>
<span className="font-medium">
{guess.playerName}:
</span>{' '}
{guess.guess}
</div>
))}
</div>
</div>
<Chat
gameState={gameState}
onGuess={submitGuess}
isDrawer={isDrawer}
/>
)}
</>
)}
Expand Down
3 changes: 0 additions & 3 deletions apps/web/components/DrawingCanvas/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ interface DrawingCanvasProps {
result: string | null;
gameMode?: boolean;
gameId?: string;
playerId?: string;
playerName?: string;
onGuess?: (drawingData: string) => Promise<any>;
clearCanvas?: () => void;
}

Expand Down

0 comments on commit 0d1b9da

Please sign in to comment.