Initial release v1.0.0
This commit is contained in:
146
frontend/features/library/hooks/useLibraryActions.ts
Normal file
146
frontend/features/library/hooks/useLibraryActions.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { api } from "@/lib/api";
|
||||
import { useAudio } from "@/lib/audio-context";
|
||||
import { Track } from "../types";
|
||||
|
||||
// Helper to convert library Track to audio context Track format
|
||||
const formatTrackForAudio = (track: Track) => ({
|
||||
id: track.id,
|
||||
title: track.title,
|
||||
duration: track.duration,
|
||||
artist: {
|
||||
id: track.album?.artist?.id,
|
||||
name: track.album?.artist?.name || "Unknown Artist",
|
||||
},
|
||||
album: {
|
||||
id: track.album?.id,
|
||||
title: track.album?.title || "Unknown Album",
|
||||
coverArt: track.album?.coverArt,
|
||||
},
|
||||
});
|
||||
|
||||
export function useLibraryActions() {
|
||||
const { playTrack, playTracks, addToQueue } = useAudio();
|
||||
|
||||
const playArtist = async (artistId: string) => {
|
||||
try {
|
||||
const albumsData = await api.getAlbums({ artistId });
|
||||
if (!albumsData.albums || albumsData.albums.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const firstAlbum = await api.getAlbum(albumsData.albums[0].id);
|
||||
if (
|
||||
!firstAlbum ||
|
||||
!firstAlbum.tracks ||
|
||||
firstAlbum.tracks.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tracksWithAlbum = firstAlbum.tracks.map((track: any) => ({
|
||||
...track,
|
||||
album: {
|
||||
id: firstAlbum.id,
|
||||
title: firstAlbum.title,
|
||||
coverArt: firstAlbum.coverArt || firstAlbum.coverUrl,
|
||||
},
|
||||
artist: {
|
||||
id: firstAlbum.artist?.id,
|
||||
name: firstAlbum.artist?.name,
|
||||
},
|
||||
}));
|
||||
|
||||
playTracks(tracksWithAlbum, 0);
|
||||
} catch (error) {
|
||||
console.error("Error playing artist:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const playAlbum = async (albumId: string) => {
|
||||
try {
|
||||
const album = await api.getAlbum(albumId);
|
||||
if (!album || !album.tracks || album.tracks.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tracksWithAlbum = album.tracks.map((track: any) => ({
|
||||
...track,
|
||||
album: {
|
||||
id: album.id,
|
||||
title: album.title,
|
||||
coverArt: album.coverArt || album.coverUrl,
|
||||
},
|
||||
artist: {
|
||||
id: album.artist?.id,
|
||||
name: album.artist?.name,
|
||||
},
|
||||
}));
|
||||
|
||||
playTracks(tracksWithAlbum, 0);
|
||||
} catch (error) {
|
||||
console.error("Error playing album:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const playTrackAction = (track: Track) => {
|
||||
try {
|
||||
playTrack(formatTrackForAudio(track));
|
||||
} catch (error) {
|
||||
console.error("Error playing track:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const addTrackToQueue = (track: Track) => {
|
||||
try {
|
||||
addToQueue(formatTrackForAudio(track));
|
||||
} catch (error) {
|
||||
console.error("Error adding track to queue:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const addTrackToPlaylist = async (playlistId: string, trackId: string) => {
|
||||
try {
|
||||
await api.addTrackToPlaylist(playlistId, trackId);
|
||||
} catch (error) {
|
||||
console.error("Error adding track to playlist:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteTrack = async (id: string): Promise<void> => {
|
||||
try {
|
||||
await api.deleteTrack(id);
|
||||
} catch (error) {
|
||||
console.error("Error deleting track:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteAlbum = async (id: string): Promise<void> => {
|
||||
try {
|
||||
await api.deleteAlbum(id);
|
||||
} catch (error) {
|
||||
console.error("Error deleting album:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteArtist = async (id: string): Promise<void> => {
|
||||
try {
|
||||
await api.deleteArtist(id);
|
||||
} catch (error) {
|
||||
console.error("Error deleting artist:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
playArtist,
|
||||
playAlbum,
|
||||
playTrack: playTrackAction,
|
||||
addTrackToQueue,
|
||||
addTrackToPlaylist,
|
||||
deleteTrack,
|
||||
deleteAlbum,
|
||||
deleteArtist,
|
||||
};
|
||||
}
|
||||
64
frontend/features/library/hooks/useLibraryData.ts
Normal file
64
frontend/features/library/hooks/useLibraryData.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { Artist, Album, Track, Tab } from "../types";
|
||||
import { api } from "@/lib/api";
|
||||
import { useAuth } from "@/lib/auth-context";
|
||||
|
||||
export type LibraryFilter = "owned" | "discovery" | "all";
|
||||
|
||||
interface UseLibraryDataProps {
|
||||
activeTab: Tab;
|
||||
filter?: LibraryFilter;
|
||||
}
|
||||
|
||||
export function useLibraryData({
|
||||
activeTab,
|
||||
filter = "owned",
|
||||
}: UseLibraryDataProps) {
|
||||
const [artists, setArtists] = useState<Artist[]>([]);
|
||||
const [albums, setAlbums] = useState<Album[]>([]);
|
||||
const [tracks, setTracks] = useState<Track[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { isAuthenticated } = useAuth();
|
||||
|
||||
const loadData = useCallback(async () => {
|
||||
if (!isAuthenticated) return;
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (activeTab === "artists") {
|
||||
const { artists } = await api.getArtists({
|
||||
limit: 500,
|
||||
filter,
|
||||
});
|
||||
setArtists(artists);
|
||||
} else if (activeTab === "albums") {
|
||||
const { albums } = await api.getAlbums({ limit: 500, filter });
|
||||
setAlbums(albums);
|
||||
} else if (activeTab === "tracks") {
|
||||
// Tracks filter could be added later if needed
|
||||
const { tracks } = await api.getTracks({ limit: 500 });
|
||||
setTracks(tracks);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load library data:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [activeTab, filter, isAuthenticated]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, [loadData]);
|
||||
|
||||
const reloadData = () => {
|
||||
loadData();
|
||||
};
|
||||
|
||||
return {
|
||||
artists,
|
||||
albums,
|
||||
tracks,
|
||||
isLoading,
|
||||
reloadData,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user