Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"description": "A democratic Spotify jukebox where everyone gets to contribute songs. Track order is determined by the D'Hondt method for fair distribution.",
"type": "module",
"scripts": {
"start": "node --import tsx src/server.ts",
"dev": "vite",
"build": "vite build && tsc src/server.ts --outDir dist --module es2022 --target es2022 --moduleResolution node --skipLibCheck --esModuleInterop --allowSyntheticDefaultImports",
"build": "vite build && tsc --project tsconfig.app.json",
"lint": "eslint .",
"preview": "vite preview",
"test": "echo \"No tests specified\" && exit 0"
Expand Down Expand Up @@ -77,6 +78,7 @@
"sonner": "^1.7.4",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"tsx": "^4.21.0",
"vaul": "^0.9.9",
"zod": "^3.25.76"
},
Expand Down
23 changes: 13 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { AuthProvider } from "@/contexts/AuthContext";
import { ErrorBoundary } from "@/components/ErrorBoundary";
import { Suspense, lazy } from "react";
import { lazy, Suspense } from "react";


// Lazy load pages for better performance
const Index = lazy(() => import("./pages/Index"));
Expand All @@ -24,15 +25,17 @@ const App = () => (
<Toaster />
<Sonner />
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/rooms" element={<Rooms />} />
<Route path="/callback" element={<Callback />} />
<Route path="/app" element={<Index />} />
<Route path="/room/:roomId" element={<Index />} />
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
<Route path="*" element={<NotFound />} />
</Routes>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/rooms" element={<Rooms />} />
<Route path="/callback" element={<Callback />} />
<Route path="/app" element={<Index />} />
<Route path="/room/:roomId" element={<Index />} />
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
<Route path="*" element={<NotFound />} />
</Routes>
</Suspense>
</BrowserRouter>
</TooltipProvider>
</AuthProvider>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
);
Button.displayName = "Button";

export { Button };
export { Button, buttonVariants };
4 changes: 2 additions & 2 deletions src/components/ui/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
...classNames,
}}
components={{
IconLeft: ({ ..._props }) => <ChevronLeft className="h-4 w-4" />,
IconRight: ({ ..._props }) => <ChevronRight className="h-4 w-4" />,
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
IconRight: () => <ChevronRight className="h-4 w-4" />,
}}
{...props}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ const Toggle = React.forwardRef<

Toggle.displayName = TogglePrimitive.Root.displayName;

export { Toggle };
export { Toggle, toggleVariants };
2 changes: 1 addition & 1 deletion src/hooks/useSocket.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useState, useCallback, useRef } from 'react';
import { useAuth } from '@/contexts/AuthContext';
import { Room, Track, SpotifyUser } from '@/types/wejay';
import { toast } from '@/lib/toast';

import { io, Socket } from 'socket.io-client';

interface SocketState {
Expand Down
33 changes: 26 additions & 7 deletions src/hooks/useSpotifyPlayer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { useState, useEffect, useCallback, useRef } from 'react';
import { useAuth } from '@/contexts/AuthContext';

interface WebPlaybackError {
message: string;
}

interface WebPlaybackReady {
device_id: string;
}

interface WebPlaybackNotReady {
device_id: string;
}

interface SpotifyPlayer {
connect: () => Promise<boolean>;
disconnect: () => void;
Expand Down Expand Up @@ -80,37 +92,44 @@ export function useSpotifyPlayer() {
});

// Error handling
spotifyPlayer.addListener('initialization_error', ({ message }) => {
spotifyPlayer.addListener('initialization_error', (data: unknown) => {
const { message } = data as WebPlaybackError;
console.error('Spotify Player initialization error:', message);
});

spotifyPlayer.addListener('authentication_error', ({ message }) => {
spotifyPlayer.addListener('authentication_error', (data: unknown) => {
const { message } = data as WebPlaybackError;
console.error('Spotify Player authentication error:', message);
});

spotifyPlayer.addListener('account_error', ({ message }) => {
spotifyPlayer.addListener('account_error', (data: unknown) => {
const { message } = data as WebPlaybackError;
console.error('Spotify Player account error:', message);
});

spotifyPlayer.addListener('playback_error', ({ message }) => {
spotifyPlayer.addListener('playback_error', (data: unknown) => {
const { message } = data as WebPlaybackError;
console.error('Spotify Player playback error:', message);
});

// Ready
spotifyPlayer.addListener('ready', ({ device_id }) => {
spotifyPlayer.addListener('ready', (data: unknown) => {
const { device_id } = data as WebPlaybackReady;
console.log('Spotify Player: Ready with device ID', device_id);
setDeviceId(device_id);
setIsReady(true);
});

// Not Ready
spotifyPlayer.addListener('not_ready', ({ device_id }) => {
spotifyPlayer.addListener('not_ready', (data: unknown) => {
const { device_id } = data as WebPlaybackNotReady;
console.log('Spotify Player: Device has gone offline', device_id);
setIsReady(false);
});

// Player state changed
spotifyPlayer.addListener('player_state_changed', (state: WebPlaybackState | null) => {
spotifyPlayer.addListener('player_state_changed', (data: unknown) => {
const state = data as WebPlaybackState | null;
if (!state) {
setCurrentTrack(null);
setIsPlaying(false);
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useSpotifySearch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect, useCallback } from "react";
import { useState, useEffect } from "react";
import { searchSpotify, SpotifyTrack } from "@/lib/spotify";

export function useSpotifySearch(query: string, enabled: boolean = true) {
Expand Down
13 changes: 13 additions & 0 deletions src/lib/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const mockSearchResults: Track[] = [
duration: 200,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:0VjIjW4GlUZAmydPCpM16n",
},
{
id: "track-2",
Expand All @@ -51,6 +52,7 @@ export const mockSearchResults: Track[] = [
duration: 194,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:2FxmhksIbx3ea33S43A0D5",
},
{
id: "track-3",
Expand All @@ -61,6 +63,7 @@ export const mockSearchResults: Track[] = [
duration: 233,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:7qiZfU4dY1Kw1owLsZvIzS",
},
{
id: "track-4",
Expand All @@ -71,6 +74,7 @@ export const mockSearchResults: Track[] = [
duration: 209,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:1W6XKfQhNulGfsmlGpZOXb",
},
{
id: "track-5",
Expand All @@ -81,6 +85,7 @@ export const mockSearchResults: Track[] = [
duration: 174,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:6UelLqjlWMvsIVP0YcZSPc",
},
{
id: "track-6",
Expand All @@ -91,6 +96,7 @@ export const mockSearchResults: Track[] = [
duration: 203,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:5y2XqVxcqW8Gdil9KbdJXt",
},
];

Expand All @@ -104,6 +110,7 @@ export const mockFavorites: Track[] = [
duration: 354,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:4cOdK2wGLETOMsVvXh5gSd",
},
{
id: "fav-2",
Expand All @@ -114,6 +121,7 @@ export const mockFavorites: Track[] = [
duration: 390,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:40riOy7x9W7GXjyGp4pjAv",
},
{
id: "fav-3",
Expand All @@ -124,6 +132,7 @@ export const mockFavorites: Track[] = [
duration: 482,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:5CQ30WqJwPSw3PlHxlgVjM",
},
{
id: "fav-4",
Expand All @@ -134,6 +143,7 @@ export const mockFavorites: Track[] = [
duration: 187,
addedBy: "",
addedAt: new Date(),
spotifyId: "spotify:track:73vAVHHpwXecj4cPTuRJ2x",
},
];

Expand All @@ -147,6 +157,7 @@ export const mockPlaylistTracks: Track[] = [
duration: 230,
addedBy: "user-2",
addedAt: new Date(Date.now() - 300000),
spotifyId: "spotify:track:7lpZ3Xs5cLGLXoLwPcFj0Z",
},
{
id: "pl-2",
Expand All @@ -157,12 +168,14 @@ export const mockPlaylistTracks: Track[] = [
duration: 187,
addedBy: "user-2",
addedAt: new Date(Date.now() - 200000),
spotifyId: "spotify:track:4S29IqW2q5tA51yFkQ9T6F",
},
{
id: "pl-3",
name: "Uptown Funk",
artist: "Bruno Mars",
album: "Uptown Special",
spotifyId: "spotify:track:7yu7Wl9v1SG8bGrKb7c3Q4",
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spotifyId field should be placed after the album field to maintain consistent field ordering with the rest of the Track objects in this file. Currently it appears before albumArt, breaking the pattern established by other Track objects where the order is: id, name, artist, album, albumArt, duration, addedBy, addedAt, spotifyId.

Copilot uses AI. Check for mistakes.
albumArt: "https://i.scdn.co/image/ab67616d0000b273e419ccba0baa8bd3f3d7abf2",
duration: 269,
addedBy: "user-3",
Expand Down
8 changes: 2 additions & 6 deletions src/pages/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Index = () => {
isConnected,
currentRoom,
tracks: socketTracks,
playbackState: socketPlaybackState,

joinRoom,
leaveRoom,
addTrack: socketAddTrack,
Expand Down Expand Up @@ -184,11 +184,7 @@ const Index = () => {
}
}, [arrangedPlaylist, isConnected, currentRoom, trackEnded]);

const handleSkip = useCallback(() => {
if (arrangedPlaylist.length > 0) {
handleTrackEnd();
}
}, [handleTrackEnd, arrangedPlaylist]);


// handlePlayPause is now handled by SpotifyPlayer component

Expand Down
Loading
Loading