From a00bdba56b90f96d6b8427c437009d2bcbba2aec Mon Sep 17 00:00:00 2001 From: MasterGordon Date: Thu, 11 Sep 2025 13:03:50 +0200 Subject: [PATCH] removed use sound dep --- CLAUDE.md | 98 +++++++++++++++++++++++++++++++++++++++ bun.lockb | Bin 259798 -> 259079 bytes package.json | 1 - src/components/Board.tsx | 4 +- src/hooks/useAudio.ts | 37 +++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 CLAUDE.md create mode 100644 src/hooks/useAudio.ts diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..f759ae8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,98 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Business Minesweeper is a real-time multiplayer minesweeper game with expanding boards, user accounts, match history, spectating, and collectibles. Built with React frontend and Bun backend using WebSockets for real-time communication. + +## Development Commands + +### Setup +```bash +# Initial setup (requires Bun installed) +echo "SECRET=SOME_RANDOM_STRING" > .env +bun install +bun run drizzle:migrate +``` + +### Development +```bash +bun dev # Start both frontend and backend in development mode +bun run dev:client # Start only frontend (Vite dev server) +bun run dev:backend # Start only backend with hot reload +``` + +### Build & Quality +```bash +bun run build # Build for production (TypeScript compilation + Vite build) +bun run lint # Run ESLint +bun run preview # Preview production build +``` + +### Database +```bash +bun run drizzle:schema # Generate database migrations +bun run drizzle:migrate # Run database migrations +bun run nukedb # Delete and recreate database (removes sqlite.db) +``` + +## Architecture + +### Frontend (`src/`) +- **Framework**: React 18 + TypeScript with Vite build system +- **Routing**: Wouter for client-side routing +- **State Management**: + - Jotai for component state (atoms in `src/atoms.ts`) + - TanStack Query for server state and caching +- **Styling**: Tailwind CSS v4 with custom CSS variables +- **Animation**: Motion (Framer Motion) for UI animations +- **Game Rendering**: Pixi.js with PixiViewport for the minesweeper board + +### Backend (`backend/`) +- **Runtime**: Bun with TypeScript +- **Architecture**: WebSocket-based real-time API with controller pattern +- **Database**: SQLite with Drizzle ORM +- **Structure**: + - `router.ts` - Main request handler and routing + - `controller/` - Business logic controllers (game, user, scoreboard) + - `repositories/` - Data access layer + - `database/` - DB connection and configuration + - `entities/` - Type definitions + - `events.ts` - Real-time event system + +### Communication +- **WebSocket Client**: `src/wsClient.ts` handles connection, reconnection, and type-safe API calls +- **Real-time Updates**: Server publishes events to all connected clients for live game updates +- **Type Safety**: Shared types between frontend/backend via `Routes` interface + +### Key Components + +#### Game Logic +- `src/views/endless/Endless.tsx` - Main game view with Pixi.js board +- `src/components/LazyBoard.tsx` - Game board rendering component +- `backend/controller/gameController.ts` - Server-side game logic + +#### UI Architecture +- `src/Shell.tsx` - Main layout with responsive drawer navigation +- `src/main.tsx` - App entry point with routing setup +- `src/components/` - Reusable UI components using Radix UI primitives + +#### Data Flow +- WebSocket mutations for game actions (reveal, flag, etc.) +- TanStack Query for caching user data, game state, leaderboards +- Jotai atoms for local UI state (current game ID, settings) + +## Key Patterns + +### WebSocket API Usage +```typescript +const mutation = useWSMutation("game.reveal"); +const { data } = useWSQuery("game.getGameState", gameId, !!gameId); +``` + +### Database Queries +Uses Drizzle ORM with repository pattern for data access. Each controller has corresponding repository in `backend/repositories/`. + +### Real-time Events +Server publishes events via `backend/events.ts`, frontend handles via WebSocket message listeners in `wsClient.ts`. \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index ab2a72680d03170983abf300cab7d3eac5d15588..2269434e9420fc10a02508cc7c60f135b0eba2f2 100755 GIT binary patch delta 46499 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 delta 47216 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 LTgFdfeO> = (props) => { const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); const showLastPos = game.user !== user || isServerGame(game); - const [playSound] = useSound(explosion, { + const [playSound] = useAudio(explosion, { volume: 0.5, }); diff --git a/src/hooks/useAudio.ts b/src/hooks/useAudio.ts new file mode 100644 index 0000000..f9b2b6c --- /dev/null +++ b/src/hooks/useAudio.ts @@ -0,0 +1,37 @@ +import { useCallback, useRef } from 'react'; + +interface AudioOptions { + volume?: number; + loop?: boolean; +} + +export const useAudio = (src: string, options: AudioOptions = {}) => { + const audioRef = useRef(null); + + const play = useCallback(() => { + if (!audioRef.current) { + audioRef.current = new Audio(src); + audioRef.current.volume = options.volume ?? 1; + audioRef.current.loop = options.loop ?? false; + } + + // Reset to beginning and play + audioRef.current.currentTime = 0; + audioRef.current.play().catch((error) => { + console.warn('Audio play failed:', error); + }); + }, [src, options.volume, options.loop]); + + const pause = useCallback(() => { + audioRef.current?.pause(); + }, []); + + const stop = useCallback(() => { + if (audioRef.current) { + audioRef.current.pause(); + audioRef.current.currentTime = 0; + } + }, []); + + return [play, { pause, stop }] as const; +}; \ No newline at end of file