feat: implement multi-provider support in media library
- Introduced IProviderRegistry to manage multiple media providers. - Updated AppState to use provider_registry instead of a single media_provider. - Refactored library routes to support provider-specific queries for collections, series, genres, and items. - Enhanced ProgrammingBlock to include provider_id for algorithmic and manual content types. - Modified frontend components to allow selection of providers and updated API calls to include provider parameters. - Adjusted hooks and types to accommodate provider-specific functionality.
This commit is contained in:
@@ -7,38 +7,38 @@ import type { MediaFilter } from "@/lib/types";
|
||||
|
||||
const STALE = 10 * 60 * 1000; // 10 min — library metadata rarely changes in a session
|
||||
|
||||
/** List top-level collections (Jellyfin libraries, Plex sections, etc.) */
|
||||
export function useCollections() {
|
||||
/** List top-level collections for a provider (empty = primary). */
|
||||
export function useCollections(provider?: string) {
|
||||
const { token } = useAuthContext();
|
||||
return useQuery({
|
||||
queryKey: ["library", "collections"],
|
||||
queryFn: () => api.library.collections(token!),
|
||||
queryKey: ["library", "collections", provider ?? null],
|
||||
queryFn: () => api.library.collections(token!, provider),
|
||||
enabled: !!token,
|
||||
staleTime: STALE,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* List TV series, optionally scoped to a collection.
|
||||
* List TV series, optionally scoped to a collection and provider.
|
||||
* All series are loaded upfront so the series picker can filter client-side
|
||||
* without a request per keystroke.
|
||||
*/
|
||||
export function useSeries(collectionId?: string, opts?: { enabled?: boolean }) {
|
||||
export function useSeries(collectionId?: string, opts?: { enabled?: boolean; provider?: string }) {
|
||||
const { token } = useAuthContext();
|
||||
return useQuery({
|
||||
queryKey: ["library", "series", collectionId ?? null],
|
||||
queryFn: () => api.library.series(token!, collectionId),
|
||||
queryKey: ["library", "series", collectionId ?? null, opts?.provider ?? null],
|
||||
queryFn: () => api.library.series(token!, collectionId, opts?.provider),
|
||||
enabled: !!token && (opts?.enabled ?? true),
|
||||
staleTime: STALE,
|
||||
});
|
||||
}
|
||||
|
||||
/** List available genres, optionally scoped to a content type. */
|
||||
export function useGenres(contentType?: string, opts?: { enabled?: boolean }) {
|
||||
/** List available genres, optionally scoped to a content type and provider. */
|
||||
export function useGenres(contentType?: string, opts?: { enabled?: boolean; provider?: string }) {
|
||||
const { token } = useAuthContext();
|
||||
return useQuery({
|
||||
queryKey: ["library", "genres", contentType ?? null],
|
||||
queryFn: () => api.library.genres(token!, contentType),
|
||||
queryKey: ["library", "genres", contentType ?? null, opts?.provider ?? null],
|
||||
queryFn: () => api.library.genres(token!, contentType, opts?.provider),
|
||||
enabled: !!token && (opts?.enabled ?? true),
|
||||
staleTime: STALE,
|
||||
});
|
||||
@@ -64,11 +64,12 @@ export function useLibraryItems(
|
||||
filter: Pick<MediaFilter, "content_type" | "series_names" | "collections" | "search_term" | "genres"> | null,
|
||||
enabled: boolean,
|
||||
strategy?: string,
|
||||
provider?: string,
|
||||
) {
|
||||
const { token } = useAuthContext();
|
||||
return useQuery({
|
||||
queryKey: ["library", "items", filter, strategy ?? null],
|
||||
queryFn: () => api.library.items(token!, filter!, 30, strategy),
|
||||
queryKey: ["library", "items", filter, strategy ?? null, provider ?? null],
|
||||
queryFn: () => api.library.items(token!, filter!, 30, strategy, provider),
|
||||
enabled: !!token && enabled && !!filter,
|
||||
staleTime: 2 * 60 * 1000,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user