test redux on homepage

redux_test_david
Lucas Delanier 2 years ago
parent 1a99571791
commit 59b584e55d

@ -4,6 +4,8 @@ import useCachedResources from './hooks/useCachedResources';
import useColorScheme from './hooks/useColorScheme'; import useColorScheme from './hooks/useColorScheme';
import Navigation from './navigation'; import Navigation from './navigation';
import {View} from "react-native"; import {View} from "react-native";
import store from "./redux/store";
import {Provider} from "react-redux";
export default function App() { export default function App() {
const isLoadingComplete = useCachedResources(); const isLoadingComplete = useCachedResources();
@ -13,10 +15,12 @@ export default function App() {
return null; return null;
} else { } else {
return ( return (
<Provider store={store}>
<SafeAreaProvider> <SafeAreaProvider>
<Navigation colorScheme={colorScheme} /> <Navigation colorScheme={colorScheme} />
<StatusBar /> <StatusBar />
</SafeAreaProvider> </SafeAreaProvider>
</Provider>
); );
} }
} }

@ -0,0 +1,4 @@
export default {
api_key: "a133422b5b1f22428e8074470d321865",
base_url: "https://api.themoviedb.org/3/"
}

@ -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;

@ -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);
}
}
}

@ -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";

@ -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;
}
}

@ -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;

@ -3,7 +3,7 @@ import * as React from "react";
import {BadgeFilm} from "./HomeScreen"; import {BadgeFilm} from "./HomeScreen";
import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome"; import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome";
import { faHeart} from "@fortawesome/free-solid-svg-icons"; import { faHeart} from "@fortawesome/free-solid-svg-icons";
import {RootTabScreenProps} from "../types.js"; import {RootTabScreenProps} from "../types";
export default function FavoriteScreen({ navigation }: RootTabScreenProps<'Favorite'>) { export default function FavoriteScreen({ navigation }: RootTabScreenProps<'Favorite'>) {

@ -1,10 +1,13 @@
import * as React from 'react'; import * as React from 'react';
import {Button,TouchableOpacity,ScrollView,View, Text, StyleSheet, Image, ImageBackground, SafeAreaView} from 'react-native'; 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 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 {RiveViewManager} from "rive-react-native/lib/typescript/Rive.js";
import {useSafeAreaInsets} from "react-native-safe-area-context"; 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'>) { export default function App({ navigation }: RootStackScreenProps<'Home'>) {
const riveRef = useRef(); 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 ( return (
<SafeAreaView style={styles.background}> <SafeAreaView style={styles.background}>
<ImageBackground blurRadius={20} <ImageBackground blurRadius={20}
style={{ style={{
position: 'absolute', position: 'absolute',
@ -67,14 +88,14 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) {
opacity: 0.28 opacity: 0.28
}} }}
source={{ source={{
uri: 'https://fr.web.img4.acsta.net/pictures/21/11/16/10/01/4860598.jpg', uri: firstelement.poster_path,
}} }}
></ImageBackground> ></ImageBackground>
<View style={styles.image}> <View style={styles.image}>
<Image <Image
style={styles.filmCard} style={styles.filmCard}
source={{ source={{
uri: 'https://fr.web.img4.acsta.net/pictures/21/11/16/10/01/4860598.jpg', uri: firstelement.poster_path,
}} }}
/> />
</View> </View>
@ -104,12 +125,12 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) {
<BadgeFilm name={"9:11"}></BadgeFilm> <BadgeFilm name={"9:11"}></BadgeFilm>
</View> </View>
<View> <View>
<Text numberOfLines={1} style={{color: "white", fontSize: 28, fontWeight: "bold", paddingTop: 5}}>SPIDER-MAN No Way Home</Text> <Text numberOfLines={1} style={{color: "white", fontSize: 28, fontWeight: "bold", paddingTop: 5}}>{firstelement.original_title}</Text>
</View> </View>
<Text style={{color: "grey", fontSize: 20, fontWeight: "bold"}}>Jean-Marc généreux</Text> <Text style={{color: "grey", fontSize: 20, fontWeight: "bold"}}>{firstelement.release_date}</Text>
</View> </View>
<View style={{ flexDirection: 'row' ,alignItems: 'center', justifyContent: "space-evenly", paddingHorizontal: 30, height: '15%', width:'100%'}}> <View style={{ flexDirection: 'row' ,alignItems: 'center', justifyContent: "space-evenly", paddingHorizontal: 30, height: '15%', width:'100%'}}>
<TouchableOpacity> <TouchableOpacity onPress={onPress}>
<Image <Image
source={require('../assets/images/WatchLater.png')} style={{ resizeMode:"stretch", height:'65%', aspectRatio: 1,}} source={require('../assets/images/WatchLater.png')} style={{ resizeMode:"stretch", height:'65%', aspectRatio: 1,}}
/> />
@ -166,8 +187,16 @@ type BadgeFilmProps = {
export function BadgeFilm(props: BadgeFilmProps) { export function BadgeFilm(props: BadgeFilmProps) {
return ( return (
<View style={{paddingHorizontal: 15, marginHorizontal: 5,height: 30, backgroundColor: '#8906B8', borderRadius: 15, justifyContent: "center"}} > <View style={{
<Text style={{color: "white", fontSize: 12, fontWeight:"bold"}}>{props.name}</Text> paddingHorizontal: 15,
marginHorizontal: 5,
height: 30,
backgroundColor: '#8906B8',
borderRadius: 15,
justifyContent: "center",
alignSelf: "flex-start"
}}>
<Text style={{color: "white", fontSize: 12, fontWeight: "bold"}}>{props.name}</Text>
</View> </View>
); );

@ -4,11 +4,16 @@ import {BadgeFilm} from "./HomeScreen";
import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome"; import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome";
import { faClock} from "@fortawesome/free-solid-svg-icons"; import { faClock} from "@fortawesome/free-solid-svg-icons";
import LinearGradient from 'react-native-linear-gradient'; 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 {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'>) { export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'WatchLater'>) {
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, 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 ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<View style={{height: 50, justifyContent: "flex-start",flexDirection: 'row', paddingHorizontal:20, marginBottom: 15,marginVertical:5, alignItems:"flex-end"}} > <View style={{height: 50, justifyContent: "flex-start",flexDirection: 'row', paddingHorizontal:20, marginBottom: 15,marginVertical:5, alignItems:"flex-end"}} >
@ -49,19 +67,9 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat
<TextInput style={{width:'100%', height:40, marginHorizontal:20}} ></TextInput> <TextInput style={{width:'100%', height:40, marginHorizontal:20}} ></TextInput>
</View> </View>
<FlatList <FlatList
data={[ data={trendingMovies}
{key: 'Devin'}, keyExtractor={item => item.original_title}
{key: 'Dan'}, renderItem={({item}) => <ListWidget movie={item} ></ListWidget>}
{key: 'Dominic'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem={({item}) => <ListWidget name={item.key} ></ListWidget>}
/> />
</SafeAreaView> </SafeAreaView>
); );
@ -70,7 +78,7 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat
type ListWidgetProps = { 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 ( return (
<View style={{height: 100, borderRadius: 20, justifyContent: "flex-start", flexDirection: 'row', paddingHorizontal:20, marginVertical:5}} > <View style={{
<Image height: 100,
style={styles.filmCard} borderRadius: 20,
source={{ justifyContent: "flex-start",
uri: 'https://fr.web.img4.acsta.net/pictures/21/11/16/10/01/4860598.jpg', flexDirection: 'row',
}} paddingHorizontal: 20,
/> marginVertical: 5
<View style={{height: 100, borderRadius: 20, justifyContent: "flex-start", flexDirection: 'column', paddingLeft:10}} > }}>
<Text style={{color: "white", fontWeight:"bold", fontSize:25}}>{props.name}</Text> <Image
<Text style={{color: "grey", fontWeight:"bold", fontSize:17}}>{props.name}</Text> style={styles.filmCard}
<View style={{marginVertical:10}}> source={{
<BadgeFilm name={"Science-Ficton"}/> uri: props.movie.poster_path,
</View> }}
</View> />
<View style={{
height: 100,
borderRadius: 20,
justifyContent: "flex-start",
flexDirection: 'column',
paddingLeft: 10
}}>
<Text numberOfLines={1} style={{
color: "white",
fontWeight: "bold",
fontSize: 25,
paddingRight: 50
}}>{props.movie.original_title}</Text>
<Text style={{color: "grey", fontWeight: "bold", fontSize: 17}}>{formatTime(props.movie.runtime)}</Text>
<View style={{marginVertical: 10}}>
<BadgeFilm name={"Science-Ficton"}/>
</View> </View>
</View>
</View>
); );

Loading…
Cancel
Save