add watch providers
This commit is contained in:
parent
5fcde524fe
commit
8225d77a99
25
src/App.css
25
src/App.css
|
@ -52,6 +52,11 @@ main {
|
|||
font-size: 1.6rem;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0;
|
||||
|
@ -134,7 +139,7 @@ main {
|
|||
|
||||
|
||||
#background {
|
||||
/* background-color: black; */
|
||||
background-color: black;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -145,6 +150,24 @@ main {
|
|||
.CrossfadeImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: blur(1rem) brightness(0.4);
|
||||
}
|
||||
|
||||
#watch-providers {
|
||||
display: flex;
|
||||
|
||||
h1 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.watch-logos-container {
|
||||
display: flex;
|
||||
gap: 0.4rem;
|
||||
|
||||
.watch-logo {
|
||||
width: 30px;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
16
src/App.tsx
16
src/App.tsx
|
@ -7,11 +7,13 @@ import tmdb from './objects/tmdb'
|
|||
import { Sidebar } from './objects/sidebar'
|
||||
import { Movie } from './objects/movie-wall'
|
||||
import CrossfadeImage from 'react-crossfade-image'
|
||||
import { WhereToWatch } from './objects/whereToWatch'
|
||||
|
||||
export type Config = {
|
||||
language: string,
|
||||
region: string,
|
||||
page: number,
|
||||
locale: string
|
||||
}
|
||||
class MovieClass implements Movie {
|
||||
id = null
|
||||
|
@ -26,13 +28,14 @@ function App() {
|
|||
const [config, setConfig] = useState<Config>({
|
||||
language: "es",
|
||||
region: "spain",
|
||||
page: 1
|
||||
page: 1,
|
||||
locale: "ES"
|
||||
})
|
||||
const [movies, setMovies] = useState([new MovieClass()])
|
||||
const [backdrop, setBackdrop] = useState("")
|
||||
const [chosenMovie, setChosenMovie] = useState(new MovieClass())
|
||||
const [similarMoviesAvailable, setSimilarMoviesAvailable] = useState(true)
|
||||
|
||||
const [watchProviders, setWatchProviders] = useState({})
|
||||
useEffect(() => { tmdb.getPopular(config, setMovies) }, [])
|
||||
useEffect(() => {
|
||||
const bgString = chosenMovie.backdrop_path ?
|
||||
|
@ -40,9 +43,12 @@ function App() {
|
|||
: tmdb.makeBgImgUrl(movies[0]?.backdrop_path ?? "")
|
||||
setBackdrop(bgString)
|
||||
}, [movies])
|
||||
|
||||
useEffect(() => {
|
||||
tmdb.getWhereToWatch(chosenMovie, setWatchProviders, config)
|
||||
}, [chosenMovie])
|
||||
const crossfadeImageStyles = {
|
||||
width: "100%",
|
||||
width: "2560px",
|
||||
minHeight: "100%",
|
||||
aspectRatio: "16/9"
|
||||
}
|
||||
return (
|
||||
|
@ -51,7 +57,7 @@ function App() {
|
|||
<CrossfadeImage src={backdrop} style={crossfadeImageStyles} />
|
||||
</div>
|
||||
<main >
|
||||
<Sidebar movie={chosenMovie} similarMoviesAvailable={similarMoviesAvailable} />
|
||||
<Sidebar movie={chosenMovie} similarMoviesAvailable={similarMoviesAvailable} watchProviders={watchProviders} />
|
||||
<div id="movie-wall-container">
|
||||
<MovieWall movies={movies}
|
||||
setMovies={setMovies}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import React from "react";
|
||||
import { Movie } from "./movie-wall";
|
||||
import tmdb from "./tmdb";
|
||||
import { WhereToWatch } from "./whereToWatch";
|
||||
export interface SidebarProps extends React.ComponentPropsWithRef<"div"> {
|
||||
movie: Movie;
|
||||
similarMoviesAvailable: boolean;
|
||||
watchProviders: {};
|
||||
}
|
||||
export function Sidebar({ movie, similarMoviesAvailable }: SidebarProps) {
|
||||
export function Sidebar({ movie, similarMoviesAvailable, watchProviders }: SidebarProps) {
|
||||
return <div id="sidebar">
|
||||
<h1>{movie?.title ?? "loading"}</h1>
|
||||
<figure>
|
||||
|
@ -20,6 +22,7 @@ export function Sidebar({ movie, similarMoviesAvailable }: SidebarProps) {
|
|||
: movie.overview === "" ? "Resumen no disponible."
|
||||
: movie.overview}
|
||||
</p>
|
||||
<WhereToWatch watchProviders={watchProviders} />
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ export default {
|
|||
setSimilarMoviesAvailable(true)
|
||||
} else {
|
||||
setSimilarMoviesAvailable(false)
|
||||
console.log("SIMILAR NOT AVAILABLE")
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
|
@ -64,24 +63,15 @@ export default {
|
|||
}
|
||||
|
||||
},
|
||||
/**
|
||||
*Calls TMDB/images, and sets the backdrop state accordingly
|
||||
*
|
||||
*/
|
||||
getBackdrop: async function(movie: Movie, setBackdrop: Function) {
|
||||
let res = await tmdb.get(movie.id + '/images')
|
||||
console.log(res)
|
||||
if (res.status === 200) {
|
||||
const file_path = res.data.backdrops[0].file_path
|
||||
console.log("file_path:" + file_path)
|
||||
const imgUrl = this.makeBgImgUrl(file_path)
|
||||
console.log("imgUrl: " + imgUrl)
|
||||
setBackdrop(imgUrl)
|
||||
getWhereToWatch: async function(movie: Movie, setWatchProviders: Function, config: Config) {
|
||||
if (movie?.id) {
|
||||
let res = await tmdb.get(movie.id + "/watch/providers")
|
||||
if (res.status == 200) {
|
||||
setWatchProviders(res.data.results[config.locale])
|
||||
} else {
|
||||
throw Error("API call failed! Response: " + JSON.stringify(res))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
makeBgImgUrl:
|
||||
/**
|
||||
|
@ -103,5 +93,8 @@ export default {
|
|||
*/
|
||||
function(movie: Movie) {
|
||||
return "https://www.themoviedb.org/movie/" + movie.id
|
||||
},
|
||||
makeLogoPath: function(str: string) {
|
||||
return "https://image.tmdb.org/t/p/original/" + str
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
import React from "react"
|
||||
import tmdb from "./tmdb"
|
||||
|
||||
interface WhereToWatchProps extends React.ComponentPropsWithRef<"div"> {
|
||||
watchProviders: {
|
||||
flatrate: Array<{}>;
|
||||
rent: Array<{}>;
|
||||
buy: Array<{}>;
|
||||
link: string;
|
||||
|
||||
};
|
||||
}
|
||||
const sampleData = {
|
||||
link: "https://www.themoviedb.org/movie/872585-oppenheimer/watch?locale=ES",
|
||||
rent: [{
|
||||
logo_path: "/7K6rVbpWXB6ByDI0PRzGGRXRBSY.jpg",
|
||||
provider_id: 149,
|
||||
provider_name: "Movistar Plus",
|
||||
display_priority: 12
|
||||
}],
|
||||
buy: [{
|
||||
logo_path: "/9ghgSC0MA082EL6HLCW3GalykFD.jpg",
|
||||
provider_id: 2,
|
||||
provider_name: "Apple TV",
|
||||
display_priority: 4
|
||||
},
|
||||
{
|
||||
logo_path: "/bZvc9dXrXNly7cA0V4D9pR8yJwm.jpg",
|
||||
provider_id: 35,
|
||||
provider_name: "Rakuten TV",
|
||||
display_priority: 13
|
||||
},
|
||||
{
|
||||
logo_path: "/8z7rC8uIDaTM91X0ZfkRf04ydj2.jpg",
|
||||
provider_id: 3,
|
||||
provider_name: "Google Play Movies",
|
||||
display_priority: 15
|
||||
},
|
||||
{
|
||||
logo_path: "/5vfrJQgNe9UnHVgVNAwZTy0Jo9o.jpg",
|
||||
provider_id: 68,
|
||||
provider_name: "Microsoft Store",
|
||||
display_priority: 16
|
||||
},
|
||||
{
|
||||
logo_path: "/seGSXajazLMCKGB5hnRCidtjay1.jpg",
|
||||
provider_id: 10,
|
||||
provider_name: "Amazon Video",
|
||||
display_priority: 36
|
||||
}],
|
||||
flatrate: [{
|
||||
logo_path: "/gQbqEYd0C9uprYxEUqTM589qn8g.jpg",
|
||||
provider_id: 1773,
|
||||
provider_name: "SkyShowtime",
|
||||
display_priority: 9
|
||||
}]
|
||||
}
|
||||
interface ProviderIconsProps extends React.ComponentPropsWithRef<"div"> {
|
||||
providerList: Array<{}>;
|
||||
link: string;
|
||||
}
|
||||
function ProviderIcons({ providerList, link }: ProviderIconsProps) {
|
||||
const list = providerList.map((e: any, i: number) => {
|
||||
return <a href={link}><img src={tmdb.makeLogoPath(e.logo_path)} className="watch-logo" key={e.provider_id + "_" + i} /></a>
|
||||
})
|
||||
return <div className="watch-logos-container">
|
||||
{list}
|
||||
</div>
|
||||
}
|
||||
|
||||
export function WhereToWatch({ watchProviders }: WhereToWatchProps) {
|
||||
if (!watchProviders?.link) {
|
||||
console.group()
|
||||
console.log("Watch providers (WhereToWatch)")
|
||||
console.log(watchProviders)
|
||||
console.groupEnd()
|
||||
return <div id="no-watch"></div>
|
||||
}
|
||||
return <><div id="watch-providers">
|
||||
{watchProviders?.flatrate?.length > 0 ? <div><h1>Streaming:</h1><ProviderIcons providerList={watchProviders.flatrate} link={watchProviders.link} /></div> : ""}
|
||||
{watchProviders?.rent?.length > 0 ? <div><h1>Alquiler:</h1><ProviderIcons providerList={watchProviders.rent} link={watchProviders.link} /></div> : ""}
|
||||
{watchProviders?.buy?.length > 0 ? <div><h1>Comprar:</h1><ProviderIcons providerList={watchProviders.buy} link={watchProviders.link} /></div> : ""}
|
||||
</div>
|
||||
<p>Powered by Just Watch.</p>
|
||||
</>
|
||||
}
|
Loading…
Reference in New Issue