Files
ersatztv/web/src/api/search.ts
T

65 lines
2.5 KiB
TypeScript

import { ApiError, request } from './client';
import type { components } from './generated/v1';
import type { AddItemsToCollectionRequest } from './collections';
export type SearchResults = components['schemas']['SearchResultsResponseModel'];
export type SearchResultGroup = components['schemas']['SearchResultGroupResponseModel'];
// The ten media-item id arrays a search query resolves to, one bucket per addable kind. Wire keys
// match AddItemsToCollectionRequest exactly, so a result pipes straight into addItemsToCollection /
// addItemsToPlaylist via toAddItemsRequestFromSearch below.
export type SearchAllItemIds = components['schemas']['SearchResultAllItemsResponseModel'];
export interface GetSearchResultsParams {
query: string;
pageSize?: number;
}
export function getSearchResults(params: GetSearchResultsParams): Promise<SearchResults> {
const searchParams = new URLSearchParams();
searchParams.set('query', params.query);
if (params.pageSize != null) {
searchParams.set('pageSize', String(params.pageSize));
}
return request<SearchResults>(`/api/search?${searchParams.toString()}`);
}
// Resolves a search query to the full set of matching media-item ids, bucketed by kind. Backs the
// "Add all results" flow so the caller never has to page through every result to add them.
export function getSearchAllItems(query: string): Promise<SearchAllItemIds> {
const searchParams = new URLSearchParams();
searchParams.set('query', query);
return request<SearchAllItemIds>(`/api/search/all-items?${searchParams.toString()}`);
}
// Normalizes a SearchAllItemIds result (nullable arrays) into a full AddItemsToCollectionRequest
// so it can be piped straight into addItemsToCollection / addItemsToPlaylist.
export function toAddItemsRequestFromSearch(result: SearchAllItemIds): AddItemsToCollectionRequest {
return {
artistIds: result.artistIds ?? [],
episodeIds: result.episodeIds ?? [],
imageIds: result.imageIds ?? [],
movieIds: result.movieIds ?? [],
musicVideoIds: result.musicVideoIds ?? [],
otherVideoIds: result.otherVideoIds ?? [],
remoteStreamIds: result.remoteStreamIds ?? [],
seasonIds: result.seasonIds ?? [],
showIds: result.showIds ?? [],
songIds: result.songIds ?? []
};
}
export function messageFromSearchError(error: unknown, fallback = 'Unable to search library'): string {
if (error instanceof ApiError) {
return error.detail ?? error.message;
}
if (error instanceof Error) {
return error.message;
}
return fallback;
}