From bdb57f46ed0fd2dca8dcf68d9a11accd2f918353 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 18 Jul 2025 16:53:43 -0500 Subject: [PATCH] Signed-off-by: Matt Bruce --- src/components/Auth/AuthInitializer.tsx | 5 +- src/components/Auth/LoginPrompt.tsx | 7 +-- src/components/Navigation/Navigation.tsx | 7 +-- src/components/common/InfiniteScrollList.tsx | 7 +-- src/components/common/PlayerControls.tsx | 11 +++-- src/features/Artists/Artists.tsx | 9 ++-- src/features/Favorites/Favorites.tsx | 5 +- src/features/History/History.tsx | 5 +- src/features/NewSongs/NewSongs.tsx | 5 +- src/features/Queue/Queue.tsx | 27 ++++++----- src/features/Search/Search.tsx | 11 +++-- src/features/Settings/Settings.tsx | 15 +++++- src/features/Singers/Singers.tsx | 5 +- src/features/TopPlayed/Top100.tsx | 13 ++--- src/firebase/services.ts | 9 ++-- src/hooks/useArtists.ts | 7 +-- src/hooks/useDisabledSongs.ts | 3 +- src/hooks/useFavorites.ts | 3 +- src/hooks/useHistory.ts | 3 +- src/hooks/useNewSongs.ts | 3 +- src/hooks/useQueue.ts | 51 ++++++++++---------- src/hooks/useSongLists.ts | 9 ++-- src/hooks/useTopPlayed.ts | 7 +-- src/utils/dataProcessing.ts | 3 +- src/utils/logger.ts | 36 ++++++++++++++ 25 files changed, 169 insertions(+), 97 deletions(-) create mode 100644 src/utils/logger.ts diff --git a/src/components/Auth/AuthInitializer.tsx b/src/components/Auth/AuthInitializer.tsx index 0dc59af..e5308da 100644 --- a/src/components/Auth/AuthInitializer.tsx +++ b/src/components/Auth/AuthInitializer.tsx @@ -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 = ({ 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 = ({ children }) => { { - console.log('onComplete called, setting showLogin to false'); + debugLog('onComplete called, setting showLogin to false'); setShowLogin(false); }} /> diff --git a/src/components/Auth/LoginPrompt.tsx b/src/components/Auth/LoginPrompt.tsx index 5eafeef..23e12e9 100644 --- a/src/components/Auth/LoginPrompt.tsx +++ b/src/components/Auth/LoginPrompt.tsx @@ -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 = ({ 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 = ({ 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); diff --git a/src/components/Navigation/Navigation.tsx b/src/components/Navigation/Navigation.tsx index bbbb43c..689a665 100644 --- a/src/components/Navigation/Navigation.tsx +++ b/src/components/Navigation/Navigation.tsx @@ -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 (
{ } // For mobile screens, use the Ionic menu - console.log('Rendering mobile menu'); + debugLog('Rendering mobile menu'); return ( { @@ -28,18 +29,18 @@ const InfiniteScrollList = ({ // 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(); } }, diff --git a/src/components/common/PlayerControls.tsx b/src/components/common/PlayerControls.tsx index a70a421..d4611e2 100644 --- a/src/components/common/PlayerControls.tsx +++ b/src/components/common/PlayerControls.tsx @@ -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 = ({ 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 = ({ 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) { diff --git a/src/features/Artists/Artists.tsx b/src/features/Artists/Artists.tsx index 08b2eaf..472df53 100644 --- a/src/features/Artists/Artists.tsx +++ b/src/features/Artists/Artists.tsx @@ -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(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); diff --git a/src/features/Favorites/Favorites.tsx b/src/features/Favorites/Favorites.tsx index 0f0f545..543a85f 100644 --- a/src/features/Favorites/Favorites.tsx +++ b/src/features/Favorites/Favorites.tsx @@ -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 ( <> diff --git a/src/features/History/History.tsx b/src/features/History/History.tsx index 4fe0923..0f34550 100644 --- a/src/features/History/History.tsx +++ b/src/features/History/History.tsx @@ -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) => { diff --git a/src/features/NewSongs/NewSongs.tsx b/src/features/NewSongs/NewSongs.tsx index 56607e4..cab1297 100644 --- a/src/features/NewSongs/NewSongs.tsx +++ b/src/features/NewSongs/NewSongs.tsx @@ -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 ( <> diff --git a/src/features/Queue/Queue.tsx b/src/features/Queue/Queue.tsx index c27bf8a..98563d5 100644 --- a/src/features/Queue/Queue.tsx +++ b/src/features/Queue/Queue.tsx @@ -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 ( diff --git a/src/features/Search/Search.tsx b/src/features/Search/Search.tsx index f8b9622..9dbc74e 100644 --- a/src/features/Search/Search.tsx +++ b/src/features/Search/Search.tsx @@ -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 (
diff --git a/src/features/Settings/Settings.tsx b/src/features/Settings/Settings.tsx index 5dc8d5e..8b86a6a 100644 --- a/src/features/Settings/Settings.tsx +++ b/src/features/Settings/Settings.tsx @@ -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)} /> + + Debug Logging + handleToggleDebug(e.detail.checked)} + /> +
diff --git a/src/features/Singers/Singers.tsx b/src/features/Singers/Singers.tsx index 62b8863..9497577 100644 --- a/src/features/Singers/Singers.tsx +++ b/src/features/Singers/Singers.tsx @@ -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) => ( diff --git a/src/features/TopPlayed/Top100.tsx b/src/features/TopPlayed/Top100.tsx index 8d8f3d9..9a74e6a 100644 --- a/src/features/TopPlayed/Top100.tsx +++ b/src/features/TopPlayed/Top100.tsx @@ -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(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 ( <> diff --git a/src/firebase/services.ts b/src/firebase/services.ts index a27599c..ddd13a6 100644 --- a/src/firebase/services.ts +++ b/src/firebase/services.ts @@ -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 diff --git a/src/hooks/useArtists.ts b/src/hooks/useArtists.ts index 31878bc..26aa2da 100644 --- a/src/hooks/useArtists.ts +++ b/src/hooks/useArtists.ts @@ -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]); diff --git a/src/hooks/useDisabledSongs.ts b/src/hooks/useDisabledSongs.ts index 05d7cad..d5499f0 100644 --- a/src/hooks/useDisabledSongs.ts +++ b/src/hooks/useDisabledSongs.ts @@ -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) { diff --git a/src/hooks/useFavorites.ts b/src/hooks/useFavorites.ts index c549148..f90b648 100644 --- a/src/hooks/useFavorites.ts +++ b/src/hooks/useFavorites.ts @@ -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); } diff --git a/src/hooks/useHistory.ts b/src/hooks/useHistory.ts index 78602f7..c2969b8 100644 --- a/src/hooks/useHistory.ts +++ b/src/hooks/useHistory.ts @@ -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); } diff --git a/src/hooks/useNewSongs.ts b/src/hooks/useNewSongs.ts index 46ff131..1eccc68 100644 --- a/src/hooks/useNewSongs.ts +++ b/src/hooks/useNewSongs.ts @@ -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); } diff --git a/src/hooks/useQueue.ts b/src/hooks/useQueue.ts index 97e1e0c..2f78e41 100644 --- a/src/hooks/useQueue.ts +++ b/src/hooks/useQueue.ts @@ -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); diff --git a/src/hooks/useSongLists.ts b/src/hooks/useSongLists.ts index bea5e78..f461c7e 100644 --- a/src/hooks/useSongLists.ts +++ b/src/hooks/useSongLists.ts @@ -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]); diff --git a/src/hooks/useTopPlayed.ts b/src/hooks/useTopPlayed.ts index 2402ea9..5f83e49 100644 --- a/src/hooks/useTopPlayed.ts +++ b/src/hooks/useTopPlayed.ts @@ -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 diff --git a/src/utils/dataProcessing.ts b/src/utils/dataProcessing.ts index b02fad8..1480c83 100644 --- a/src/utils/dataProcessing.ts +++ b/src/utils/dataProcessing.ts @@ -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}`) ); } diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..a34572d --- /dev/null +++ b/src/utils/logger.ts @@ -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); + } +}; \ No newline at end of file