import * as React from 'react'; import {TouchableOpacity, ScrollView, View, Text, StyleSheet, Image, SafeAreaView, FlatList} from 'react-native'; import {RootStackScreenProps} from "../types"; import {useSafeAreaInsets} from "react-native-safe-area-context"; import Movie from "../model/Movie"; import {LinearGradient} from 'expo-linear-gradient'; import {useEffect, useState} from "react"; import config from "../constants/config"; import YoutubeIframe from "react-native-youtube-iframe"; import Ionicons from "@expo/vector-icons/Ionicons"; import MinimalMovie from "../model/MinimalMovie"; import Review from "../model/review"; import Stars from "../components/StarsComponent"; import minimalMovie from "../model/MinimalMovie"; export default function InfoScreen({navigation, route}: RootStackScreenProps<'Info'>) { // @ts-ignore const item: Movie = route.params.item const insets = useSafeAreaInsets(); const [trailerPath, setTrailerPath] = useState(""); const [similarMovies, setSimilarMovies] = useState([]); const [review, setReview] = useState([]); const [credit, setCredit] = useState(); const [paddingTopBackground, setPaddingTopBackground] = useState(0); const [opacityBackground, setOpacityBackground] = useState(0.7); const [scaleBackground, setScaleBackground] = useState(1); function formatTime(time: number) { const hours = Math.floor(time / 60); const minutes = time % 60; return `${hours}h ${minutes < 10 ? `0${minutes}` : minutes}m`; } const handleScroll = (event: any) => { const {y} = event.nativeEvent.contentOffset; let padTop = y / -5; if (padTop <= 0) setPaddingTopBackground(y / -5); setOpacityBackground(0.5 - y / 500); let scale = 1 - y / -1000 if (scale >= 1) setScaleBackground(scale); }; type creditItem = [string, string, number]; type creditProps = { data: creditItem[]; }; function CreditList({data}: creditProps) { const renderItem = ({item}: { item: creditItem }) => ( {item[2].toFixed(1).toString()} {item[0]} ); return ( item[0]} /> ); } type SimilarMovieProps = { movie: minimalMovie; }; function SimilarMovie(props: SimilarMovieProps) { return ( {props.movie.original_title} ); } type ReviewProps = { review: Review; }; function ReviewComponent(props: ReviewProps) { return ( {props.review.pseudo} {props.review.date} {props.review.message} ); } type InfoBadgeProps = { texte: string } function InfoBadge(props: InfoBadgeProps) { return ( {props.texte} ); } const styles = StyleSheet.create({ background1: { height: '100%', width: '100%', paddingTop: insets.top, }, body: { backgroundColor: "#0E0E0E" }, backgroundSection: { height: "100%", width: "100%", position: "absolute" }, back_drop: { height: "45%", top: paddingTopBackground, width: '100%', opacity: opacityBackground, position: "absolute", transform: [{scale: scaleBackground}], }, gradientFade: { height: "30%", top: "25%" }, backButton: { position: "absolute", top: 10, left: 5 }, list: { height: "100%" }, section1: { paddingHorizontal: 35 }, title: { color: "white", fontSize: 43, fontWeight: "bold", paddingBottom: 10, paddingTop: "45%" }, characteristics: { flexDirection: "row", width: "100%", justifyContent: "flex-start" }, stars: { flexDirection: "row", width: "100%", justifyContent: "flex-start", alignItems: "center", paddingBottom: 30 }, starsLabel: { color: "#FFC42D", fontWeight: "bold", paddingLeft: 10, fontSize: 16 }, player: { borderRadius: 10, overflow: "hidden" }, resume: { color: "#B3B3B3", paddingTop: 30, fontSize: 17 }, creditSection: { paddingTop: 30 }, creditTitle: { color: "#2998FD", paddingBottom: 20, paddingLeft: 35, fontSize: 17, fontWeight: "600" }, similarSection: { paddingTop: 30 }, similarTitle: { color: "#2998FD", paddingLeft: 35, fontSize: 17, fontWeight: "600", paddingBottom: 20 }, similarContainer: { width: 90, marginHorizontal: 7 }, similarPoster: { height: 130, width: 90, borderRadius: 8 }, similarTitleFilm: { color: "#DADADA", paddingTop: 5, fontWeight: "300" }, reviewSection: { paddingTop: 30 }, reviewTitle: { color: "#2998FD", paddingLeft: 35, fontSize: 17, fontWeight: "600", paddingBottom: 10 }, reviewContainer: { marginHorizontal: 7, width: 300, padding: 20, backgroundColor: "#09090F", marginVertical: 10, borderRadius: 14, borderWidth: 0.8, borderColor: "rgba(223,223,223,0.14)" }, reviewInfo: { flexDirection: "row", paddingBottom: 20 }, imageProfile: { height: 50, width: 50, borderRadius: 100 }, infoContainer: { paddingLeft: 10, flexDirection: "row", justifyContent: "space-between", width: "80%", alignItems: "center" }, pseudo: { color: "white", paddingTop: 5, fontWeight: "700", fontSize: 16 }, date: { color: "grey", paddingTop: 5, fontWeight: "500", fontSize: 14 }, message: { color: "#B3B3B3", paddingTop: 5, fontWeight: "400" }, creditContainer: { width: 90, marginHorizontal: 7, alignItems: "center" }, bubble: { justifyContent: "center" }, photo: { height: 90, width: 90, borderRadius: 200, borderWidth: 3, borderColor: "rgba(255,255,255,0.8)" }, popularityDot: { backgroundColor: "white", borderRadius: 20, padding: 2, paddingHorizontal: 5, justifyContent: "center", alignItems: "center", position: "absolute", bottom: 0, right: 0, flexDirection: "row" }, popularityLabel: { color: "black", fontWeight: "500", paddingRight: 4 }, creditName: { color: "#DADADA", paddingTop: 5, fontWeight: "300" } }); const getTriller = async () => { const trailerResponse = (await fetch(config.base_url + "movie/" + item.id + "/videos?api_key=" + config.api_key + "&language=fr-FR")); const trailerJson = await trailerResponse.json(); //console.log("trailer", trailerJson) // @ts-ignore const trailer_key = trailerJson.results.slice(0, 1).map((elt) => { if (elt["type"] === "Trailer" && elt["site"] === "YouTube") { return elt["key"]; } }); //console.log("key", trailer_key) setTrailerPath(trailer_key); } const getCredits = async () => { const creditResponse = (await fetch(config.base_url + "movie/" + item.id + "/credits?api_key=" + config.api_key + "&language=fr-FR")); const creditJson = await creditResponse.json(); //console.log("credittttttt", creditJson) // @ts-ignore let creditList = creditJson.cast.map((elt) => { if (elt["popularity"]) return [elt["name"], 'https://image.tmdb.org/t/p/w185' + elt["profile_path"], elt["popularity"]] }); creditList = creditList.slice(0, 5).sort((a: [fullname: string, profile_path: string, popularity: number], b: [fullname: string, profil_path: string, popularity: number]) => b[2] - a[2]); //console.log("credit", creditList); setCredit(creditList); } const getSimilarMovies = async () => { const SimilarMoviesResponse = (await fetch(config.base_url + "movie/" + item.id + "/recommendations?api_key=" + config.api_key + "&language=fr-FR")); const SimilarMoviesJson = await SimilarMoviesResponse.json(); // @ts-ignore const SimilarMoviesList = SimilarMoviesJson.results.slice(0, 10).map((elt) => { return new MinimalMovie(elt["original_title"], elt["poster_path"]) }); //console.log("similar", SimilarMoviesList); setSimilarMovies(SimilarMoviesList); } const getReview = async () => { const ReviewResponse = (await fetch(config.base_url + "movie/" + item.id + "/reviews?api_key=" + config.api_key + "&language=us-EN&page=1")); const ReviewJson = await ReviewResponse.json(); // @ts-ignore let ReviewList = ReviewJson.results.slice(0, 5).map((elt) => { // @ts-ignore const newreview = new Review(elt["content"], elt["author_details"].avatar_path, elt["created_at"], elt["author"]) return newreview }); ReviewList = ReviewList.filter((review: Review, index: number, array: Review[]) => { return array.findIndex((item: Review) => item.pseudo === review.pseudo) === index; }); //console.log("review", ReviewJson.results); setReview(ReviewList); } useEffect(() => { getTriller(); getSimilarMovies(); getCredits(); getReview(); }, []); return ( navigation.goBack()} style={{zIndex: 100}}> {item.original_title} {item.vote_average.toFixed(1)} {trailerPath !== "" && ()} {item.overview} {credit !== undefined && ( Crédits )} {similarMovies.length !== 0 && ( Recommendations item.original_title} renderItem={({item}) => } /> )} {review.length !== 0 && ( Commentaires item.pseudo} renderItem={({item}) => } /> )} ) }