- Implemented LocalFilesProvider to manage local video files. - Added LocalIndex for in-memory and SQLite-backed indexing of video files. - Introduced scanning functionality to detect video files and extract metadata. - Added API endpoints for listing collections, genres, and series based on provider capabilities. - Enhanced existing routes to check for provider capabilities before processing requests. - Updated frontend to utilize provider capabilities for conditional rendering of UI elements. - Implemented rescan functionality to refresh the local files index. - Added database migration for local files index schema.
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { api } from "@/lib/api";
|
|
import { useAuthContext } from "@/context/auth-context";
|
|
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() {
|
|
const { token } = useAuthContext();
|
|
return useQuery({
|
|
queryKey: ["library", "collections"],
|
|
queryFn: () => api.library.collections(token!),
|
|
enabled: !!token,
|
|
staleTime: STALE,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* List TV series, optionally scoped to a collection.
|
|
* 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 }) {
|
|
const { token } = useAuthContext();
|
|
return useQuery({
|
|
queryKey: ["library", "series", collectionId ?? null],
|
|
queryFn: () => api.library.series(token!, collectionId),
|
|
enabled: !!token && (opts?.enabled ?? true),
|
|
staleTime: STALE,
|
|
});
|
|
}
|
|
|
|
/** List available genres, optionally scoped to a content type. */
|
|
export function useGenres(contentType?: string, opts?: { enabled?: boolean }) {
|
|
const { token } = useAuthContext();
|
|
return useQuery({
|
|
queryKey: ["library", "genres", contentType ?? null],
|
|
queryFn: () => api.library.genres(token!, contentType),
|
|
enabled: !!token && (opts?.enabled ?? true),
|
|
staleTime: STALE,
|
|
});
|
|
}
|
|
|
|
/** Trigger a local-files rescan. Only available when `provider_capabilities.rescan` is true. */
|
|
export function useRescanLibrary() {
|
|
const { token } = useAuthContext();
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: () => api.files.rescan(token!),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ["library"] });
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch items matching a filter for the block editor's "Preview results" panel.
|
|
* Pass `enabled: false` until the user explicitly requests a preview.
|
|
*/
|
|
export function useLibraryItems(
|
|
filter: Pick<MediaFilter, "content_type" | "series_names" | "collections" | "search_term" | "genres"> | null,
|
|
enabled: boolean,
|
|
strategy?: string,
|
|
) {
|
|
const { token } = useAuthContext();
|
|
return useQuery({
|
|
queryKey: ["library", "items", filter, strategy ?? null],
|
|
queryFn: () => api.library.items(token!, filter!, 30, strategy),
|
|
enabled: !!token && enabled && !!filter,
|
|
staleTime: 2 * 60 * 1000,
|
|
});
|
|
}
|