Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-07-18 16:53:43 -05:00
parent 3e143dade9
commit bdb57f46ed
25 changed files with 169 additions and 97 deletions

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { selectIsAuthenticated } from '../../redux/authSlice';
import { debugLog } from '../../utils/logger';
import { LoginPrompt } from './index';
interface AuthInitializerProps {
@ -17,7 +18,7 @@ const AuthInitializer: React.FC<AuthInitializerProps> = ({ children }) => {
const isAuthenticated = useAppSelector(selectIsAuthenticated);
useEffect(() => {
console.log('AuthInitializer effect - isAuthenticated:', isAuthenticated, 'showLogin:', showLogin);
debugLog('AuthInitializer effect - isAuthenticated:', isAuthenticated, 'showLogin:', showLogin);
// Only process admin parameter once
if (hasProcessedAdminParam) return;
@ -54,7 +55,7 @@ const AuthInitializer: React.FC<AuthInitializerProps> = ({ children }) => {
<LoginPrompt
isAdmin={isAdminMode}
onComplete={() => {
console.log('onComplete called, setting showLogin to false');
debugLog('onComplete called, setting showLogin to false');
setShowLogin(false);
}}
/>

View File

@ -2,6 +2,7 @@ import { useState } from 'react';
import { IonIcon } from '@ionic/react';
import { micOutline } from 'ionicons/icons';
import { useAppDispatch } from '../../redux/hooks';
import { debugLog } from '../../utils/logger';
import { setAuth } from '../../redux/authSlice';
import { database } from '../../firebase/config';
import { ref, get } from 'firebase/database';
@ -20,7 +21,7 @@ const LoginPrompt: React.FC<LoginPromptProps> = ({ isAdmin, onComplete }) => {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
console.log('Login form submitted');
debugLog('Login form submitted');
if (!partyId.trim() || !singerName.trim()) {
setError('Please enter both Party Id and your name.');
return;
@ -43,9 +44,9 @@ const LoginPrompt: React.FC<LoginPromptProps> = ({ isAdmin, onComplete }) => {
isAdmin: isAdmin,
controller: partyId.trim(),
};
console.log('Dispatching auth:', auth);
debugLog('Dispatching auth:', auth);
dispatch(setAuth(auth));
console.log('Calling onComplete');
debugLog('Calling onComplete');
onComplete();
} catch (error) {
console.error('Error checking controller:', error);

View File

@ -5,6 +5,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { PlayerControls } from '../common';
import { useAppSelector } from '../../redux';
import { selectIsAdmin } from '../../redux';
import { debugLog } from '../../utils/logger';
const Navigation: React.FC = () => {
const location = useLocation();
@ -32,7 +33,7 @@ const Navigation: React.FC = () => {
useEffect(() => {
const checkScreenSize = () => {
const large = window.innerWidth >= 768;
console.log('Screen width:', window.innerWidth, 'Is large screen:', large);
debugLog('Screen width:', window.innerWidth, 'Is large screen:', large);
setIsLargeScreen(large);
};
@ -54,7 +55,7 @@ const Navigation: React.FC = () => {
// For large screens, render a fixed sidebar instead of a menu
if (isLargeScreen) {
console.log('Rendering large screen sidebar');
debugLog('Rendering large screen sidebar');
return (
<div
style={{
@ -121,7 +122,7 @@ const Navigation: React.FC = () => {
}
// For mobile screens, use the Ionic menu
console.log('Rendering mobile menu');
debugLog('Rendering mobile menu');
return (
<IonMenu
contentId="main-content"

View File

@ -1,4 +1,5 @@
import React, { useEffect, useRef } from 'react';
import { debugLog } from '../../utils/logger';
import { EmptyState } from './index';
interface InfiniteScrollListProps<T> {
@ -28,18 +29,18 @@ const InfiniteScrollList = <T extends string | { key?: string }>({
// Intersection Observer for infinite scrolling
useEffect(() => {
console.log('InfiniteScrollList - Setting up observer:', { hasMore, isLoading, itemsLength: items.length });
debugLog('InfiniteScrollList - Setting up observer:', { hasMore, isLoading, itemsLength: items.length });
const observer = new IntersectionObserver(
(entries) => {
console.log('InfiniteScrollList - Intersection detected:', {
debugLog('InfiniteScrollList - Intersection detected:', {
isIntersecting: entries[0].isIntersecting,
hasMore,
isLoading
});
if (entries[0].isIntersecting && hasMore && !isLoading) {
console.log('InfiniteScrollList - Loading more items');
debugLog('InfiniteScrollList - Loading more items');
onLoadMore();
}
},

View File

@ -6,6 +6,7 @@ import { useAppSelector } from '../../redux';
import { selectPlayerState, selectIsAdmin, selectQueue } from '../../redux';
import { playerService } from '../../firebase/services';
import { selectControllerName } from '../../redux';
import { debugLog } from '../../utils/logger';
import { useToast } from '../../hooks/useToast';
import { PlayerState } from '../../types';
@ -22,9 +23,9 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
const { showSuccess, showError } = useToast();
// Debug logging
console.log('PlayerControls - playerState:', playerState);
console.log('PlayerControls - isAdmin:', isAdmin);
console.log('PlayerControls - queue length:', Object.keys(queue).length);
debugLog('PlayerControls - playerState:', playerState);
debugLog('PlayerControls - isAdmin:', isAdmin);
debugLog('PlayerControls - queue length:', Object.keys(queue).length);
const handlePlay = async () => {
if (!controllerName) return;
@ -70,8 +71,8 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
const currentState = playerState?.state || PlayerState.stopped;
const hasSongsInQueue = Object.keys(queue).length > 0;
console.log('PlayerControls - currentState:', currentState);
console.log('PlayerControls - hasSongsInQueue:', hasSongsInQueue);
debugLog('PlayerControls - currentState:', currentState);
debugLog('PlayerControls - hasSongsInQueue:', hasSongsInQueue);
const getStateColor = () => {
switch (currentState) {

View File

@ -5,6 +5,7 @@ import { InfiniteScrollList, SongItem } from '../../components/common';
import { useArtists } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectSongs } from '../../redux';
import { debugLog } from '../../utils/logger';
const Artists: React.FC = () => {
const {
@ -24,10 +25,10 @@ const Artists: React.FC = () => {
const [selectedArtist, setSelectedArtist] = useState<string | null>(null);
// Debug logging
console.log('Artists component - artists count:', artists.length);
console.log('Artists component - selected artist:', selectedArtist);
console.log('Artists component - songs count:', songsCount);
console.log('Artists component - search term:', searchTerm);
debugLog('Artists component - artists count:', artists.length);
debugLog('Artists component - selected artist:', selectedArtist);
debugLog('Artists component - songs count:', songsCount);
debugLog('Artists component - search term:', searchTerm);
const handleArtistClick = (artist: string) => {
setSelectedArtist(artist);

View File

@ -3,6 +3,7 @@ import { InfiniteScrollList, SongItem } from '../../components/common';
import { useFavorites } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectFavorites } from '../../redux';
import { debugLog } from '../../utils/logger';
import type { Song } from '../../types';
const Favorites: React.FC = () => {
@ -18,8 +19,8 @@ const Favorites: React.FC = () => {
const favoritesCount = Object.keys(favorites).length;
// Debug logging
console.log('Favorites component - favorites count:', favoritesCount);
console.log('Favorites component - favorites items:', favoritesItems);
debugLog('Favorites component - favorites count:', favoritesCount);
debugLog('Favorites component - favorites items:', favoritesItems);
return (
<>

View File

@ -5,6 +5,7 @@ import { InfiniteScrollList, SongItem } from '../../components/common';
import { useHistory } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectHistory } from '../../redux';
import { debugLog } from '../../utils/logger';
import { formatDate } from '../../utils/dataProcessing';
import type { Song } from '../../types';
@ -21,8 +22,8 @@ const History: React.FC = () => {
const historyCount = Object.keys(history).length;
// Debug logging
console.log('History component - history count:', historyCount);
console.log('History component - history items:', historyItems);
debugLog('History component - history count:', historyCount);
debugLog('History component - history items:', historyItems);
// Render extra content for history items (play date)
const renderExtraContent = (item: Song) => {

View File

@ -3,6 +3,7 @@ import { InfiniteScrollList, SongItem } from '../../components/common';
import { useNewSongs } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectNewSongs } from '../../redux';
import { debugLog } from '../../utils/logger';
import type { Song } from '../../types';
const NewSongs: React.FC = () => {
@ -18,8 +19,8 @@ const NewSongs: React.FC = () => {
const newSongsCount = Object.keys(newSongs).length;
// Debug logging
console.log('NewSongs component - new songs count:', newSongsCount);
console.log('NewSongs component - new songs items:', newSongsItems);
debugLog('NewSongs component - new songs count:', newSongsCount);
debugLog('NewSongs component - new songs items:', newSongsItems);
return (
<>

View File

@ -7,6 +7,7 @@ import { useAppSelector } from '../../redux';
import { selectQueue, selectPlayerState, selectIsAdmin, selectControllerName } from '../../redux';
import { PlayerState } from '../../types';
import { queueService } from '../../firebase/services';
import { debugLog } from '../../utils/logger';
import type { QueueItem } from '../../types';
type QueueMode = 'delete' | 'reorder';
@ -29,18 +30,18 @@ const Queue: React.FC = () => {
const queueCount = Object.keys(queue).length;
// Debug logging
console.log('Queue component - queue count:', queueCount);
console.log('Queue component - queue items:', queueItems);
console.log('Queue component - player state:', playerState);
console.log('Queue component - isAdmin:', isAdmin);
console.log('Queue component - canReorder:', canReorder);
console.log('Queue component - queueMode:', queueMode);
debugLog('Queue component - queue count:', queueCount);
debugLog('Queue component - queue items:', queueItems);
debugLog('Queue component - player state:', playerState);
debugLog('Queue component - isAdmin:', isAdmin);
debugLog('Queue component - canReorder:', canReorder);
debugLog('Queue component - queueMode:', queueMode);
// Check if items can be deleted (admin can delete any item when not playing)
const canDeleteItems = isAdmin && (playerState?.state === PlayerState.stopped || playerState?.state === PlayerState.paused);
console.log('Queue component - canDeleteItems:', canDeleteItems);
console.log('Queue component - canReorder:', canReorder);
debugLog('Queue component - canDeleteItems:', canDeleteItems);
debugLog('Queue component - canReorder:', canReorder);
// Update list items when queue changes
@ -60,7 +61,7 @@ const Queue: React.FC = () => {
// Handle reorder event from IonReorderGroup
const doReorder = async (event: CustomEvent) => {
console.log('Reorder event:', event.detail);
debugLog('Reorder event:', event.detail);
const { from, to, complete } = event.detail;
if (listItems && controllerName) {
@ -73,21 +74,21 @@ const Queue: React.FC = () => {
// Create the new queue order (first item + reordered items)
const newQueueItems = [queueItems[0], ...copy];
console.log('New queue order:', newQueueItems);
debugLog('New queue order:', newQueueItems);
try {
// Update all items with their new order values
const updatePromises = newQueueItems.map((item, index) => {
const newOrder = index + 1;
if (item.key && item.order !== newOrder) {
console.log(`Updating item ${item.key} from order ${item.order} to ${newOrder}`);
debugLog(`Updating item ${item.key} from order ${item.order} to ${newOrder}`);
return queueService.updateQueueItem(controllerName, item.key, { order: newOrder });
}
return Promise.resolve();
});
await Promise.all(updatePromises);
console.log('Queue reorder completed successfully');
debugLog('Queue reorder completed successfully');
} catch (error) {
console.error('Failed to reorder queue:', error);
// You might want to show an error toast here
@ -97,7 +98,7 @@ const Queue: React.FC = () => {
// Render queue item
const renderQueueItem = (queueItem: QueueItem, index: number) => {
console.log(`Queue item ${index}: order=${queueItem.order}, key=${queueItem.key}`);
debugLog(`Queue item ${index}: order=${queueItem.order}, key=${queueItem.key}`);
const canDelete = isAdmin && queueMode === 'delete'; // Only allow delete in delete mode
return (

View File

@ -4,6 +4,7 @@ import { InfiniteScrollList, SongItem } from '../../components/common';
import { useSearch } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectIsAdmin, selectSongs } from '../../redux';
import { debugLog } from '../../utils/logger';
import type { Song } from '../../types';
const Search: React.FC = () => {
@ -27,15 +28,15 @@ const Search: React.FC = () => {
return () => {
const endTime = performance.now();
const renderTime = endTime - startTime;
console.log(`Search component render time: ${renderTime.toFixed(2)}ms`);
debugLog(`Search component render time: ${renderTime.toFixed(2)}ms`);
};
});
// Debug logging
console.log('Search component - songs count:', songsCount);
console.log('Search component - search results:', searchResults);
console.log('Search component - search term:', searchTerm);
console.log('Search component - showing:', searchResults.songs.length, 'of', searchResults.count);
debugLog('Search component - songs count:', songsCount);
debugLog('Search component - search results:', searchResults);
debugLog('Search component - search term:', searchTerm);
debugLog('Search component - showing:', searchResults.songs.length, 'of', searchResults.count);
return (
<div className="max-w-4xl mx-auto p-6">

View File

@ -6,6 +6,7 @@ import { selectIsAdmin, selectSettings } from '../../redux';
import { useDisabledSongs } from '../../hooks';
import { InfiniteScrollList, ActionButton } from '../../components/common';
import { filterSongs } from '../../utils/dataProcessing';
import { setDebugEnabled, isDebugEnabled, debugLog } from '../../utils/logger';
import type { Song } from '../../types';
interface DisabledSongDisplay {
@ -44,7 +45,11 @@ const Settings: React.FC = () => {
const handleToggleSetting = async (setting: string, value: boolean) => {
// This would need to be implemented with the settings service
console.log(`Toggle ${setting} to ${value}`);
debugLog(`Toggle ${setting} to ${value}`);
};
const handleToggleDebug = (enabled: boolean) => {
setDebugEnabled(enabled);
};
const handleRemoveDisabledSong = async (song: DisabledSongDisplay) => {
@ -89,6 +94,14 @@ const Settings: React.FC = () => {
onIonChange={(e) => handleToggleSetting('userpick', e.detail.checked)}
/>
</IonItem>
<IonItem>
<IonLabel>Debug Logging</IonLabel>
<IonToggle
slot="end"
checked={isDebugEnabled()}
onIonChange={(e) => handleToggleDebug(e.detail.checked)}
/>
</IonItem>
</IonList>
</div>

View File

@ -5,6 +5,7 @@ import { InfiniteScrollList, ActionButton } from '../../components/common';
import { useSingers } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectSingers } from '../../redux';
import { debugLog } from '../../utils/logger';
import type { Singer } from '../../types';
const Singers: React.FC = () => {
@ -39,8 +40,8 @@ const Singers: React.FC = () => {
const singersCount = Object.keys(singersData).length;
// Debug logging
console.log('Singers component - singers count:', singersCount);
console.log('Singers component - singers:', singers);
debugLog('Singers component - singers count:', singersCount);
debugLog('Singers component - singers:', singers);
// Render singer item for InfiniteScrollList
const renderSingerItem = (singer: Singer) => (

View File

@ -6,12 +6,13 @@ import { useAppSelector } from '../../redux';
import { selectTopPlayed, selectSongsArray } from '../../redux';
import { InfiniteScrollList, SongItem } from '../../components/common';
import { filterSongs } from '../../utils/dataProcessing';
import { debugLog } from '../../utils/logger';
import { useSongOperations } from '../../hooks';
import { useToast } from '../../hooks';
import type { TopPlayed, Song } from '../../types';
const Top100: React.FC = () => {
console.log('Top100 component - RENDERING START');
debugLog('Top100 component - RENDERING START');
const {
topPlayedItems,
@ -27,7 +28,7 @@ const Top100: React.FC = () => {
const { showSuccess, showError } = useToast();
const [selectedTopPlayed, setSelectedTopPlayed] = useState<TopPlayed | null>(null);
console.log('Top100 component - Redux data:', { topPlayedCount, topPlayedItems: topPlayedItems.length });
debugLog('Top100 component - Redux data:', { topPlayedCount, topPlayedItems: topPlayedItems.length });
const handleTopPlayedClick = useCallback((item: TopPlayed) => {
setSelectedTopPlayed(item);
@ -44,7 +45,7 @@ const Top100: React.FC = () => {
// Use the shared search function with title and artist
const searchTerm = `${selectedTopPlayed.title} ${selectedTopPlayed.artist}`;
console.log('Top100 - Search details:', {
debugLog('Top100 - Search details:', {
selectedTopPlayed,
searchTerm,
allSongsCount: allSongs.length
@ -52,7 +53,7 @@ const Top100: React.FC = () => {
const filteredSongs = filterSongs(allSongs, searchTerm);
console.log('Top100 - Search results:', {
debugLog('Top100 - Search results:', {
filteredSongsCount: filteredSongs.length,
firstFewResults: filteredSongs.slice(0, 3).map(s => `${s.artist} - ${s.title}`)
});
@ -83,7 +84,7 @@ const Top100: React.FC = () => {
const displayCount = topPlayedItems.length;
const displayHasMore = hasMore;
console.log('Top100 component - Real Firebase data:', {
debugLog('Top100 component - Real Firebase data:', {
displayItems: displayItems.length,
displayCount,
displayHasMore,
@ -93,7 +94,7 @@ const Top100: React.FC = () => {
isLoading
});
console.log('Top100 component - About to render JSX');
debugLog('Top100 component - About to render JSX');
return (
<>

View File

@ -9,6 +9,7 @@ import {
update
} from 'firebase/database';
import { database } from './config';
import { debugLog } from '../utils/logger';
import type { Song, QueueItem, Controller, Singer, DisabledSong } from '../types';
// Basic CRUD operations for controllers
@ -336,7 +337,7 @@ export const disabledSongsService = {
// Add a song to the disabled list
addDisabledSong: async (controllerName: string, song: Song) => {
console.log('disabledSongsService.addDisabledSong called with:', { controllerName, song });
debugLog('disabledSongsService.addDisabledSong called with:', { controllerName, song });
if (!controllerName) {
throw new Error('Controller name is required');
@ -351,7 +352,7 @@ export const disabledSongsService = {
}
const songKey = disabledSongsService.generateSongKey(song.path);
console.log('Generated song key:', songKey);
debugLog('Generated song key:', songKey);
const disabledSongRef = ref(database, `controllers/${controllerName}/disabledSongs/${songKey}`);
const disabledSong = {
@ -362,9 +363,9 @@ export const disabledSongsService = {
disabledAt: new Date().toISOString(),
};
console.log('Saving disabled song:', disabledSong);
debugLog('Saving disabled song:', disabledSong);
await set(disabledSongRef, disabledSong);
console.log('Disabled song saved successfully');
debugLog('Disabled song saved successfully');
},
// Remove a song from the disabled list

View File

@ -1,5 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { useAppSelector, selectArtistsArray, selectSongsArray } from '../redux';
import { debugLog } from '../utils/logger';
import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import type { Song } from '../types';
@ -55,17 +56,17 @@ export const useArtists = () => {
}, [artists.length, filteredArtists.length]);
const loadMore = useCallback(() => {
console.log('useArtists - loadMore called:', {
debugLog('useArtists - loadMore called:', {
hasMore,
currentPage,
filteredArtistsLength: filteredArtists.length,
artistsLength: artists.length
});
if (hasMore) {
console.log('useArtists - Incrementing page from', currentPage, 'to', currentPage + 1);
debugLog('useArtists - Incrementing page from', currentPage, 'to', currentPage + 1);
setCurrentPage(prev => prev + 1);
} else {
console.log('useArtists - Not loading more because hasMore is false');
debugLog('useArtists - Not loading more because hasMore is false');
}
}, [hasMore, currentPage, filteredArtists.length, artists.length]);

View File

@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react';
import { disabledSongsService } from '../firebase/services';
import { useAppSelector } from '../redux';
import { selectControllerName } from '../redux';
import { debugLog } from '../utils/logger';
import { useToast } from './useToast';
import type { Song, DisabledSong } from '../types';
@ -66,7 +67,7 @@ export const useDisabledSongs = () => {
}
try {
console.log('Adding disabled song:', { controllerName, song });
debugLog('Adding disabled song:', { controllerName, song });
await disabledSongsService.addDisabledSong(controllerName, song);
showSuccess('Song marked as disabled');
} catch (error) {

View File

@ -1,5 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { useAppSelector, selectFavoritesArray } from '../redux';
import { debugLog } from '../utils/logger';
import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import { useDisabledSongs } from './useDisabledSongs';
@ -28,7 +29,7 @@ export const useFavorites = () => {
}, [favoritesItems.length, allFavoritesItems.length, filterDisabledSongs]);
const loadMore = useCallback(() => {
console.log('useFavorites - loadMore called:', { hasMore, currentPage, allFavoritesItemsLength: allFavoritesItems.length });
debugLog('useFavorites - loadMore called:', { hasMore, currentPage, allFavoritesItemsLength: allFavoritesItems.length });
if (hasMore) {
setCurrentPage(prev => prev + 1);
}

View File

@ -1,5 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { useAppSelector, selectHistoryArray } from '../redux';
import { debugLog } from '../utils/logger';
import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import { useDisabledSongs } from './useDisabledSongs';
@ -28,7 +29,7 @@ export const useHistory = () => {
}, [historyItems.length, allHistoryItems.length, filterDisabledSongs]);
const loadMore = useCallback(() => {
console.log('useHistory - loadMore called:', { hasMore, currentPage, allHistoryItemsLength: allHistoryItems.length });
debugLog('useHistory - loadMore called:', { hasMore, currentPage, allHistoryItemsLength: allHistoryItems.length });
if (hasMore) {
setCurrentPage(prev => prev + 1);
}

View File

@ -1,5 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { useAppSelector, selectNewSongsArray } from '../redux';
import { debugLog } from '../utils/logger';
import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import { useDisabledSongs } from './useDisabledSongs';
@ -28,7 +29,7 @@ export const useNewSongs = () => {
}, [newSongsItems.length, allNewSongsItems.length, filterDisabledSongs]);
const loadMore = useCallback(() => {
console.log('useNewSongs - loadMore called:', { hasMore, currentPage, allNewSongsItemsLength: allNewSongsItems.length });
debugLog('useNewSongs - loadMore called:', { hasMore, currentPage, allNewSongsItemsLength: allNewSongsItems.length });
if (hasMore) {
setCurrentPage(prev => prev + 1);
}

View File

@ -4,6 +4,7 @@ import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import { queueService } from '../firebase/services';
import { selectControllerName } from '../redux';
import { debugLog } from '../utils/logger';
import type { QueueItem } from '../types';
export const useQueue = () => {
@ -25,7 +26,7 @@ export const useQueue = () => {
});
if (needsFix) {
console.log('Fixing queue order...');
debugLog('Fixing queue order...');
try {
// Update all items with sequential order
const updatePromises = queueItems.map((item, index) => {
@ -37,7 +38,7 @@ export const useQueue = () => {
});
await Promise.all(updatePromises);
console.log('Queue order fixed successfully');
debugLog('Queue order fixed successfully');
} catch (error) {
console.error('Failed to fix queue order:', error);
}
@ -83,12 +84,12 @@ export const useQueue = () => {
}, [toggleFavorite, showSuccess, showError]);
const handleMoveUp = useCallback(async (queueItem: QueueItem) => {
console.log('handleMoveUp called with:', queueItem);
console.log('Current queueItems:', queueItems);
console.log('Controller name:', controllerName);
debugLog('handleMoveUp called with:', queueItem);
debugLog('Current queueItems:', queueItems);
debugLog('Controller name:', controllerName);
if (!controllerName || !queueItem.key || queueItem.order <= 1) {
console.log('Early return - conditions not met:', {
debugLog('Early return - conditions not met:', {
controllerName: !!controllerName,
queueItemKey: !!queueItem.key,
order: queueItem.order
@ -99,15 +100,15 @@ export const useQueue = () => {
try {
// Find the item above this one
const itemAbove = queueItems.find(item => item.order === queueItem.order - 1);
console.log('Item above:', itemAbove);
debugLog('Item above:', itemAbove);
if (!itemAbove || !itemAbove.key) {
console.log('No item above found');
debugLog('No item above found');
showError('Cannot move item up');
return;
}
console.log('Swapping orders:', {
debugLog('Swapping orders:', {
currentItem: { key: queueItem.key, order: queueItem.order },
itemAbove: { key: itemAbove.key, order: itemAbove.order }
});
@ -118,7 +119,7 @@ export const useQueue = () => {
queueService.updateQueueItem(controllerName, itemAbove.key, { order: queueItem.order })
]);
console.log('Move up completed successfully');
debugLog('Move up completed successfully');
showSuccess('Song moved up in queue');
} catch (error) {
console.error('Failed to move song up:', error);
@ -127,12 +128,12 @@ export const useQueue = () => {
}, [controllerName, queueItems, showSuccess, showError]);
const handleMoveDown = useCallback(async (queueItem: QueueItem) => {
console.log('handleMoveDown called with:', queueItem);
console.log('Current queueItems:', queueItems);
console.log('Controller name:', controllerName);
debugLog('handleMoveDown called with:', queueItem);
debugLog('Current queueItems:', queueItems);
debugLog('Controller name:', controllerName);
if (!controllerName || !queueItem.key || queueItem.order >= queueItems.length) {
console.log('Early return - conditions not met:', {
debugLog('Early return - conditions not met:', {
controllerName: !!controllerName,
queueItemKey: !!queueItem.key,
order: queueItem.order,
@ -144,15 +145,15 @@ export const useQueue = () => {
try {
// Find the item below this one
const itemBelow = queueItems.find(item => item.order === queueItem.order + 1);
console.log('Item below:', itemBelow);
debugLog('Item below:', itemBelow);
if (!itemBelow || !itemBelow.key) {
console.log('No item below found');
debugLog('No item below found');
showError('Cannot move item down');
return;
}
console.log('Swapping orders:', {
debugLog('Swapping orders:', {
currentItem: { key: queueItem.key, order: queueItem.order },
itemBelow: { key: itemBelow.key, order: itemBelow.order }
});
@ -163,7 +164,7 @@ export const useQueue = () => {
queueService.updateQueueItem(controllerName, itemBelow.key, { order: queueItem.order })
]);
console.log('Move down completed successfully');
debugLog('Move down completed successfully');
showSuccess('Song moved down in queue');
} catch (error) {
console.error('Failed to move song down:', error);
@ -172,12 +173,12 @@ export const useQueue = () => {
}, [controllerName, queueItems, showSuccess, showError]);
const handleReorder = useCallback(async (oldIndex: number, newIndex: number) => {
console.log('handleReorder called with:', { oldIndex, newIndex });
console.log('Current queueItems:', queueItems);
console.log('Controller name:', controllerName);
debugLog('handleReorder called with:', { oldIndex, newIndex });
debugLog('Current queueItems:', queueItems);
debugLog('Controller name:', controllerName);
if (!controllerName || oldIndex === newIndex) {
console.log('Early return - conditions not met:', {
debugLog('Early return - conditions not met:', {
controllerName: !!controllerName,
oldIndex,
newIndex
@ -188,12 +189,12 @@ export const useQueue = () => {
try {
const itemToMove = queueItems[oldIndex];
if (!itemToMove || !itemToMove.key) {
console.log('No item to move found');
debugLog('No item to move found');
showError('Cannot reorder item');
return;
}
console.log('Moving item:', {
debugLog('Moving item:', {
item: { key: itemToMove.key, order: itemToMove.order },
fromIndex: oldIndex,
toIndex: newIndex
@ -233,7 +234,7 @@ export const useQueue = () => {
);
await Promise.all(updatePromises);
console.log('Reorder completed successfully');
debugLog('Reorder completed successfully');
showSuccess('Queue reordered successfully');
} catch (error) {
console.error('Failed to reorder queue:', error);

View File

@ -1,5 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { useAppSelector, selectSongListArray, selectSongsArray } from '../redux';
import { debugLog } from '../utils/logger';
import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import type { SongListSong, Song } from '../types';
@ -23,7 +24,7 @@ export const useSongLists = () => {
const hasMore = useMemo(() => {
// Show "hasMore" if there are more items than currently loaded
const hasMoreItems = songLists.length < allSongLists.length;
console.log('useSongLists - hasMore calculation:', {
debugLog('useSongLists - hasMore calculation:', {
songListsLength: songLists.length,
allSongListsLength: allSongLists.length,
hasMore: hasMoreItems,
@ -36,7 +37,7 @@ export const useSongLists = () => {
const endIndex = currentPage * ITEMS_PER_PAGE;
const hasMoreItems = endIndex < allSongLists.length;
console.log('useSongLists - loadMore called:', {
debugLog('useSongLists - loadMore called:', {
hasMoreItems,
currentPage,
allSongListsLength: allSongLists.length,
@ -44,10 +45,10 @@ export const useSongLists = () => {
});
if (hasMoreItems) {
console.log('useSongLists - Incrementing page from', currentPage, 'to', currentPage + 1);
debugLog('useSongLists - Incrementing page from', currentPage, 'to', currentPage + 1);
setCurrentPage(prev => prev + 1);
} else {
console.log('useSongLists - Not loading more because hasMore is false');
debugLog('useSongLists - Not loading more because hasMore is false');
}
}, [currentPage, allSongLists.length]);

View File

@ -1,5 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { useAppSelector, selectTopPlayedArray } from '../redux';
import { debugLog } from '../utils/logger';
import { useSongOperations } from './useSongOperations';
import { useToast } from './useToast';
import type { TopPlayed } from '../types';
@ -18,7 +19,7 @@ export const useTopPlayed = () => {
const topPlayedItems = useMemo(() => {
const endIndex = currentPage * ITEMS_PER_PAGE;
const result = allTopPlayedItems.slice(0, endIndex);
console.log('useTopPlayed - pagination:', {
debugLog('useTopPlayed - pagination:', {
currentPage,
ITEMS_PER_PAGE,
endIndex,
@ -31,7 +32,7 @@ export const useTopPlayed = () => {
const hasMore = useMemo(() => {
// Show "hasMore" if there are more items than currently loaded
const result = topPlayedItems.length < allTopPlayedItems.length;
console.log('useTopPlayed - hasMore calculation:', {
debugLog('useTopPlayed - hasMore calculation:', {
topPlayedItemsLength: topPlayedItems.length,
allTopPlayedItemsLength: allTopPlayedItems.length,
result
@ -40,7 +41,7 @@ export const useTopPlayed = () => {
}, [topPlayedItems.length, allTopPlayedItems.length]);
const loadMore = useCallback(() => {
console.log('useTopPlayed - loadMore called:', { hasMore, currentPage, allTopPlayedItemsLength: allTopPlayedItems.length });
debugLog('useTopPlayed - loadMore called:', { hasMore, currentPage, allTopPlayedItemsLength: allTopPlayedItems.length });
if (hasMore && !isLoading) {
setIsLoading(true);
// Simulate a small delay to show loading state

View File

@ -1,3 +1,4 @@
import { debugLog } from './logger';
import type { Song, QueueItem, TopPlayed } from '../types';
// Convert Firebase object to array with keys
@ -83,7 +84,7 @@ export const sortSongsByArtistAndTitle = (songs: Song[]): Song[] => {
// Debug logging for first few songs to verify sorting
if (sortedSongs.length > 0) {
console.log('Songs sorted by artist and title. First 5 songs:',
debugLog('Songs sorted by artist and title. First 5 songs:',
sortedSongs.slice(0, 5).map(s => `${s.artist} - ${s.title}`)
);
}

36
src/utils/logger.ts Normal file
View File

@ -0,0 +1,36 @@
// Global debug setting - can be controlled from settings
let debugEnabled = false;
// Setter function to control debug logging
export const setDebugEnabled = (enabled: boolean) => {
debugEnabled = enabled;
};
// Getter function to check if debug is enabled
export const isDebugEnabled = () => debugEnabled;
// Main logging function that takes the same arguments as console.log
export const debugLog = (...args: unknown[]) => {
if (debugEnabled) {
console.log(...args);
}
};
// Convenience functions for different log levels
export const debugInfo = (...args: unknown[]) => {
if (debugEnabled) {
console.info(...args);
}
};
export const debugWarn = (...args: unknown[]) => {
if (debugEnabled) {
console.warn(...args);
}
};
export const debugError = (...args: unknown[]) => {
if (debugEnabled) {
console.error(...args);
}
};