mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +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,
|
TMDBMovieExternalIds,
|
||||||
TMDBMovieResponse,
|
TMDBMovieResponse,
|
||||||
TMDBMovieResult,
|
TMDBMovieResult,
|
||||||
|
TMDBMovieSearchResult,
|
||||||
|
TMDBSearchResult,
|
||||||
TMDBSeason,
|
TMDBSeason,
|
||||||
TMDBSeasonMetaResult,
|
TMDBSeasonMetaResult,
|
||||||
TMDBShowData,
|
TMDBShowData,
|
||||||
TMDBShowExternalIds,
|
TMDBShowExternalIds,
|
||||||
TMDBShowResponse,
|
TMDBShowResponse,
|
||||||
TMDBShowResult,
|
TMDBShowResult,
|
||||||
|
TMDBShowSearchResult,
|
||||||
} from "./types/tmdb";
|
} from "./types/tmdb";
|
||||||
import { mwFetch } from "../helpers/fetch";
|
import { mwFetch } from "../helpers/fetch";
|
||||||
|
|
||||||
|
@ -150,6 +153,37 @@ export async function searchMedia(
|
||||||
return data;
|
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
|
// Conditional type which for inferring the return type based on the content type
|
||||||
type MediaDetailReturn<T extends TMDBContentTypes> = T extends "movie"
|
type MediaDetailReturn<T extends TMDBContentTypes> = T extends "movie"
|
||||||
? TMDBMovieData
|
? TMDBMovieData
|
||||||
|
|
|
@ -306,3 +306,46 @@ export interface ExternalIdMovieSearchResult {
|
||||||
tv_episode_results: any[];
|
tv_episode_results: any[];
|
||||||
tv_season_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,
|
Switch,
|
||||||
useHistory,
|
useHistory,
|
||||||
useLocation,
|
useLocation,
|
||||||
|
useParams,
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
|
|
||||||
import { convertLegacyUrl, isLegacyUrl } from "@/backend/metadata/getmeta";
|
import { convertLegacyUrl, isLegacyUrl } from "@/backend/metadata/getmeta";
|
||||||
|
import { generateQuickSearchMediaUrl } from "@/backend/metadata/tmdb";
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||||
import { BannerContextProvider } from "@/hooks/useBanner";
|
import { BannerContextProvider } from "@/hooks/useBanner";
|
||||||
import { Layout } from "@/setup/Layout";
|
import { Layout } from "@/setup/Layout";
|
||||||
|
@ -35,6 +37,23 @@ function LegacyUrlView({ children }: { children: ReactElement }) {
|
||||||
return children;
|
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() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<SettingsProvider>
|
<SettingsProvider>
|
||||||
|
@ -48,6 +67,9 @@ function App() {
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<Redirect to={`/search/${MWMediaType.MOVIE}`} />
|
<Redirect to={`/search/${MWMediaType.MOVIE}`} />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route exact path="/s/:query">
|
||||||
|
<QuickSearch />
|
||||||
|
</Route>
|
||||||
|
|
||||||
{/* pages */}
|
{/* pages */}
|
||||||
<Route exact path="/media/:media">
|
<Route exact path="/media/:media">
|
||||||
|
|
Loading…
Reference in a new issue