Signed-off-by: mbrucedogs <mbrucedogs@gmail.com>
This commit is contained in:
parent
e556b4949d
commit
8626251f33
@ -1,11 +1,12 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { IonSearchbar, IonModal, IonHeader, IonToolbar, IonTitle, IonButton, IonIcon, IonContent, IonItem } from '@ionic/react';
|
import { IonSearchbar, IonModal, IonHeader, IonToolbar, IonTitle, IonButton, IonIcon, IonContent, IonItem } from '@ionic/react';
|
||||||
import { close, list } from 'ionicons/icons';
|
import { close, list } from 'ionicons/icons';
|
||||||
import { InfiniteScrollList, SongItem, ListItem, NumberDisplay } from '../../components/common';
|
import { InfiniteScrollList, SongItem, ListItem, NumberDisplay, SongInfo } from '../../components/common';
|
||||||
import { useArtists } from '../../hooks';
|
import { useArtists } from '../../hooks';
|
||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectSongs } from '../../redux';
|
import { selectSongs } from '../../redux';
|
||||||
import { debugLog } from '../../utils/logger';
|
import { debugLog } from '../../utils/logger';
|
||||||
|
import type { Song } from '../../types';
|
||||||
|
|
||||||
const Artists: React.FC = () => {
|
const Artists: React.FC = () => {
|
||||||
const {
|
const {
|
||||||
@ -22,6 +23,8 @@ const Artists: React.FC = () => {
|
|||||||
const songs = useAppSelector(selectSongs);
|
const songs = useAppSelector(selectSongs);
|
||||||
const songsCount = Object.keys(songs).length;
|
const songsCount = Object.keys(songs).length;
|
||||||
const [selectedArtist, setSelectedArtist] = useState<string | null>(null);
|
const [selectedArtist, setSelectedArtist] = useState<string | null>(null);
|
||||||
|
const [selectedSong, setSelectedSong] = useState<Song | null>(null);
|
||||||
|
const [isSongInfoOpen, setIsSongInfoOpen] = useState(false);
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
debugLog('Artists component - artists count:', artists.length);
|
debugLog('Artists component - artists count:', artists.length);
|
||||||
@ -37,6 +40,16 @@ const Artists: React.FC = () => {
|
|||||||
setSelectedArtist(null);
|
setSelectedArtist(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSongInfo = (song: Song) => {
|
||||||
|
setSelectedSong(song);
|
||||||
|
setIsSongInfoOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseSongInfo = () => {
|
||||||
|
setIsSongInfoOpen(false);
|
||||||
|
setSelectedSong(null);
|
||||||
|
};
|
||||||
|
|
||||||
const selectedArtistSongs = selectedArtist ? getSongsByArtist(selectedArtist) : [];
|
const selectedArtistSongs = selectedArtist ? getSongsByArtist(selectedArtist) : [];
|
||||||
|
|
||||||
// Render artist item for InfiniteScrollList
|
// Render artist item for InfiniteScrollList
|
||||||
@ -135,7 +148,7 @@ const Artists: React.FC = () => {
|
|||||||
song={song}
|
song={song}
|
||||||
context="search"
|
context="search"
|
||||||
onAddToQueue={() => handleAddToQueue(song)}
|
onAddToQueue={() => handleAddToQueue(song)}
|
||||||
onSelectSinger={() => {}} // Info button functionality
|
onSelectSinger={() => handleSongInfo(song)}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
showInfoButton={true}
|
showInfoButton={true}
|
||||||
showFavoriteButton={false}
|
showFavoriteButton={false}
|
||||||
@ -150,6 +163,15 @@ const Artists: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</IonContent>
|
</IonContent>
|
||||||
</IonModal>
|
</IonModal>
|
||||||
|
|
||||||
|
{/* Song Info Modal */}
|
||||||
|
{selectedSong && (
|
||||||
|
<SongInfo
|
||||||
|
isOpen={isSongInfoOpen}
|
||||||
|
onClose={handleCloseSongInfo}
|
||||||
|
song={selectedSong}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IonChip, IonIcon } from '@ionic/react';
|
import { IonChip, IonIcon } from '@ionic/react';
|
||||||
import { time } from 'ionicons/icons';
|
import { time } from 'ionicons/icons';
|
||||||
import { InfiniteScrollList, SongItem } from '../../components/common';
|
import { InfiniteScrollList, SongItem, SongInfo } from '../../components/common';
|
||||||
import { useHistory } from '../../hooks';
|
import { useHistory } from '../../hooks';
|
||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectHistory, selectIsAdmin } from '../../redux';
|
import { selectHistory, selectIsAdmin } from '../../redux';
|
||||||
@ -21,11 +21,23 @@ const History: React.FC = () => {
|
|||||||
const history = useAppSelector(selectHistory);
|
const history = useAppSelector(selectHistory);
|
||||||
const isAdmin = useAppSelector(selectIsAdmin);
|
const isAdmin = useAppSelector(selectIsAdmin);
|
||||||
const historyCount = Object.keys(history).length;
|
const historyCount = Object.keys(history).length;
|
||||||
|
const [selectedSong, setSelectedSong] = React.useState<Song | null>(null);
|
||||||
|
const [isSongInfoOpen, setIsSongInfoOpen] = React.useState(false);
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
debugLog('History component - history count:', historyCount);
|
debugLog('History component - history count:', historyCount);
|
||||||
debugLog('History component - history items:', historyItems);
|
debugLog('History component - history items:', historyItems);
|
||||||
|
|
||||||
|
const handleSongInfo = (song: Song) => {
|
||||||
|
setSelectedSong(song);
|
||||||
|
setIsSongInfoOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseSongInfo = () => {
|
||||||
|
setIsSongInfoOpen(false);
|
||||||
|
setSelectedSong(null);
|
||||||
|
};
|
||||||
|
|
||||||
// Render extra content for history items (play date)
|
// Render extra content for history items (play date)
|
||||||
const renderExtraContent = (item: Song) => {
|
const renderExtraContent = (item: Song) => {
|
||||||
if (item.date) {
|
if (item.date) {
|
||||||
@ -53,7 +65,7 @@ const History: React.FC = () => {
|
|||||||
song={song}
|
song={song}
|
||||||
context="history"
|
context="history"
|
||||||
onAddToQueue={() => handleAddToQueue(song)}
|
onAddToQueue={() => handleAddToQueue(song)}
|
||||||
onSelectSinger={() => {}} // Info button functionality
|
onSelectSinger={() => handleSongInfo(song)}
|
||||||
onDeleteItem={() => handleDeleteFromHistory(song)}
|
onDeleteItem={() => handleDeleteFromHistory(song)}
|
||||||
isAdmin={isAdmin}
|
isAdmin={isAdmin}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
@ -70,6 +82,15 @@ const History: React.FC = () => {
|
|||||||
loadingTitle="Loading history..."
|
loadingTitle="Loading history..."
|
||||||
loadingMessage="Please wait while history data is being loaded"
|
loadingMessage="Please wait while history data is being loaded"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Song Info Modal */}
|
||||||
|
{selectedSong && (
|
||||||
|
<SongInfo
|
||||||
|
isOpen={isSongInfoOpen}
|
||||||
|
onClose={handleCloseSongInfo}
|
||||||
|
song={selectedSong}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { InfiniteScrollList, SongItem } from '../../components/common';
|
import { InfiniteScrollList, SongItem, SongInfo } from '../../components/common';
|
||||||
import { useNewSongs } from '../../hooks';
|
import { useNewSongs } from '../../hooks';
|
||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectNewSongsArray } from '../../redux';
|
import { selectNewSongsArray } from '../../redux';
|
||||||
@ -16,11 +16,23 @@ const NewSongs: React.FC = () => {
|
|||||||
|
|
||||||
const newSongsArray = useAppSelector(selectNewSongsArray);
|
const newSongsArray = useAppSelector(selectNewSongsArray);
|
||||||
const newSongsCount = newSongsArray.length;
|
const newSongsCount = newSongsArray.length;
|
||||||
|
const [selectedSong, setSelectedSong] = React.useState<Song | null>(null);
|
||||||
|
const [isSongInfoOpen, setIsSongInfoOpen] = React.useState(false);
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
debugLog('NewSongs component - new songs count:', newSongsCount);
|
debugLog('NewSongs component - new songs count:', newSongsCount);
|
||||||
debugLog('NewSongs component - new songs items:', newSongsItems);
|
debugLog('NewSongs component - new songs items:', newSongsItems);
|
||||||
|
|
||||||
|
const handleSongInfo = (song: Song) => {
|
||||||
|
setSelectedSong(song);
|
||||||
|
setIsSongInfoOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseSongInfo = () => {
|
||||||
|
setIsSongInfoOpen(false);
|
||||||
|
setSelectedSong(null);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InfiniteScrollList<Song>
|
<InfiniteScrollList<Song>
|
||||||
@ -33,6 +45,7 @@ const NewSongs: React.FC = () => {
|
|||||||
song={song}
|
song={song}
|
||||||
context="search"
|
context="search"
|
||||||
onAddToQueue={() => handleAddToQueue(song)}
|
onAddToQueue={() => handleAddToQueue(song)}
|
||||||
|
onSelectSinger={() => handleSongInfo(song)}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
showInfoButton={true}
|
showInfoButton={true}
|
||||||
showFavoriteButton={false}
|
showFavoriteButton={false}
|
||||||
@ -43,6 +56,15 @@ const NewSongs: React.FC = () => {
|
|||||||
loadingTitle="Loading new songs..."
|
loadingTitle="Loading new songs..."
|
||||||
loadingMessage="Please wait while new songs data is being loaded"
|
loadingMessage="Please wait while new songs data is being loaded"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Song Info Modal */}
|
||||||
|
{selectedSong && (
|
||||||
|
<SongInfo
|
||||||
|
isOpen={isSongInfoOpen}
|
||||||
|
onClose={handleCloseSongInfo}
|
||||||
|
song={selectedSong}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useMemo, useCallback } from 'react';
|
import React, { useState, useMemo, useCallback } from 'react';
|
||||||
import { IonItem, IonModal, IonHeader, IonToolbar, IonTitle, IonButton, IonIcon, IonChip, IonContent, IonList, IonAccordionGroup, IonAccordion } from '@ionic/react';
|
import { IonItem, IonModal, IonHeader, IonToolbar, IonTitle, IonButton, IonIcon, IonChip, IonContent, IonList, IonAccordionGroup, IonAccordion } from '@ionic/react';
|
||||||
import { close, list } from 'ionicons/icons';
|
import { close, list } from 'ionicons/icons';
|
||||||
import { InfiniteScrollList, SongItem, ListItem, TwoLineDisplay, NumberDisplay } from '../../components/common';
|
import { InfiniteScrollList, SongItem, ListItem, TwoLineDisplay, NumberDisplay, SongInfo } from '../../components/common';
|
||||||
import { useSongLists } from '../../hooks';
|
import { useSongLists } from '../../hooks';
|
||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectSongList } from '../../redux';
|
import { selectSongList } from '../../redux';
|
||||||
@ -22,6 +22,8 @@ const SongLists: React.FC = () => {
|
|||||||
const songListCount = Object.keys(songListData).length;
|
const songListCount = Object.keys(songListData).length;
|
||||||
const [selectedSongList, setSelectedSongList] = useState<string | null>(null);
|
const [selectedSongList, setSelectedSongList] = useState<string | null>(null);
|
||||||
const [expandedSongKey, setExpandedSongKey] = useState<string | null>(null);
|
const [expandedSongKey, setExpandedSongKey] = useState<string | null>(null);
|
||||||
|
const [selectedSong, setSelectedSong] = useState<Song | null>(null);
|
||||||
|
const [isSongInfoOpen, setIsSongInfoOpen] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +41,16 @@ const SongLists: React.FC = () => {
|
|||||||
setExpandedSongKey(expandedSongKey === songKey ? null : songKey);
|
setExpandedSongKey(expandedSongKey === songKey ? null : songKey);
|
||||||
}, [expandedSongKey]);
|
}, [expandedSongKey]);
|
||||||
|
|
||||||
|
const handleSongInfo = useCallback((song: Song) => {
|
||||||
|
setSelectedSong(song);
|
||||||
|
setIsSongInfoOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCloseSongInfo = useCallback(() => {
|
||||||
|
setIsSongInfoOpen(false);
|
||||||
|
setSelectedSong(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const finalSelectedList = selectedSongList
|
const finalSelectedList = selectedSongList
|
||||||
? allSongLists.find(list => list.key === selectedSongList)
|
? allSongLists.find(list => list.key === selectedSongList)
|
||||||
: null;
|
: null;
|
||||||
@ -132,7 +144,7 @@ const SongLists: React.FC = () => {
|
|||||||
song={song}
|
song={song}
|
||||||
context="search"
|
context="search"
|
||||||
onAddToQueue={() => handleAddToQueue(song)}
|
onAddToQueue={() => handleAddToQueue(song)}
|
||||||
onSelectSinger={() => {}} // Info button functionality
|
onSelectSinger={() => handleSongInfo(song)}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
showInfoButton={true}
|
showInfoButton={true}
|
||||||
showFavoriteButton={false}
|
showFavoriteButton={false}
|
||||||
@ -173,6 +185,15 @@ const SongLists: React.FC = () => {
|
|||||||
</IonAccordionGroup>
|
</IonAccordionGroup>
|
||||||
</IonContent>
|
</IonContent>
|
||||||
</IonModal>
|
</IonModal>
|
||||||
|
|
||||||
|
{/* Song Info Modal */}
|
||||||
|
{selectedSong && (
|
||||||
|
<SongInfo
|
||||||
|
isOpen={isSongInfoOpen}
|
||||||
|
onClose={handleCloseSongInfo}
|
||||||
|
song={selectedSong}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { close, list } from 'ionicons/icons';
|
|||||||
import { useTopPlayed } from '../../hooks';
|
import { useTopPlayed } from '../../hooks';
|
||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectTopPlayed, selectSongsArray } from '../../redux';
|
import { selectTopPlayed, selectSongsArray } from '../../redux';
|
||||||
import { InfiniteScrollList, SongItem, ListItem } from '../../components/common';
|
import { InfiniteScrollList, SongItem, ListItem, SongInfo } from '../../components/common';
|
||||||
import { filterSongs } from '../../utils/dataProcessing';
|
import { filterSongs } from '../../utils/dataProcessing';
|
||||||
import { debugLog } from '../../utils/logger';
|
import { debugLog } from '../../utils/logger';
|
||||||
import { useSongOperations } from '../../hooks';
|
import { useSongOperations } from '../../hooks';
|
||||||
@ -27,6 +27,8 @@ const Top100: React.FC = () => {
|
|||||||
const { addToQueue } = useSongOperations();
|
const { addToQueue } = useSongOperations();
|
||||||
const { showSuccess, showError } = useToast();
|
const { showSuccess, showError } = useToast();
|
||||||
const [selectedTopPlayed, setSelectedTopPlayed] = useState<TopPlayed | null>(null);
|
const [selectedTopPlayed, setSelectedTopPlayed] = useState<TopPlayed | null>(null);
|
||||||
|
const [selectedSong, setSelectedSong] = useState<Song | null>(null);
|
||||||
|
const [isSongInfoOpen, setIsSongInfoOpen] = useState(false);
|
||||||
|
|
||||||
debugLog('Top100 component - Redux data:', { topPlayedCount, topPlayedItems: topPlayedItems.length });
|
debugLog('Top100 component - Redux data:', { topPlayedCount, topPlayedItems: topPlayedItems.length });
|
||||||
|
|
||||||
@ -38,6 +40,16 @@ const Top100: React.FC = () => {
|
|||||||
setSelectedTopPlayed(null);
|
setSelectedTopPlayed(null);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleSongInfo = useCallback((song: Song) => {
|
||||||
|
setSelectedSong(song);
|
||||||
|
setIsSongInfoOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCloseSongInfo = useCallback(() => {
|
||||||
|
setIsSongInfoOpen(false);
|
||||||
|
setSelectedSong(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Find songs that match the selected top played item
|
// Find songs that match the selected top played item
|
||||||
const selectedSongs = useMemo(() => {
|
const selectedSongs = useMemo(() => {
|
||||||
if (!selectedTopPlayed) return [];
|
if (!selectedTopPlayed) return [];
|
||||||
@ -141,7 +153,7 @@ const Top100: React.FC = () => {
|
|||||||
song={song}
|
song={song}
|
||||||
context="search"
|
context="search"
|
||||||
onAddToQueue={() => handleAddToQueue(song)}
|
onAddToQueue={() => handleAddToQueue(song)}
|
||||||
onSelectSinger={() => {}} // Info button functionality
|
onSelectSinger={() => handleSongInfo(song)}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
showInfoButton={true}
|
showInfoButton={true}
|
||||||
showFavoriteButton={false}
|
showFavoriteButton={false}
|
||||||
@ -150,6 +162,15 @@ const Top100: React.FC = () => {
|
|||||||
</IonList>
|
</IonList>
|
||||||
</IonContent>
|
</IonContent>
|
||||||
</IonModal>
|
</IonModal>
|
||||||
|
|
||||||
|
{/* Song Info Modal */}
|
||||||
|
{selectedSong && (
|
||||||
|
<SongInfo
|
||||||
|
isOpen={isSongInfoOpen}
|
||||||
|
onClose={handleCloseSongInfo}
|
||||||
|
song={selectedSong}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user