diff --git a/src/backend/metadata/search.ts b/src/backend/metadata/search.ts
index 08671db7..2bbee195 100644
--- a/src/backend/metadata/search.ts
+++ b/src/backend/metadata/search.ts
@@ -7,6 +7,8 @@ import {
getMediaDetails,
getMediaPoster,
multiSearch,
+ searchMovies,
+ searchTVShows,
} from "./tmdb";
import { TMDBContentTypes } from "./types/tmdb";
@@ -26,6 +28,9 @@ const tmdbIdPattern = /^tmdb:(\d+)(?::(movie|tv))?$/i;
// detect "year:YYYY"
const yearPattern = /(.+?)\s+year:(\d{4})$/i;
+// detect "type:movie" or "type:tv"
+const typePattern = /(.+?)\s+type:(movie|tv)$/i;
+
export async function searchForMedia(query: MWQuery): Promise {
if (cache.has(query)) return cache.get(query) as MediaItem[];
const { searchQuery } = query;
@@ -82,8 +87,25 @@ export async function searchForMedia(query: MWQuery): Promise {
yearValue = yearMatch[2];
}
- // normal search
- const data = await multiSearch(queryWithoutYear);
+ // type extract logic
+ let typeValue: string | undefined;
+ let queryWithoutType = queryWithoutYear;
+
+ const typeMatch = queryWithoutYear.match(typePattern);
+ if (typeMatch && typeMatch[2]) {
+ queryWithoutType = typeMatch[1].trim();
+ typeValue = typeMatch[2].toLowerCase();
+ }
+
+ let data: any[];
+ if (typeValue === "movie") {
+ data = await searchMovies(queryWithoutType);
+ } else if (typeValue === "tv") {
+ data = await searchTVShows(queryWithoutType);
+ } else {
+ data = await multiSearch(queryWithoutType);
+ }
+
let results = data.map((v) => {
const formattedResult = formatTMDBSearchResult(v, v.media_type);
return formatTMDBMetaToMediaItem(formattedResult);
diff --git a/src/backend/metadata/tmdb.ts b/src/backend/metadata/tmdb.ts
index 875046e7..92628fe2 100644
--- a/src/backend/metadata/tmdb.ts
+++ b/src/backend/metadata/tmdb.ts
@@ -248,6 +248,38 @@ export async function multiSearch(
return results;
}
+export async function searchMovies(
+ query: string,
+): Promise {
+ const data = await get<{
+ results: TMDBMovieSearchResult[];
+ }>("search/movie", {
+ query,
+ include_adult: false,
+ page: 1,
+ });
+ return data.results.map((result) => ({
+ ...result,
+ media_type: TMDBContentTypes.MOVIE,
+ }));
+}
+
+export async function searchTVShows(
+ query: string,
+): Promise {
+ const data = await get<{
+ results: TMDBShowSearchResult[];
+ }>("search/tv", {
+ query,
+ include_adult: false,
+ page: 1,
+ });
+ return data.results.map((result) => ({
+ ...result,
+ media_type: TMDBContentTypes.TV,
+ }));
+}
+
export async function generateQuickSearchMediaUrl(
query: string,
): Promise {
diff --git a/src/components/form/SearchBar.tsx b/src/components/form/SearchBar.tsx
index 6ef95665..b86abcd3 100644
--- a/src/components/form/SearchBar.tsx
+++ b/src/components/form/SearchBar.tsx
@@ -114,6 +114,15 @@ export const SearchBarInput = forwardRef(
Inception year:2010
+
+
Type search:
+
+ Marvel type:movie
+
+
+ Friends type:tv
+
+