From 59b584e55dbf95df147f5f13cc8cd0fa1268c0fc Mon Sep 17 00:00:00 2001 From: Lucas Delanier Date: Sun, 12 Feb 2023 20:44:08 +0100 Subject: [PATCH] test redux on homepage --- App.tsx | 4 ++ constants/config.ts | 4 ++ model/Movie.tsx | 21 ++++++ redux/actions/actionGetTrendingID.tsx | 39 ++++++++++++ redux/constants.tsx | 4 ++ redux/reducers/appReducer.tsx | 22 +++++++ redux/store.tsx | 14 ++++ screens/FavoriteScreen.tsx | 2 +- screens/HomeScreen.tsx | 49 +++++++++++--- screens/WatchLaterScreen.tsx | 92 ++++++++++++++++++--------- 10 files changed, 211 insertions(+), 40 deletions(-) create mode 100644 constants/config.ts create mode 100644 model/Movie.tsx create mode 100644 redux/actions/actionGetTrendingID.tsx create mode 100644 redux/constants.tsx create mode 100644 redux/reducers/appReducer.tsx create mode 100644 redux/store.tsx diff --git a/App.tsx b/App.tsx index 9b54a76..84d9eba 100644 --- a/App.tsx +++ b/App.tsx @@ -4,6 +4,8 @@ import useCachedResources from './hooks/useCachedResources'; import useColorScheme from './hooks/useColorScheme'; import Navigation from './navigation'; import {View} from "react-native"; +import store from "./redux/store"; +import {Provider} from "react-redux"; export default function App() { const isLoadingComplete = useCachedResources(); @@ -13,10 +15,12 @@ export default function App() { return null; } else { return ( + + ); } } diff --git a/constants/config.ts b/constants/config.ts new file mode 100644 index 0000000..2f64e41 --- /dev/null +++ b/constants/config.ts @@ -0,0 +1,4 @@ +export default { + api_key: "a133422b5b1f22428e8074470d321865", + base_url: "https://api.themoviedb.org/3/" +} \ No newline at end of file diff --git a/model/Movie.tsx b/model/Movie.tsx new file mode 100644 index 0000000..3a55b61 --- /dev/null +++ b/model/Movie.tsx @@ -0,0 +1,21 @@ +class Movie { + original_title: string + + poster_path: string + runtime: number + vote_average : number + release_date: string + + constructor(original_title: string, poster_path: string,runtime: number, vote_average: number, release_date : string) { + this.original_title = original_title; + this.poster_path = 'https://image.tmdb.org/t/p/w500'+poster_path; + this.runtime = runtime; + this.vote_average = vote_average; + this.release_date = release_date; + } + + + +} + +export default Movie; \ No newline at end of file diff --git a/redux/actions/actionGetTrendingID.tsx b/redux/actions/actionGetTrendingID.tsx new file mode 100644 index 0000000..fc3cc71 --- /dev/null +++ b/redux/actions/actionGetTrendingID.tsx @@ -0,0 +1,39 @@ +import {FETCH_TRENDING_MOVIE, FETCH_TRENDING_ID, POP_FIRST_TRENDING} from '../constants'; +import config from "../../constants/config"; +import Movie from "../../model/Movie"; + +export const setTrendingID = (TrendingIDList: Movie[]) => { + return { + type: FETCH_TRENDING_ID, + payload: TrendingIDList, + }; +} + +export const setinfoMovie = (TrendingMovieList: Movie[]) => { + return { + type: FETCH_TRENDING_MOVIE, + payload: TrendingMovieList, + }; +} +export const getTrendingID = () => { + // @ts-ignore + return async dispatch => { + try { + const IDPromise = await fetch(config.base_url + "trending/movie/day?api_key="+config.api_key); + const IDListJson = await IDPromise.json(); + // @ts-ignore + const idList: String[] = IDListJson.results.map(elt => elt["id"]); + const MovieList: Movie[] = []; + idList.map(async elt => { + const infoPromise = await fetch(config.base_url + "movie/"+elt+"?api_key=" + config.api_key); + const infoJson = await infoPromise.json(); + //console.log('infos---------', infoJson); + MovieList.push(new Movie(infoJson["original_title"], infoJson["poster_path"],infoJson["runtime"], infoJson["vote_average"], infoJson["release_date"])) + dispatch(setinfoMovie(MovieList)); + }); + + } catch (error) { + console.log('Error---------', error); + } + } +} \ No newline at end of file diff --git a/redux/constants.tsx b/redux/constants.tsx new file mode 100644 index 0000000..883050e --- /dev/null +++ b/redux/constants.tsx @@ -0,0 +1,4 @@ + +export const FETCH_TRENDING_ID : string = "FETCH_TRENDING_ID"; +export const FETCH_TRENDING_MOVIE: string = "FETCH_TRENDING_MOVIE"; +export const POP_FIRST_TRENDING: string = "POP_FIRST_TRENDING"; \ No newline at end of file diff --git a/redux/reducers/appReducer.tsx b/redux/reducers/appReducer.tsx new file mode 100644 index 0000000..553d6a5 --- /dev/null +++ b/redux/reducers/appReducer.tsx @@ -0,0 +1,22 @@ +import {POP_FIRST_TRENDING, FETCH_TRENDING_MOVIE,FETCH_TRENDING_ID} from "../constants"; + +const initialState = { + trendingIDs: [], + trendingMovies: [], +} + +// @ts-ignore +export default appReducer = (state = initialState, action) => { + switch (action.type) { + case FETCH_TRENDING_ID: + // @ts-ignore + return {...state, trendingIDs: action.payload}; + case FETCH_TRENDING_MOVIE: + return {...state, trendingMovies: action.payload}; + case POP_FIRST_TRENDING: + return {...state, trendingMovies: state.trendingMovies.pop()}; + default: + return state; + } + +} \ No newline at end of file diff --git a/redux/store.tsx b/redux/store.tsx new file mode 100644 index 0000000..09fd4f2 --- /dev/null +++ b/redux/store.tsx @@ -0,0 +1,14 @@ +import { configureStore } from '@reduxjs/toolkit' +import appReducer from "./reducers/appReducer"; + +const reducer = { + appReducer: appReducer, +} + + +const store= configureStore({ + // @ts-ignore + reducer, +},); + +export default store; \ No newline at end of file diff --git a/screens/FavoriteScreen.tsx b/screens/FavoriteScreen.tsx index 93d40ce..7911410 100644 --- a/screens/FavoriteScreen.tsx +++ b/screens/FavoriteScreen.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import {BadgeFilm} from "./HomeScreen"; import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome"; import { faHeart} from "@fortawesome/free-solid-svg-icons"; -import {RootTabScreenProps} from "../types.js"; +import {RootTabScreenProps} from "../types"; export default function FavoriteScreen({ navigation }: RootTabScreenProps<'Favorite'>) { diff --git a/screens/HomeScreen.tsx b/screens/HomeScreen.tsx index 4ad3320..24d29a0 100644 --- a/screens/HomeScreen.tsx +++ b/screens/HomeScreen.tsx @@ -1,10 +1,13 @@ import * as React from 'react'; import {Button,TouchableOpacity,ScrollView,View, Text, StyleSheet, Image, ImageBackground, SafeAreaView} from 'react-native'; -import {RootStackScreenProps} from "../types.js"; +import {RootStackScreenProps} from "../types"; import Rive from 'rive-react-native'; -import {useRef} from "react"; +import {useEffect, useRef} from "react"; import {RiveViewManager} from "rive-react-native/lib/typescript/Rive.js"; import {useSafeAreaInsets} from "react-native-safe-area-context"; +import {getTrendingID, } from "../redux/actions/actionGetTrendingID"; +import {useDispatch, useSelector} from 'react-redux'; +import Movie from "../model/Movie.js"; export default function App({ navigation }: RootStackScreenProps<'Home'>) { const riveRef = useRef(); @@ -54,9 +57,27 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) { }, }); + + // @ts-ignore + const trendingMovies = useSelector(state => state.appReducer.trendingMovies); + + const dispatch = useDispatch(); + + let firstelement: Movie = trendingMovies[0]; + + useEffect(() => { + const loadTrendingID = async () => { + // @ts-ignore + await dispatch(getTrendingID()); + }; + loadTrendingID(); + firstelement = trendingMovies[0]; + }, [dispatch]); + + // @ts-ignore + const onPress = () => this.setState({trendingMovies: trendingMovies.shift()}) ; return ( - ) { opacity: 0.28 }} source={{ - uri: 'https://fr.web.img4.acsta.net/pictures/21/11/16/10/01/4860598.jpg', + uri: firstelement.poster_path, }} > @@ -104,12 +125,12 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) { - SPIDER-MAN No Way Home + {firstelement.original_title} - Jean-Marc généreux + {firstelement.release_date} - + @@ -166,8 +187,16 @@ type BadgeFilmProps = { export function BadgeFilm(props: BadgeFilmProps) { return ( - - {props.name} + + {props.name} ); diff --git a/screens/WatchLaterScreen.tsx b/screens/WatchLaterScreen.tsx index 622fac7..20a6ee6 100644 --- a/screens/WatchLaterScreen.tsx +++ b/screens/WatchLaterScreen.tsx @@ -4,11 +4,16 @@ import {BadgeFilm} from "./HomeScreen"; import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome"; import { faClock} from "@fortawesome/free-solid-svg-icons"; import LinearGradient from 'react-native-linear-gradient'; -import {RootTabScreenProps} from "../types.js"; +import {RootTabScreenProps} from "../types"; import {useSafeAreaInsets} from "react-native-safe-area-context"; +import {useDispatch,useSelector} from 'react-redux'; +import {useEffect} from 'react'; +import {getTrendingID} from "../redux/actions/actionGetTrendingID"; +import Movie from "../model/Movie"; export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'WatchLater'>) { const insets = useSafeAreaInsets(); + const styles = StyleSheet.create({ container: { flex: 1, @@ -35,6 +40,19 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat }, }); + + // @ts-ignore + const trendingMovies = useSelector(state => state.appReducer.trendingMovies); + + const dispatch = useDispatch(); + + useEffect(() => { + const loadTrendingID = async () => { + // @ts-ignore + await dispatch(getTrendingID()); + }; + loadTrendingID(); + }, [dispatch]); return ( @@ -49,19 +67,9 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat } + data={trendingMovies} + keyExtractor={item => item.original_title} + renderItem={({item}) => } /> ); @@ -70,7 +78,7 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat type ListWidgetProps = { - name : String + movie : Movie } @@ -86,22 +94,48 @@ export function ListWidget(props: ListWidgetProps) { }, }); + + function formatTime(time: number) { + console.log(time); + const hours = Math.floor(time / 60); + const minutes = time % 60; + return `${hours}h ${minutes < 10 ? `0${minutes}` : minutes}m`; + } + return ( - - - - {props.name} - {props.name} - - - - + + + + {props.movie.original_title} + {formatTime(props.movie.runtime)} + + + + );