39 lines
998 B
TypeScript
39 lines
998 B
TypeScript
/** The whole album index, fetched once.
|
|
|
|
At roughly 90 kB for a real collection this is cheaper than a search endpoint and makes
|
|
type-to-search instant, which is what the keyboard-first design needs.
|
|
*/
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
|
|
import { api } from "../api/client";
|
|
import type { Album } from "../api/types";
|
|
|
|
export interface Library {
|
|
albums: Album[];
|
|
loading: boolean;
|
|
error: string | null;
|
|
reload: () => void;
|
|
}
|
|
|
|
export function useLibrary(): Library {
|
|
const [albums, setAlbums] = useState<Album[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const reload = useCallback(() => {
|
|
api
|
|
.library()
|
|
.then((loaded) => {
|
|
setAlbums(loaded);
|
|
setError(null);
|
|
})
|
|
.catch((cause: unknown) => setError(String(cause)))
|
|
.finally(() => setLoading(false));
|
|
}, []);
|
|
|
|
useEffect(reload, [reload]);
|
|
|
|
return { albums, loading, error, reload };
|
|
}
|