From e3f74aac09e794f33a4a3386461a08771dead3aa Mon Sep 17 00:00:00 2001 From: Adrian Castro <22133246+castdrian@users.noreply.github.com> Date: Sun, 4 Feb 2024 16:14:16 +0100 Subject: [PATCH] feat: implement search via tmdb package --- apps/expo/src/app/(tabs)/search/Searchbar.tsx | 9 ++- apps/expo/src/app/(tabs)/search/_layout.tsx | 65 +++++++++++++++---- apps/expo/src/app/components/item/item.tsx | 14 ++-- packages/tmdb/package.json | 1 + packages/tmdb/src/search.ts | 2 +- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/apps/expo/src/app/(tabs)/search/Searchbar.tsx b/apps/expo/src/app/(tabs)/search/Searchbar.tsx index fef0b7a..20229a0 100644 --- a/apps/expo/src/app/(tabs)/search/Searchbar.tsx +++ b/apps/expo/src/app/(tabs)/search/Searchbar.tsx @@ -5,7 +5,7 @@ import { FontAwesome5 } from "@expo/vector-icons"; import Colors from "@movie-web/tailwind-config/colors"; -export default function Searchbar() { +export default function Searchbar({ onSearchChange }: { onSearchChange: (text: string) => void }) { const [keyword, setKeyword] = useState(""); const inputRef = useRef(null); @@ -22,6 +22,11 @@ export default function Searchbar() { }, []), ); + const handleChange = (text: string) => { + setKeyword(text); + onSearchChange(text); + }; + return ( @@ -29,7 +34,7 @@ export default function Searchbar() { setKeyword(text)} + onChangeText={handleChange} ref={inputRef} placeholder="What are you looking for?" placeholderTextColor={Colors.secondary[200]} diff --git a/apps/expo/src/app/(tabs)/search/_layout.tsx b/apps/expo/src/app/(tabs)/search/_layout.tsx index 8ea2af4..2de62b6 100644 --- a/apps/expo/src/app/(tabs)/search/_layout.tsx +++ b/apps/expo/src/app/(tabs)/search/_layout.tsx @@ -1,11 +1,24 @@ -import { ScrollView, View } from "react-native"; +import React, { useState } from 'react'; +import { ScrollView, View } from 'react-native'; -import Item from "~/components/item/item"; -import ScreenLayout from "~/components/layout/ScreenLayout"; +import Item from '~/components/item/item'; import { Text } from "~/components/ui/Text"; -import Searchbar from "./Searchbar"; +import ScreenLayout from '~/components/layout/ScreenLayout'; +import Searchbar from './Searchbar'; +import { searchTitle, getMediaPoster } from '@movie-web/tmdb'; export default function SearchScreen() { +const [searchResults, setSearchResults] = useState<{ title: string; posterUrl: string; year: number; type: "movie" | "tv"; }[]>([]); + +const handleSearchChange = async (query: string) => { + if (query.length > 0) { + const results = await fetchSearchResults(query); + setSearchResults(results); + } else { + setSearchResults([]); + } +}; + return ( - + - - - - - - - - - + {searchResults.map((item, index) => ( + + + + ))} ); } + +async function fetchSearchResults(query: string): Promise<{ title: string; posterUrl: string; year: number; type: "movie" | "tv"; }[]> { + console.log('Fetching results for:', query); + const results = await searchTitle(query); + + return results.map((result) => { + switch (result.media_type) { + case 'movie': + return { + title: result.title, + posterUrl: getMediaPoster(result.poster_path), + year: new Date(result.release_date).getFullYear(), + type: result.media_type as "movie", + }; + case 'tv': + return { + title: result.name, + posterUrl: getMediaPoster(result.poster_path), + year: new Date(result.first_air_date).getFullYear(), + type: result.media_type as "tv", + }; + default: + return undefined; + } + }).filter((item): item is { title: string; posterUrl: string; year: number; type: "movie" | "tv"; } => item !== undefined); + } + + \ No newline at end of file diff --git a/apps/expo/src/app/components/item/item.tsx b/apps/expo/src/app/components/item/item.tsx index e175f7b..f251cc2 100644 --- a/apps/expo/src/app/components/item/item.tsx +++ b/apps/expo/src/app/components/item/item.tsx @@ -1,25 +1,25 @@ import { Image, View } from "react-native"; - -import { TMDB_POSTER_PATH } from "~/app/constants/General"; import { Text } from "~/components/ui/Text"; -export default function Item() { +export default function Item({ data }: { data: { title: string, type: string, year: number, posterUrl: string } }) { + const { title, type, year, posterUrl } = data; + return ( - Hamilton + {title} - Movie + {type} - 2023 + {year} ); diff --git a/packages/tmdb/package.json b/packages/tmdb/package.json index 3d926ea..a768004 100644 --- a/packages/tmdb/package.json +++ b/packages/tmdb/package.json @@ -3,6 +3,7 @@ "private": true, "version": "0.1.0", "type": "module", + "main": "./src/index.ts", "exports": { ".": "./src/index.ts" }, diff --git a/packages/tmdb/src/search.ts b/packages/tmdb/src/search.ts index 43452e6..37f482d 100644 --- a/packages/tmdb/src/search.ts +++ b/packages/tmdb/src/search.ts @@ -5,7 +5,7 @@ const TMDB_API_KEY = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJkYTM1ZTgyMzE4OTc0NTgxNDJmZjljZTE4ODExNWRlNiIsInN1YiI6IjY0OTM0ZDQ1ODliNTYxMDExYzliZDVhMiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.AzWnIcxPNgDwGdzeIZ_C3mRC_5_qy-Z-SRPglLjzlNc"; const tmdb = new TMDB(TMDB_API_KEY); -export async function searchTitle(query: string): Promise { +export async function searchTitle(query: string) { try { const rawResults = await tmdb.search.multi({ query,