diff --git a/package.json b/package.json index 77f9709..38cff80 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "react-native-screens": "~4.1.0", "react-native-svg": "15.8.0", "react-native-web": "~0.19.13", + "react-native-web-webview": "^1.0.2", "react-native-webview": "13.12.5", "react-native-youtube-iframe": "^2.3.0" }, diff --git a/src/api/api.ts b/src/api/api.ts index e190995..a88e661 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -1,3 +1,6 @@ +import type { AxiosResponse } from 'axios'; +import axios from 'axios'; + import { LOCALE_I18N } from 'constants/locales'; export const BASE_API_URL = 'https://api.themoviedb.org/3/'; @@ -18,9 +21,19 @@ export type GetApiUrlProps = { query: string; }; -export type GetApiUrlReturn = { +type HttpMethod = 'get' | 'post' | 'put' | 'delete'; + +type GetApiUrlReturn = { + callApi: ( + page?: number, + method?: HttpMethod + ) => Promise>; queryParams?: string[]; - queryUrl: (page?: number) => string; +}; + +export type CallApiProps = { + method?: HttpMethod; + page?: number; }; export function getApi({ params, query }: GetApiUrlProps): GetApiUrlReturn { @@ -37,11 +50,25 @@ export function getApi({ params, query }: GetApiUrlProps): GetApiUrlReturn { const queryUrl = (page?: number) => { const pageParam = page ? `&page=${page}` : ''; - return `${BASE_API_URL}${query}?api_key=${process.env.EXPO_PUBLIC_THEMOVIEDB_API_KEY}&language=${LOCALE_I18N}${pageParam}${queryParamsUrl}`; + return `${BASE_API_URL}${query}?language=${LOCALE_I18N}${pageParam}${queryParamsUrl}`; + }; + + const callApi = ( + page?: number, + method: HttpMethod = 'get' + ): Promise> => { + return axios({ + method, + url: queryUrl(page), + headers: { + Accept: 'application/json', + Authorization: `Bearer ${process.env.EXPO_PUBLIC_THEMOVIEDB_API_KEY}` + } + }); }; return { queryParams, - queryUrl + callApi }; } diff --git a/src/api/discover.ts b/src/api/discover.ts index 63dcccf..4fa5439 100644 --- a/src/api/discover.ts +++ b/src/api/discover.ts @@ -1,6 +1,5 @@ import { useInfiniteQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE } from 'constants/locales'; @@ -30,7 +29,7 @@ export type UseGetDiscoverMovieApiProps = { export function useGetDiscoverTv(props?: UseGetDiscoverTvApiProps) { const { maxPages = 30, params } = props || {}; - const { queryParams, queryUrl } = getApi({ + const { callApi, queryParams } = getApi({ query: 'discover/tv', params }); @@ -39,7 +38,7 @@ export function useGetDiscoverTv(props?: UseGetDiscoverTvApiProps) { queryKey: ['discover', 'tv', ...queryParams, LOCALE], queryFn: async ({ pageParam }) => { const { data }: AxiosResponse = - await axios.get(queryUrl(pageParam)); + await callApi(pageParam); return data; }, initialPageParam: 1, @@ -52,7 +51,7 @@ export function useGetDiscoverTv(props?: UseGetDiscoverTvApiProps) { export function useGetDiscoverMovie(props?: UseGetDiscoverMovieApiProps) { const { maxPages = 30, params } = props || {}; - const { queryParams, queryUrl } = getApi({ + const { callApi, queryParams } = getApi({ query: 'discover/movie', params }); @@ -61,7 +60,7 @@ export function useGetDiscoverMovie(props?: UseGetDiscoverMovieApiProps) { queryKey: ['discover', 'movie', ...queryParams, LOCALE], queryFn: async ({ pageParam }) => { const { data }: AxiosResponse = - await axios.get(queryUrl(pageParam)); + await callApi(pageParam); return data; }, initialPageParam: 1, diff --git a/src/api/genres.ts b/src/api/genres.ts index cf7f6bb..04ec773 100644 --- a/src/api/genres.ts +++ b/src/api/genres.ts @@ -1,6 +1,5 @@ import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE } from 'constants/locales'; @@ -13,7 +12,7 @@ export type UseGetGenreTvListApiResponse = paths['/3/genre/tv/list']['get']['responses']['200']['content']['application/json']; export function useGetGenreMovieList() { - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: 'genre/movie/list' }); @@ -21,7 +20,7 @@ export function useGetGenreMovieList() { queryKey: ['genre', 'movie', 'list', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data?.genres; } @@ -29,7 +28,7 @@ export function useGetGenreMovieList() { } export function useGetGenreTvList() { - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: 'genre/tv/list' }); @@ -37,7 +36,7 @@ export function useGetGenreTvList() { queryKey: ['genre', 'tv', 'list', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data.genres; } }); diff --git a/src/api/logo.ts b/src/api/logo.ts index a043ba8..9397b15 100644 --- a/src/api/logo.ts +++ b/src/api/logo.ts @@ -1,7 +1,6 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import type { Locale } from 'constants/locales'; import { LOCALE } from 'constants/locales'; @@ -53,7 +52,7 @@ export function useGetContentLogo( const locales = `${LOCALE},en`; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `${type}/${id}/images`, params: [ { @@ -67,7 +66,7 @@ export function useGetContentLogo( queryKey: [type, id, 'images', 'logo', locales], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return formatImageToLogo(data, LOCALE); }, diff --git a/src/api/movie.ts b/src/api/movie.ts index 819881a..6524b0b 100644 --- a/src/api/movie.ts +++ b/src/api/movie.ts @@ -1,7 +1,6 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE, REGION_CODE } from 'constants/locales'; import type { NetworkId } from 'types/content'; @@ -57,15 +56,14 @@ export type UseGetMovie = UseQueryResult< export function useGetMovie(props?: UseGetMovieApiProps): UseGetMovie { const { id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `movie/${id}` }); return useQuery({ queryKey: ['movie', id, LOCALE], queryFn: async () => { - const { data }: AxiosResponse = - await axios.get(queryUrl()); + const { data }: AxiosResponse = await callApi(); const networkId = getNetworkFromUrl(data.homepage); @@ -102,7 +100,7 @@ export function useGetMovie(props?: UseGetMovieApiProps): UseGetMovie { export function useGetMovieCredits(props?: UseGetMovieEnabledApiProps) { const { enabled, id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `movie/${id}/credits` }); @@ -110,7 +108,7 @@ export function useGetMovieCredits(props?: UseGetMovieEnabledApiProps) { queryKey: ['movie', id, 'credits', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return { cast: data.cast.slice(0, 30) @@ -125,7 +123,7 @@ export function useGetMovieImages(props?: UseGetMovieEnabledApiProps) { const locales = `${LOCALE},en`; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `movie/${id}/images`, params: [ { @@ -139,7 +137,7 @@ export function useGetMovieImages(props?: UseGetMovieEnabledApiProps) { queryKey: ['movie', id, 'images', locales], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, @@ -148,7 +146,7 @@ export function useGetMovieImages(props?: UseGetMovieEnabledApiProps) { } export function useGetMovieNowPlaying() { - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: 'movie/now_playing', params: [{ name: 'region', value: REGION_CODE }] }); @@ -157,7 +155,7 @@ export function useGetMovieNowPlaying() { queryKey: ['movies', 'now_playing', REGION_CODE, LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; } @@ -165,7 +163,7 @@ export function useGetMovieNowPlaying() { } export function useGetMovieUpcoming() { - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: 'movie/upcoming', params: [{ name: 'region', value: REGION_CODE }] }); @@ -174,7 +172,7 @@ export function useGetMovieUpcoming() { queryKey: ['movies', 'upcoming', REGION_CODE, LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; } @@ -184,7 +182,7 @@ export function useGetMovieUpcoming() { export function useGetMovieSimilar(props?: UseGetMovieEnabledApiProps) { const { enabled, id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `movie/${id}/similar` }); @@ -192,7 +190,7 @@ export function useGetMovieSimilar(props?: UseGetMovieEnabledApiProps) { queryKey: ['movie', id, 'similar', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, @@ -203,7 +201,7 @@ export function useGetMovieSimilar(props?: UseGetMovieEnabledApiProps) { export function useGetMovieVideos(props?: UseGetMovieApiProps) { const { id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `movie/${id}/videos` }); @@ -211,7 +209,7 @@ export function useGetMovieVideos(props?: UseGetMovieApiProps) { queryKey: ['movie', id, 'videos', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, diff --git a/src/api/person.ts b/src/api/person.ts index cf51552..16f044a 100644 --- a/src/api/person.ts +++ b/src/api/person.ts @@ -1,7 +1,6 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE } from 'constants/locales'; @@ -45,15 +44,14 @@ export type UseGetPerson = UseQueryResult< export function useGetPerson(props?: UseGetPersonApiProps): UseGetPerson { const { id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `person/${id}` }); return useQuery({ queryKey: ['person', id, LOCALE], queryFn: async () => { - const { data }: AxiosResponse = - await axios.get(queryUrl()); + const { data }: AxiosResponse = await callApi(); return { biography: data.biography, @@ -74,7 +72,7 @@ export function useGetPersonMovieCredits( ) { const { id, isActing } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `person/${id}/movie_credits` }); @@ -82,7 +80,7 @@ export function useGetPersonMovieCredits( queryKey: ['person', id, 'movies', isActing, LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return isActing ? data.cast : data.crew; }, @@ -95,7 +93,7 @@ export function useGetPersonTvCredits( ) { const { id, isActing } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `person/${id}/tv_credits` }); @@ -103,7 +101,7 @@ export function useGetPersonTvCredits( queryKey: ['person', id, 'tv', isActing, LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return isActing ? data.cast : data.crew; }, @@ -116,7 +114,7 @@ export function useGetPersonCredits( ) { const { id, isActing } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `person/${id}/combined_credits` }); @@ -124,7 +122,7 @@ export function useGetPersonCredits( queryKey: ['person', id, 'credits', isActing, LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return isActing ? data.cast : data.crew; }, @@ -137,7 +135,7 @@ export function useGetPersonImages(props?: UseGetPersonApiProps) { const locales = `${LOCALE},en`; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `person/${id}/images`, params: [ { @@ -151,7 +149,7 @@ export function useGetPersonImages(props?: UseGetPersonApiProps) { queryKey: ['person', id, 'tv', 'images', locales], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data.profiles; }, @@ -160,7 +158,7 @@ export function useGetPersonImages(props?: UseGetPersonApiProps) { } export function useGetPersonPopular() { - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: 'person/popular' }); @@ -168,7 +166,7 @@ export function useGetPersonPopular() { queryKey: ['person', 'popular', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; } diff --git a/src/api/search.ts b/src/api/search.ts index 726dcac..9ddd749 100644 --- a/src/api/search.ts +++ b/src/api/search.ts @@ -1,6 +1,5 @@ import { useInfiniteQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE } from 'constants/locales'; @@ -22,7 +21,7 @@ export type UseGetSearchApiProps = { export function useGetSearch(props?: UseGetSearchApiProps) { const { maxPages = 30, params } = props || {}; - const { queryParams, queryUrl } = getApi({ + const { callApi, queryParams } = getApi({ query: 'search/multi', params }); @@ -30,9 +29,9 @@ export function useGetSearch(props?: UseGetSearchApiProps) { return useInfiniteQuery({ queryKey: ['search', 'multi', ...queryParams, LOCALE], queryFn: async ({ pageParam }) => { - const { data }: AxiosResponse = await axios.get( - queryUrl(pageParam) - ); + const { data }: AxiosResponse = + await callApi(pageParam); + return data; }, initialPageParam: 1, diff --git a/src/api/trending.ts b/src/api/trending.ts index 5d94d57..3a99608 100644 --- a/src/api/trending.ts +++ b/src/api/trending.ts @@ -1,6 +1,5 @@ import { useInfiniteQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE } from 'constants/locales'; @@ -23,7 +22,7 @@ export type UseGetTrendingApiProps = { export function useGetTrending(props?: UseGetTrendingApiProps) { const { maxPages = 30, type = 'all' } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `trending/${type}/day` }); @@ -31,7 +30,7 @@ export function useGetTrending(props?: UseGetTrendingApiProps) { queryKey: ['trending', type, LOCALE], queryFn: async ({ pageParam }) => { const { data }: AxiosResponse = - await axios.get(queryUrl(pageParam)); + await callApi(pageParam); return data; }, initialPageParam: 1, diff --git a/src/api/tv.ts b/src/api/tv.ts index 1ab9e5f..42171b0 100644 --- a/src/api/tv.ts +++ b/src/api/tv.ts @@ -1,7 +1,6 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; -import axios from 'axios'; import { LOCALE } from 'constants/locales'; import type { NetworkId } from 'types/content'; @@ -74,15 +73,14 @@ export type UseGetTv = UseQueryResult< export function useGetTv(props?: UseGetTvApiProps): UseGetTv { const { id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `tv/${id}` }); return useQuery({ queryKey: ['tv', id, LOCALE], queryFn: async () => { - const { data }: AxiosResponse = - await axios.get(queryUrl()); + const { data }: AxiosResponse = await callApi(); const startYear = data.first_air_date ? new Date(data.first_air_date).getFullYear() @@ -130,7 +128,7 @@ export function useGetTv(props?: UseGetTvApiProps): UseGetTv { export function useGetTvSeason(props?: UseGetTvWithSeasonApiProps) { const { id, seasonNumber } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `tv/${id}/season/${seasonNumber}` }); @@ -138,7 +136,7 @@ export function useGetTvSeason(props?: UseGetTvWithSeasonApiProps) { queryKey: ['tv', id, 'season', seasonNumber, LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, @@ -149,7 +147,7 @@ export function useGetTvSeason(props?: UseGetTvWithSeasonApiProps) { export function useGetTvCredits(props?: UseGetTvEnabledApiProps) { const { enabled, id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `tv/${id}/aggregate_credits` }); @@ -157,7 +155,7 @@ export function useGetTvCredits(props?: UseGetTvEnabledApiProps) { queryKey: ['tv', id, 'credits', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return { cast: data.cast.slice(0, 30) @@ -172,7 +170,7 @@ export function useGetTvImages(props?: UseGetTvEnabledApiProps) { const locales = `${LOCALE},en`; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `tv/${id}/images`, params: [ { @@ -186,7 +184,7 @@ export function useGetTvImages(props?: UseGetTvEnabledApiProps) { queryKey: ['tv', id, 'images', locales], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, @@ -197,7 +195,7 @@ export function useGetTvImages(props?: UseGetTvEnabledApiProps) { export function useGetTvSimilar(props?: UseGetTvEnabledApiProps) { const { enabled, id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `tv/${id}/similar` }); @@ -205,7 +203,7 @@ export function useGetTvSimilar(props?: UseGetTvEnabledApiProps) { queryKey: ['tv', id, 'similar', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, @@ -216,7 +214,7 @@ export function useGetTvSimilar(props?: UseGetTvEnabledApiProps) { export function useGetTvVideos(props?: UseGetTvApiProps) { const { id } = props || {}; - const { queryUrl } = getApi({ + const { callApi } = getApi({ query: `tv/${id}/videos` }); @@ -224,7 +222,7 @@ export function useGetTvVideos(props?: UseGetTvApiProps) { queryKey: ['tv', id, 'videos', LOCALE], queryFn: async () => { const { data }: AxiosResponse = - await axios.get(queryUrl()); + await callApi(); return data; }, diff --git a/yarn.lock b/yarn.lock index aae0dbc..38bbb9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8791,6 +8791,13 @@ qrcode-terminal@0.11.0: resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz#ffc6c28a2fc0bfb47052b47e23f4f446a5fbdb9e" integrity sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ== +qs@^6.5.1: + version "6.13.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.1.tgz#3ce5fc72bd3a8171b85c99b93c65dd20b7d1b16e" + integrity sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg== + dependencies: + side-channel "^1.0.6" + query-string@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" @@ -8947,6 +8954,13 @@ react-native-svg@15.8.0: css-tree "^1.1.3" warn-once "0.1.1" +react-native-web-webview@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-native-web-webview/-/react-native-web-webview-1.0.2.tgz#c215efa70c17589f2c8d640b1f1dc669b18c6e02" + integrity sha512-oNAYNuqUqeqTuAAdIejzDqvUtYA+k5lrvhUYmASdUznZNmyIaoQFA6OKoA4K9F3wdMvark42vUXkUWIp875ewg== + dependencies: + qs "^6.5.1" + react-native-web@~0.19.13: version "0.19.13" resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.19.13.tgz#2d84849bf0251ec0e3a8072fda7f9a7c29375331"