mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
implement quicksearch
This commit is contained in:
parent
7ee1c13760
commit
517ef2f8cd
3 changed files with 99 additions and 0 deletions
|
@ -13,12 +13,15 @@ import {
|
|||
TMDBMovieExternalIds,
|
||||
TMDBMovieResponse,
|
||||
TMDBMovieResult,
|
||||
TMDBMovieSearchResult,
|
||||
TMDBSearchResult,
|
||||
TMDBSeason,
|
||||
TMDBSeasonMetaResult,
|
||||
TMDBShowData,
|
||||
TMDBShowExternalIds,
|
||||
TMDBShowResponse,
|
||||
TMDBShowResult,
|
||||
TMDBShowSearchResult,
|
||||
} from "./types/tmdb";
|
||||
import { mwFetch } from "../helpers/fetch";
|
||||
|
||||
|
@ -150,6 +153,37 @@ export async function searchMedia(
|
|||
return data;
|
||||
}
|
||||
|
||||
export async function multiSearch(
|
||||
query: string
|
||||
): Promise<(TMDBMovieSearchResult | TMDBShowSearchResult)[]> {
|
||||
const data = await get<TMDBSearchResult>(`search/multi`, {
|
||||
query,
|
||||
include_adult: false,
|
||||
language: "en-US",
|
||||
page: 1,
|
||||
});
|
||||
// filter out results that aren't movies or shows
|
||||
const results = data.results.filter(
|
||||
(r) => r.media_type === "movie" || r.media_type === "tv"
|
||||
);
|
||||
return results;
|
||||
}
|
||||
|
||||
export async function generateQuickSearchMediaUrl(
|
||||
query: string
|
||||
): Promise<string | undefined> {
|
||||
const data = await multiSearch(query);
|
||||
if (data.length === 0) return undefined;
|
||||
const result = data[0];
|
||||
const type = result.media_type === "movie" ? "movie" : "show";
|
||||
const title = result.media_type === "movie" ? result.title : result.name;
|
||||
|
||||
return `/media/tmdb-${type}-${result.id}-${slugify(title, {
|
||||
lower: true,
|
||||
strict: true,
|
||||
})}`;
|
||||
}
|
||||
|
||||
// Conditional type which for inferring the return type based on the content type
|
||||
type MediaDetailReturn<T extends TMDBContentTypes> = T extends "movie"
|
||||
? TMDBMovieData
|
||||
|
|
|
@ -306,3 +306,46 @@ export interface ExternalIdMovieSearchResult {
|
|||
tv_episode_results: any[];
|
||||
tv_season_results: any[];
|
||||
}
|
||||
|
||||
export interface TMDBMovieSearchResult {
|
||||
adult: boolean;
|
||||
backdrop_path: string;
|
||||
id: number;
|
||||
title: string;
|
||||
original_language: string;
|
||||
original_title: string;
|
||||
overview: string;
|
||||
poster_path: string;
|
||||
media_type: "movie";
|
||||
genre_ids: number[];
|
||||
popularity: number;
|
||||
release_date: string;
|
||||
video: boolean;
|
||||
vote_average: number;
|
||||
vote_count: number;
|
||||
}
|
||||
|
||||
export interface TMDBShowSearchResult {
|
||||
adult: boolean;
|
||||
backdrop_path: string;
|
||||
id: number;
|
||||
name: string;
|
||||
original_language: string;
|
||||
original_name: string;
|
||||
overview: string;
|
||||
poster_path: string;
|
||||
media_type: "tv";
|
||||
genre_ids: number[];
|
||||
popularity: number;
|
||||
first_air_date: string;
|
||||
vote_average: number;
|
||||
vote_count: number;
|
||||
origin_country: string[];
|
||||
}
|
||||
|
||||
export interface TMDBSearchResult {
|
||||
page: number;
|
||||
results: (TMDBMovieSearchResult | TMDBShowSearchResult)[];
|
||||
total_pages: number;
|
||||
total_results: number;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@ import {
|
|||
Switch,
|
||||
useHistory,
|
||||
useLocation,
|
||||
useParams,
|
||||
} from "react-router-dom";
|
||||
|
||||
import { convertLegacyUrl, isLegacyUrl } from "@/backend/metadata/getmeta";
|
||||
import { generateQuickSearchMediaUrl } from "@/backend/metadata/tmdb";
|
||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||
import { BannerContextProvider } from "@/hooks/useBanner";
|
||||
import { Layout } from "@/setup/Layout";
|
||||
|
@ -35,6 +37,23 @@ function LegacyUrlView({ children }: { children: ReactElement }) {
|
|||
return children;
|
||||
}
|
||||
|
||||
function QuickSearch() {
|
||||
const { query } = useParams<{ query: string }>();
|
||||
const { replace } = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
if (query) {
|
||||
generateQuickSearchMediaUrl(query).then((url) => {
|
||||
replace(url ?? "/");
|
||||
});
|
||||
} else {
|
||||
replace("/");
|
||||
}
|
||||
}, [query, replace]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<SettingsProvider>
|
||||
|
@ -48,6 +67,9 @@ function App() {
|
|||
<Route exact path="/">
|
||||
<Redirect to={`/search/${MWMediaType.MOVIE}`} />
|
||||
</Route>
|
||||
<Route exact path="/s/:query">
|
||||
<QuickSearch />
|
||||
</Route>
|
||||
|
||||
{/* pages */}
|
||||
<Route exact path="/media/:media">
|
||||
|
|
Loading…
Reference in a new issue