feat: add API availability checks and fallback for cover art in various components
This commit is contained in:
@@ -80,8 +80,12 @@ export default function AlbumPage() {
|
||||
console.error('Failed to play album from track:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddToQueue = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -106,9 +110,8 @@ export default function AlbumPage() {
|
||||
const seconds = duration % 60;
|
||||
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
// Get cover art URL with proper fallback
|
||||
const coverArtUrl = album.coverArt
|
||||
const coverArtUrl = album.coverArt && api
|
||||
? api.getCoverArtUrl(album.coverArt, 300)
|
||||
: '/default-user.jpg';
|
||||
|
||||
|
||||
@@ -89,9 +89,8 @@ export default function ArtistPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Get artist image URL with proper fallback
|
||||
const artistImageUrl = artist.coverArt
|
||||
const artistImageUrl = artist.coverArt && api
|
||||
? api.getCoverArtUrl(artist.coverArt, 300)
|
||||
: '/default-user.jpg';
|
||||
|
||||
|
||||
@@ -24,8 +24,12 @@ export default function BrowsePage() {
|
||||
const albumsPerPage = 84;
|
||||
|
||||
const api = getNavidromeAPI();
|
||||
|
||||
const loadAlbums = async (page: number, append: boolean = false) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoadingAlbums(true);
|
||||
const offset = page * albumsPerPage;
|
||||
|
||||
@@ -57,9 +57,8 @@ export function AlbumArtwork({
|
||||
starItem(album.id, 'album');
|
||||
}
|
||||
};
|
||||
|
||||
// Get cover art URL with proper fallback
|
||||
const coverArtUrl = album.coverArt
|
||||
const coverArtUrl = album.coverArt && api
|
||||
? api.getCoverArtUrl(album.coverArt, 300)
|
||||
: '/default-user.jpg';
|
||||
|
||||
|
||||
@@ -52,9 +52,8 @@ export function ArtistIcon({
|
||||
starItem(artist.id, 'artist');
|
||||
}
|
||||
};
|
||||
|
||||
// Get cover art URL with proper fallback
|
||||
const artistImageUrl = artist.coverArt
|
||||
const artistImageUrl = artist.coverArt && api
|
||||
? api.getCoverArtUrl(artist.coverArt, 200)
|
||||
: '/default-user.jpg';
|
||||
|
||||
|
||||
@@ -51,9 +51,8 @@ const PlaylistsPage: React.FC = () => {
|
||||
<Separator className="my-4" />
|
||||
<div className="relative">
|
||||
<ScrollArea>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 pb-4">
|
||||
{playlists.map((playlist) => {
|
||||
const playlistCoverUrl = playlist.coverArt
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 pb-4"> {playlists.map((playlist) => {
|
||||
const playlistCoverUrl = playlist.coverArt && api
|
||||
? api.getCoverArtUrl(playlist.coverArt, 200)
|
||||
: '/default-user.jpg';
|
||||
|
||||
|
||||
@@ -101,8 +101,12 @@ export default function SongsPage() {
|
||||
|
||||
setFilteredSongs(filtered);
|
||||
}, [songs, searchQuery, sortBy, sortDirection]);
|
||||
|
||||
const handlePlaySong = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -117,8 +121,12 @@ export default function SongsPage() {
|
||||
|
||||
playTrack(track);
|
||||
};
|
||||
|
||||
const handleAddToQueue = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -229,9 +237,8 @@ export default function SongsPage() {
|
||||
</div>
|
||||
|
||||
{/* Album Art */}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0">
|
||||
<Image
|
||||
src={song.coverArt ? api.getCoverArtUrl(song.coverArt, 100) : '/default-user.jpg'}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0"> <Image
|
||||
src={song.coverArt && api ? api.getCoverArtUrl(song.coverArt, 100) : '/default-user.jpg'}
|
||||
alt={song.album}
|
||||
width={48}
|
||||
height={48}
|
||||
|
||||
@@ -44,8 +44,12 @@ export default function PlaylistPage() {
|
||||
fetchPlaylist();
|
||||
}
|
||||
}, [id, getPlaylist]);
|
||||
|
||||
const handlePlayClick = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -59,8 +63,12 @@ export default function PlaylistPage() {
|
||||
};
|
||||
playTrack(track);
|
||||
};
|
||||
|
||||
const handleAddToQueue = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -74,9 +82,11 @@ export default function PlaylistPage() {
|
||||
};
|
||||
addToQueue(track);
|
||||
};
|
||||
|
||||
const handlePlayPlaylist = () => {
|
||||
if (tracklist.length === 0) return;
|
||||
if (tracklist.length === 0 || !api) {
|
||||
if (!api) console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert all songs to tracks
|
||||
const tracks = tracklist.map(song => ({
|
||||
@@ -125,9 +135,8 @@ export default function PlaylistPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Get playlist cover art URL with fallback
|
||||
const playlistCoverUrl = playlist.coverArt
|
||||
const playlistCoverUrl = playlist.coverArt && api
|
||||
? api.getCoverArtUrl(playlist.coverArt, 300)
|
||||
: '/default-user.jpg';
|
||||
|
||||
@@ -196,9 +205,8 @@ export default function PlaylistPage() {
|
||||
</div>
|
||||
|
||||
{/* Album Art */}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0">
|
||||
<Image
|
||||
src={song.coverArt ? api.getCoverArtUrl(song.coverArt, 100) : '/default-user.jpg'}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0"> <Image
|
||||
src={song.coverArt && api ? api.getCoverArtUrl(song.coverArt, 100) : '/default-user.jpg'}
|
||||
alt={song.album}
|
||||
width={48}
|
||||
height={48}
|
||||
|
||||
@@ -22,11 +22,13 @@ const RadioStationsPage = () => {
|
||||
});
|
||||
const { toast } = useToast();
|
||||
const { playTrack } = useAudioPlayer();
|
||||
|
||||
const loadRadioStations = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const api = getNavidromeAPI();
|
||||
if (!api) {
|
||||
throw new Error('Navidrome API not available');
|
||||
}
|
||||
const stationList = await api.getInternetRadioStations();
|
||||
setStations(stationList);
|
||||
} catch (error) {
|
||||
@@ -53,10 +55,11 @@ const RadioStationsPage = () => {
|
||||
variant: "destructive"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
} try {
|
||||
const api = getNavidromeAPI();
|
||||
if (!api) {
|
||||
throw new Error('Navidrome API not available');
|
||||
}
|
||||
await api.createInternetRadioStation(
|
||||
newStation.name,
|
||||
newStation.streamUrl,
|
||||
@@ -81,9 +84,11 @@ const RadioStationsPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const deleteRadioStation = async (stationId: string) => {
|
||||
try {
|
||||
const deleteRadioStation = async (stationId: string) => { try {
|
||||
const api = getNavidromeAPI();
|
||||
if (!api) {
|
||||
throw new Error('Navidrome API not available');
|
||||
}
|
||||
await api.deleteInternetRadioStation(stationId);
|
||||
|
||||
toast({
|
||||
|
||||
@@ -51,8 +51,12 @@ export default function SearchPage() {
|
||||
return () => clearTimeout(timeoutId);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [searchQuery]);
|
||||
|
||||
const handlePlaySong = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -67,8 +71,12 @@ export default function SearchPage() {
|
||||
|
||||
playTrack(track);
|
||||
};
|
||||
|
||||
const handleAddToQueue = (song: Song) => {
|
||||
if (!api) {
|
||||
console.error('Navidrome API not available');
|
||||
return;
|
||||
}
|
||||
|
||||
const track = {
|
||||
id: song.id,
|
||||
name: song.title,
|
||||
@@ -182,9 +190,8 @@ export default function SearchPage() {
|
||||
</div>
|
||||
|
||||
{/* Song Cover */}
|
||||
<div className="flex-shrink-0">
|
||||
<Image
|
||||
src={song.coverArt ? api.getCoverArtUrl(song.coverArt, 64) : '/default-user.jpg'}
|
||||
<div className="flex-shrink-0"> <Image
|
||||
src={song.coverArt && api ? api.getCoverArtUrl(song.coverArt, 64) : '/default-user.jpg'}
|
||||
alt={song.album}
|
||||
width={48}
|
||||
height={48}
|
||||
|
||||
Reference in New Issue
Block a user