feat: implement playArtist function to play all albums by an artist and update QueuePage layout
This commit is contained in:
@@ -21,7 +21,7 @@ export default function ArtistPage() {
|
||||
const [artist, setArtist] = useState<Artist | null>(null);
|
||||
const [isPlayingArtist, setIsPlayingArtist] = useState(false);
|
||||
const { getArtist, starItem, unstarItem } = useNavidrome();
|
||||
const { addArtistToQueue, playAlbum, clearQueue } = useAudioPlayer();
|
||||
const { playArtist } = useAudioPlayer();
|
||||
const { toast } = useToast();
|
||||
const api = getNavidromeAPI();
|
||||
|
||||
@@ -65,19 +65,7 @@ export default function ArtistPage() {
|
||||
|
||||
setIsPlayingArtist(true);
|
||||
try {
|
||||
// Clear current queue and add all artist albums
|
||||
clearQueue();
|
||||
await addArtistToQueue(artist.id);
|
||||
|
||||
// Start playing the first album if we have any
|
||||
if (artistAlbums.length > 0) {
|
||||
await playAlbum(artistAlbums[0].id);
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Playing Artist",
|
||||
description: `Now playing all albums by ${artist.name}`,
|
||||
});
|
||||
await playArtist(artist.id);
|
||||
} catch (error) {
|
||||
console.error('Failed to play artist:', error);
|
||||
toast({
|
||||
|
||||
@@ -36,6 +36,7 @@ interface AudioPlayerContextProps {
|
||||
shuffle: boolean;
|
||||
toggleShuffle: () => void;
|
||||
shuffleAllAlbums: () => Promise<void>;
|
||||
playArtist: (artistId: string) => Promise<void>;
|
||||
}
|
||||
|
||||
const AudioPlayerContext = createContext<AudioPlayerContextProps | undefined>(undefined);
|
||||
@@ -420,6 +421,55 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
|
||||
}
|
||||
}, [api, songToTrack, toast]);
|
||||
|
||||
const playArtist = useCallback(async (artistId: string) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { artist, albums } = await api.getArtist(artistId);
|
||||
let allTracks: Track[] = [];
|
||||
|
||||
// Collect all tracks from all albums
|
||||
for (const album of albums) {
|
||||
const { songs } = await api.getAlbum(album.id);
|
||||
const tracks = songs.map(songToTrack);
|
||||
allTracks = allTracks.concat(tracks);
|
||||
}
|
||||
|
||||
if (allTracks.length > 0) {
|
||||
if (shuffle) {
|
||||
// If shuffle is enabled, shuffle all tracks
|
||||
const shuffledTracks = [...allTracks];
|
||||
// Fisher-Yates shuffle algorithm
|
||||
for (let i = shuffledTracks.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[shuffledTracks[i], shuffledTracks[j]] = [shuffledTracks[j], shuffledTracks[i]];
|
||||
}
|
||||
|
||||
// Play the first shuffled track and set the rest as queue
|
||||
playTrack(shuffledTracks[0]);
|
||||
setQueue(shuffledTracks.slice(1));
|
||||
} else {
|
||||
// Normal order: play first track and set the rest as queue
|
||||
playTrack(allTracks[0]);
|
||||
setQueue(allTracks.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Playing Artist",
|
||||
description: `Now playing all albums by "${artist.name}"${shuffle ? ' (shuffled)' : ''}`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to play artist:', error);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error",
|
||||
description: "Failed to play artist albums",
|
||||
});
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [api, songToTrack, toast, shuffle, playTrack]);
|
||||
|
||||
const contextValue = useMemo(() => ({
|
||||
currentTrack,
|
||||
playTrack,
|
||||
@@ -437,7 +487,8 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
|
||||
skipToTrackInQueue,
|
||||
shuffle,
|
||||
toggleShuffle,
|
||||
shuffleAllAlbums
|
||||
shuffleAllAlbums,
|
||||
playArtist
|
||||
}), [
|
||||
currentTrack,
|
||||
queue,
|
||||
@@ -455,7 +506,8 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
|
||||
skipToTrackInQueue,
|
||||
shuffle,
|
||||
toggleShuffle,
|
||||
shuffleAllAlbums
|
||||
shuffleAllAlbums,
|
||||
playArtist
|
||||
]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -19,7 +19,7 @@ const QueuePage: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full px-4 py-6 lg:px-8">
|
||||
<div className="h-full px-4 py-6 lg:px-8 pb-24">
|
||||
<div className="space-y-6">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
|
||||
Reference in New Issue
Block a user