Compare commits

...

5 Commits

Author SHA1 Message Date
Lucas Delanier 8660bfb01d redux and watch late screen
2 years ago
Lucas Delanier 4ef93425cc reset api
2 years ago
Lucas Delanier ebc12c478e comprend rien du tout
2 years ago
Lucas Delanier 8a5b796406 try api
2 years ago
Lucas Delanier c4cb072d9b try api
2 years ago

@ -3,20 +3,27 @@ import { SafeAreaProvider } from 'react-native-safe-area-context';
import useCachedResources from './hooks/useCachedResources'; 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, Text, ScrollView, FlatList} from "react-native";
import {useEffect, useState} from "react";
import * as React from "react";
import {Provider} from "react-redux";
import store from "./redux/store"
export default function App() { export default function App() {
const isLoadingComplete = useCachedResources(); const isLoadingComplete = useCachedResources();
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
if (!isLoadingComplete) { if (!isLoadingComplete) {
return null; return null;
} else { } else {
return ( return (
<SafeAreaProvider> <Provider store={store}>
<Navigation colorScheme={colorScheme} /> <SafeAreaProvider>
<StatusBar /> <Navigation colorScheme={colorScheme} />
</SafeAreaProvider> <StatusBar />
</SafeAreaProvider>
</Provider>
); );
} }
} }

@ -0,0 +1,9 @@
API_URL = https://api.themoviedb.org/3/movie/550?api_key=a133422b5b1f22428e8074470d321865
IMAGE = https://image.tmdb.org/t/p/w500/kqjL17yufvn9OVLyXYpvtyrFfak.jpg
JETON = eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhMTMzNDIyYjViMWYyMjQyOGU4MDc0NDcwZDMyMTg2NSIsInN1YiI6IjYzZGE1MDA5YTZjMTA0MDA4NTg3YTc3YiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.EfOvULIxDJ2hrltaGwdRUkAE1wd1HCHtkCP835z7PaY
<SafeAreaProvider>
<Navigation colorScheme={colorScheme} />
<StatusBar />
</SafeAreaProvider>

@ -0,0 +1,74 @@
import {Image, StyleSheet, Text, View} from "react-native";
import {BadgeFilm} from "../screens/HomeScreen";
import * as React from "react";
type ListWidgetProps = {
imageURL: string
name: String
runtime: number
director: string
}
const styles = StyleSheet.create({
filmCard: {
width: 70,
height: 100,
borderRadius: 8,
},
});
export function ListWidget(props: ListWidgetProps) {
function formatTime(time: number) {
const hours = Math.floor(time / 60);
const minutes = time % 60;
return `${hours}h ${minutes < 10 ? `0${minutes}` : minutes}m`;
}
return (
<View style={{
height: 100,
borderRadius: 20,
justifyContent: "flex-start",
flexDirection: 'row',
paddingHorizontal: 20,
marginVertical: 5
}}>
<Image
style={styles.filmCard}
source={{
uri: props.imageURL,
}}
/>
<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.name}</Text>
<Text style={{color: "grey", fontWeight: "bold", fontSize: 17}}>{formatTime(props.runtime)}</Text>
<View style={{marginVertical: 10}}>
<BadgeFilm name={"Science-Ficton"}/>
</View>
</View>
</View>
);
}

@ -0,0 +1,31 @@
class Movie {
id: string
original_title: string
poster_path: string
runtime: number
vote_average: number
constructor(id: string, original_title: string, poster_path: string, runtime: number, vote_average: number) {
this.id = id;
this.original_title = original_title;
this.poster_path = poster_path;
this.runtime = runtime;
this.vote_average = vote_average;
}
}
export interface Cast {
cast: string
}
export interface People {
name: string
job: string
}
export default Movie;

@ -0,0 +1,108 @@
import {useEffect, useState} from "react";
import {FlatList, View} from "react-native";
import {ListWidget} from "./ListWidget";
import axios from "axios";
import apiTMBD from "../services/tmdb";
interface idMovie {
id: string
}
interface Movie {
id: string
original_title: string
poster_path: string
runtime: number
vote_average: number
director: string
}
const opt = {
method: 'GET',
url: 'https://api.themoviedb.org/3/trending/all/day',
headers: {
Accept: "application/json"
},
params: {
api_key: 'a133422b5b1f22428e8074470d321865'
}
}
const opt2 = {
method: 'GET',
url: 'https://api.themoviedb.org/3/trending/all/day',
headers: {
Accept: "application/json"
},
params: {
api_key: 'a133422b5b1f22428e8074470d321865'
}
}
const MovieList = () => {
const [movies, setMovies] = useState<Movie[]>([])
const movielist: Movie[] = []
useEffect(() => {
axios.get("https://api.themoviedb.org/3/trending/all/day?api_key=a133422b5b1f22428e8074470d321865").then(async (response) => {
await response.data.results.forEach(async function (id: idMovie) {
console.log(id.id);
try {
const sheet = await axios.get(`https://api.themoviedb.org/3/movie/${id.id}?api_key=a133422b5b1f22428e8074470d321865&language=en-US`);
if (sheet && sheet.status == 200) {
movielist.push(sheet.data);
setMovies(movielist);
}
} catch (e) {
console.log(e);
}
})
})
}, [])
useEffect(() => {
movies.forEach(async function (movie: Movie) {
console.log("-----------------------------");
/*console.log(movie);*/
axios.get(`https://api.themoviedb.org/3/movie/${movie.id}/credits?api_key=a133422b5b1f22428e8074470d321865&language=en-US`).then((response) => {
response.data.results.forEach(function (cast: Cast) {
console.log(cast.cast);
try {
/*const sheet = axios.get(`https://api.themoviedb.org/3/movie/${id.id}?api_key=a133422b5b1f22428e8074470d321865&language=en-US`);
if (sheet && sheet.status == 200) {
movielist.push(sheet.data);
setMovies(movielist);
}*/
} catch (e) {
console.log(e);
}
})
});
})
})
return (
<FlatList
data={movies}
keyExtractor={item => item.id}
renderItem={({item}) => <ListWidget name={item.original_title}
imageURL={`https://image.tmdb.org/t/p/w500/${item.poster_path}`}
runtime={item.runtime} director={item.director}></ListWidget>}>
</FlatList>
)
}
export default MovieList;

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

@ -0,0 +1,3 @@
export interface Movie{
}

@ -3,15 +3,15 @@
* https://reactnavigation.org/docs/getting-started * https://reactnavigation.org/docs/getting-started
* *
*/ */
import { FontAwesome } from '@expo/vector-icons'; import {FontAwesome} from '@expo/vector-icons';
import { FontAwesomeIcon} from "@fortawesome/react-native-fontawesome"; import {FontAwesomeIcon} from "@fortawesome/react-native-fontawesome";
import { faClock, faFilm, faHeart} from "@fortawesome/free-solid-svg-icons"; import {faClock, faFilm, faHeart} from "@fortawesome/free-solid-svg-icons";
import Ionicons from '@expo/vector-icons/Ionicons'; import Ionicons from '@expo/vector-icons/Ionicons';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native'; import {NavigationContainer, DefaultTheme, DarkTheme} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack'; import {createNativeStackNavigator} from '@react-navigation/native-stack';
import * as React from 'react'; import * as React from 'react';
import { ColorSchemeName, Pressable } from 'react-native'; import {ColorSchemeName, Pressable} from 'react-native';
import Colors from '../constants/Colors'; import Colors from '../constants/Colors';
import useColorScheme from '../hooks/useColorScheme'; import useColorScheme from '../hooks/useColorScheme';
@ -19,17 +19,17 @@ import NotFoundScreen from '../screens/NotFoundScreen';
import WatchLaterScreen from '../screens/WatchLaterScreen'; import WatchLaterScreen from '../screens/WatchLaterScreen';
import FavoriteScreen from '../screens/FavoriteScreen'; import FavoriteScreen from '../screens/FavoriteScreen';
import HomeScreen from '../screens/HomeScreen'; import HomeScreen from '../screens/HomeScreen';
import { RootStackParamList, RootTabParamList, RootTabScreenProps } from '../types'; import {RootStackParamList, RootTabParamList, RootTabScreenProps} from '../types';
import LinkingConfiguration from './LinkingConfiguration'; import LinkingConfiguration from './LinkingConfiguration';
export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) { export default function Navigation({colorScheme}: { colorScheme: ColorSchemeName }) {
return ( return (
<NavigationContainer <NavigationContainer
linking={LinkingConfiguration} linking={LinkingConfiguration}
theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<RootNavigator /> <RootNavigator/>
</NavigationContainer> </NavigationContainer>
); );
} }
/** /**
@ -39,15 +39,15 @@ export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeNa
const Stack = createNativeStackNavigator<RootStackParamList>(); const Stack = createNativeStackNavigator<RootStackParamList>();
function RootNavigator() { function RootNavigator() {
return ( return (
<Stack.Navigator> <Stack.Navigator>
<Stack.Screen name="Root" component={BottomTabNavigator} options={{ headerShown: false }} /> <Stack.Screen name="Root" component={BottomTabNavigator} options={{headerShown: false}}/>
<Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} /> <Stack.Screen name="Home" component={HomeScreen} options={{headerShown: false}}/>
<Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} /> <Stack.Screen name="NotFound" component={NotFoundScreen} options={{title: 'Oops!'}}/>
<Stack.Screen name="Favorite" component={FavoriteScreen} options={{ headerShown: false }} /> <Stack.Screen name="Favorite" component={FavoriteScreen} options={{headerShown: false}}/>
<Stack.Screen name="WatchLater" component={WatchLaterScreen} options={{ headerShown: false }} /> <Stack.Screen name="WatchLater" component={WatchLaterScreen} options={{headerShown: false}}/>
</Stack.Navigator> </Stack.Navigator>
); );
} }
/** /**
@ -57,54 +57,54 @@ function RootNavigator() {
const BottomTab = createBottomTabNavigator<RootTabParamList>(); const BottomTab = createBottomTabNavigator<RootTabParamList>();
function BottomTabNavigator() { function BottomTabNavigator() {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
return ( return (
<BottomTab.Navigator <BottomTab.Navigator
initialRouteName="WatchLater" initialRouteName="Home"
screenOptions={{ screenOptions={{
tabBarActiveTintColor: "purple", tabBarActiveTintColor: "purple",
}}> }}>
<BottomTab.Screen <BottomTab.Screen
name="WatchLater" name="WatchLater"
component={WatchLaterScreen} component={WatchLaterScreen}
options={({ navigation }: RootTabScreenProps<'WatchLater'>) => ({ options={({navigation}: RootTabScreenProps<'WatchLater'>) => ({
tabBarIcon: ({ color, size}) => <TabBarIcon name={faClock} color={color} size={20}/>, tabBarIcon: ({color, size}) => <TabBarIcon name={faClock} color={color} size={20}/>,
headerShown: false, headerShown: false,
})} })}
/> />
<BottomTab.Screen <BottomTab.Screen
name="Home" name="Home"
component={HomeScreen} component={HomeScreen}
options={{ options={{
headerShown: false, headerShown: false,
tabBarIcon: ({ color, size }) => <TabBarIcon name={faFilm} color={color} size={20}/>, tabBarIcon: ({color, size}) => <TabBarIcon name={faFilm} color={color} size={20}/>,
}} }}
/> />
<BottomTab.Screen <BottomTab.Screen
name="Favorite" name="Favorite"
component={FavoriteScreen} component={FavoriteScreen}
options={{ options={{
headerShown: false, headerShown: false,
tabBarIcon: ({ color, size }) => <TabBarIcon name={faHeart} color={color} size={20} />, tabBarIcon: ({color, size}) => <TabBarIcon name={faHeart} color={color} size={20}/>,
}} }}
/> />
</BottomTab.Navigator> </BottomTab.Navigator>
); );
} }
/** /**
* You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/ * You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
*/ */
function TabBarIcon(props: { function TabBarIcon(props: {
name: any; name: any;
color: string; color: string;
size: number; size: number;
}) { }) {
return <FontAwesomeIcon icon={props.name} style={{marginBottom: -5}} size={props.size} color={props.color} />; return <FontAwesomeIcon icon={props.name} style={{marginBottom: -5}} size={props.size} color={props.color}/>;
} }

288
package-lock.json generated

@ -18,6 +18,8 @@
"@react-navigation/native": "^6.0.2", "@react-navigation/native": "^6.0.2",
"@react-navigation/native-stack": "^6.1.0", "@react-navigation/native-stack": "^6.1.0",
"@reacticons/ionicons": "^6.0.4", "@reacticons/ionicons": "^6.0.4",
"@reduxjs/toolkit": "^1.9.2",
"axios": "^1.3.0",
"expo": "~47.0.12", "expo": "~47.0.12",
"expo-asset": "~8.7.0", "expo-asset": "~8.7.0",
"expo-constants": "~14.0.2", "expo-constants": "~14.0.2",
@ -37,6 +39,8 @@
"react-native-screens": "~3.18.0", "react-native-screens": "~3.18.0",
"react-native-svg": "^13.7.0", "react-native-svg": "^13.7.0",
"react-native-web": "~0.18.9", "react-native-web": "~0.18.9",
"react-redux": "^8.0.5",
"redux": "^4.2.1",
"rive-react-native": "^3.0.41" "rive-react-native": "^3.0.41"
}, },
"devDependencies": { "devDependencies": {
@ -5421,6 +5425,29 @@
"resolved": "https://registry.npmjs.org/@reacticons/ionicons/-/ionicons-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@reacticons/ionicons/-/ionicons-6.0.4.tgz",
"integrity": "sha512-FN4/D6a/kS2dEMwVltAGCKiYArDESGW1fgsV2bgz2ZHFAlmBF7o2p7Ckr+clOHzIEg1odWm+gdc+DBtYc80ENQ==" "integrity": "sha512-FN4/D6a/kS2dEMwVltAGCKiYArDESGW1fgsV2bgz2ZHFAlmBF7o2p7Ckr+clOHzIEg1odWm+gdc+DBtYc80ENQ=="
}, },
"node_modules/@reduxjs/toolkit": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
"integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
"dependencies": {
"immer": "^9.0.16",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || ^18",
"react-redux": "^7.2.1 || ^8.0.2"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-redux": {
"optional": true
}
}
},
"node_modules/@segment/loosely-validate-event": { "node_modules/@segment/loosely-validate-event": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz",
@ -5530,6 +5557,15 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/istanbul-lib-coverage": { "node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -5571,8 +5607,7 @@
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
"dev": true
}, },
"node_modules/@types/qs": { "node_modules/@types/qs": {
"version": "6.9.7", "version": "6.9.7",
@ -5583,7 +5618,6 @@
"version": "18.0.27", "version": "18.0.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"dev": true,
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -5602,8 +5636,7 @@
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"dev": true
}, },
"node_modules/@types/stack-utils": { "node_modules/@types/stack-utils": {
"version": "2.0.1", "version": "2.0.1",
@ -5611,6 +5644,11 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true "dev": true
}, },
"node_modules/@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"node_modules/@types/yargs": { "node_modules/@types/yargs": {
"version": "15.0.15", "version": "15.0.15",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
@ -5969,6 +6007,29 @@
"node": ">= 4.5.0" "node": ">= 4.5.0"
} }
}, },
"node_modules/axios": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.0.tgz",
"integrity": "sha512-oCye5nHhTypzkdLIvF9SaHfr8UAquqCn1KY3j8vsrjeol8yohAdGxIpRPbF1bOLsx33HOAatdfMX1yzsj2cHwg==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios/node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/babel-core": { "node_modules/babel-core": {
"version": "7.0.0-bridge.0", "version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@ -7419,8 +7480,7 @@
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
"dev": true
}, },
"node_modules/dag-map": { "node_modules/dag-map": {
"version": "1.0.2", "version": "1.0.2",
@ -8778,6 +8838,25 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/fontfaceobserver": { "node_modules/fontfaceobserver": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
@ -9162,6 +9241,14 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hosted-git-info": { "node_modules/hosted-git-info": {
"version": "3.0.8", "version": "3.0.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
@ -9324,6 +9411,15 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/immer": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@ -14516,6 +14612,11 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/psl": { "node_modules/psl": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@ -14942,6 +15043,49 @@
"async-limiter": "~1.0.0" "async-limiter": "~1.0.0"
} }
}, },
"node_modules/react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
"integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"peerDependencies": {
"@types/react": "^16.8 || ^17.0 || ^18.0",
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0",
"react-native": ">=0.59",
"redux": "^4"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.4.3", "version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@ -15144,6 +15288,22 @@
"node": ">= 4" "node": ">= 4"
} }
}, },
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/regenerate": { "node_modules/regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -21641,6 +21801,17 @@
"resolved": "https://registry.npmjs.org/@reacticons/ionicons/-/ionicons-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@reacticons/ionicons/-/ionicons-6.0.4.tgz",
"integrity": "sha512-FN4/D6a/kS2dEMwVltAGCKiYArDESGW1fgsV2bgz2ZHFAlmBF7o2p7Ckr+clOHzIEg1odWm+gdc+DBtYc80ENQ==" "integrity": "sha512-FN4/D6a/kS2dEMwVltAGCKiYArDESGW1fgsV2bgz2ZHFAlmBF7o2p7Ckr+clOHzIEg1odWm+gdc+DBtYc80ENQ=="
}, },
"@reduxjs/toolkit": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
"integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
"requires": {
"immer": "^9.0.16",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7"
}
},
"@segment/loosely-validate-event": { "@segment/loosely-validate-event": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz",
@ -21747,6 +21918,15 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/istanbul-lib-coverage": { "@types/istanbul-lib-coverage": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -21788,8 +21968,7 @@
"@types/prop-types": { "@types/prop-types": {
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
"dev": true
}, },
"@types/qs": { "@types/qs": {
"version": "6.9.7", "version": "6.9.7",
@ -21800,7 +21979,6 @@
"version": "18.0.27", "version": "18.0.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"dev": true,
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -21819,8 +21997,7 @@
"@types/scheduler": { "@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"dev": true
}, },
"@types/stack-utils": { "@types/stack-utils": {
"version": "2.0.1", "version": "2.0.1",
@ -21828,6 +22005,11 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true "dev": true
}, },
"@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"@types/yargs": { "@types/yargs": {
"version": "15.0.15", "version": "15.0.15",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
@ -22100,6 +22282,28 @@
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
}, },
"axios": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.0.tgz",
"integrity": "sha512-oCye5nHhTypzkdLIvF9SaHfr8UAquqCn1KY3j8vsrjeol8yohAdGxIpRPbF1bOLsx33HOAatdfMX1yzsj2cHwg==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
},
"dependencies": {
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
}
}
},
"babel-core": { "babel-core": {
"version": "7.0.0-bridge.0", "version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@ -23237,8 +23441,7 @@
"csstype": { "csstype": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
"dev": true
}, },
"dag-map": { "dag-map": {
"version": "1.0.2", "version": "1.0.2",
@ -24279,6 +24482,11 @@
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz",
"integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==" "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg=="
}, },
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"fontfaceobserver": { "fontfaceobserver": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
@ -24557,6 +24765,14 @@
} }
} }
}, },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"hosted-git-info": { "hosted-git-info": {
"version": "3.0.8", "version": "3.0.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
@ -24673,6 +24889,11 @@
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
"integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==" "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA=="
}, },
"immer": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ=="
},
"import-fresh": { "import-fresh": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@ -28673,6 +28894,11 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"psl": { "psl": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@ -28992,6 +29218,26 @@
"styleq": "^0.1.2" "styleq": "^0.1.2"
} }
}, },
"react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
"integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
"requires": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"dependencies": {
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}
}
},
"react-refresh": { "react-refresh": {
"version": "0.4.3", "version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@ -29149,6 +29395,20 @@
"tslib": "^2.0.1" "tslib": "^2.0.1"
} }
}, },
"redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"requires": {}
},
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",

@ -23,6 +23,8 @@
"@react-navigation/native": "^6.0.2", "@react-navigation/native": "^6.0.2",
"@react-navigation/native-stack": "^6.1.0", "@react-navigation/native-stack": "^6.1.0",
"@reacticons/ionicons": "^6.0.4", "@reacticons/ionicons": "^6.0.4",
"@reduxjs/toolkit": "^1.9.2",
"axios": "^1.3.0",
"expo": "~47.0.12", "expo": "~47.0.12",
"expo-asset": "~8.7.0", "expo-asset": "~8.7.0",
"expo-constants": "~14.0.2", "expo-constants": "~14.0.2",
@ -42,6 +44,8 @@
"react-native-screens": "~3.18.0", "react-native-screens": "~3.18.0",
"react-native-svg": "^13.7.0", "react-native-svg": "^13.7.0",
"react-native-web": "~0.18.9", "react-native-web": "~0.18.9",
"react-redux": "^8.0.5",
"redux": "^4.2.1",
"rive-react-native": "^3.0.41" "rive-react-native": "^3.0.41"
}, },
"devDependencies": { "devDependencies": {

@ -0,0 +1,10 @@
import {FETCH_TRENDINGMOVIE} from '../constants';
import Movie from "../../components/Movie";
export const setTrendingMovieList = (trendingList: Movie[])=> {
return {
type: FETCH_TRENDINGMOVIE,
payload: trendingList,
};
}

@ -0,0 +1 @@
export const FETCH_TRENDINGMOVIE : string = "FETCH_TRENDINGMOVIE";

@ -0,0 +1,19 @@
import {FETCH_TRENDINGMOVIE} from "../constants";
const initialState = {
trendingMovies : [],
favoriteMovies : [],
watchLaterMovies : [],
}
// @ts-ignore
export default appReducer = (state = initialState, action)=> {
switch (action.type){
case FETCH_TRENDINGMOVIE:
// @ts-ignore
return {...state, trendingMovies: action.payload};
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;

@ -1,22 +1,26 @@
import {FlatList, StyleSheet, SafeAreaView, Text, View, Image, TextInput} from 'react-native'; import {FlatList, StyleSheet, SafeAreaView, Text, View, Image, TextInput} from 'react-native';
import * as React from "react"; import * as React from "react";
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";
import {useState} from "react";
import MovieList from "../components/MovieList";
import {ListWidget} from "./WatchLaterScreen";
export default function FavoriteScreen({ navigation }: RootTabScreenProps<'Favorite'>) { export default function FavoriteScreen({ navigation }: RootTabScreenProps<'Favorite'>) {
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"}} >
<FontAwesomeIcon icon={faHeart} style={{marginBottom: -5, marginRight: 20}} size={50} color="white" /> <FontAwesomeIcon icon={faHeart} style={{marginBottom: -5, marginRight: 20}} size={50} color="white" />
<Text style={{color: "white", fontSize:30}}>Favorite</Text> <Text style={{color: "white", fontSize:30}}>Favorite</Text>
</View> </View>
<Image <Image
source={require('../assets/images/delimiter.png')} style={{height: 2, width: 400, resizeMode: "stretch"}} source={require('../assets/images/delimiter.png')} style={{height: 2, width: 400, resizeMode:"stretch"}}
/> />
<View style={{height:40, width:400, backgroundColor:"grey", borderRadius:20, marginVertical:10, alignSelf:"center"}}> <View style={{height:40, width:'90%', backgroundColor:"grey", borderRadius:20, marginVertical:10, alignSelf:"center"}}>
<TextInput style={{width:'100%', height:40, marginHorizontal:20}} ></TextInput> <TextInput style={{width:'100%', height:40, marginHorizontal:20}} ></TextInput>
</View> </View>
<FlatList <FlatList
@ -58,32 +62,4 @@ const styles = StyleSheet.create({
}, },
}); });
type ListWidgetProps = {
name : String
}
export function ListWidget(props: ListWidgetProps) {
return (
<View style={{height: 100, borderRadius: 20, justifyContent: "flex-start", flexDirection: 'row', paddingHorizontal:20, marginVertical:5}} >
<Image
style={styles.filmCard}
source={{
uri: 'https://fr.web.img4.acsta.net/pictures/21/11/16/10/01/4860598.jpg',
}}
/>
<View style={{height: 100, borderRadius: 20, justifyContent: "flex-start", flexDirection: 'column', paddingLeft:10}} >
<Text style={{color: "white", fontWeight:"bold", fontSize:25}}>{props.name}</Text>
<Text style={{color: "grey", fontWeight:"bold", fontSize:17}}>{props.name}</Text>
<View style={{marginVertical:10}}>
<BadgeFilm name={"Science-Ficton"}/>
</View>
</View>
</View>
);
}

@ -1,13 +1,23 @@
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.js";
import Rive from 'rive-react-native'; import Rive from 'rive-react-native';
import {useRef} from "react"; import {useEffect, useRef, useState} 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 {Movie} from "../interfaces";
export default function App({ navigation }: RootStackScreenProps<'Home'>) { export default function App({navigation}: RootStackScreenProps<'Home'>) {
const riveRef = useRef();
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -17,15 +27,15 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) {
paddingTop: insets.top, paddingTop: insets.top,
}, },
container:{ container: {
flex: 1, flex: 1,
}, },
filmCard: { filmCard: {
width: '80%', width: '80%',
height: '60%', height: '60%',
justifyContent:'center', justifyContent: 'center',
marginLeft:'auto', marginLeft: 'auto',
marginRight:'auto', marginRight: 'auto',
borderRadius: 15, borderRadius: 15,
@ -78,7 +88,7 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) {
}} }}
/> />
</View> </View>
<View style={{height:35, marginTop: 10, marginBottom: 15}}> <View style={{height: 35, marginTop: 10, marginBottom: 15}}>
<ScrollView <ScrollView
horizontal={true} horizontal={true}
showsHorizontalScrollIndicator={false}> showsHorizontalScrollIndicator={false}>
@ -93,63 +103,99 @@ export default function App({ navigation }: RootStackScreenProps<'Home'>) {
<BadgeGenre name={"cc"} isSelected={false}></BadgeGenre> <BadgeGenre name={"cc"} isSelected={false}></BadgeGenre>
</ScrollView> </ScrollView>
</View> </View>
<View style={{ flexDirection: 'column', alignSelf: 'flex-start', alignItems: 'flex-start', paddingHorizontal: 30, flex: 1 }}> <View style={{
flexDirection: 'column',
<View style={{ flexDirection: 'row', alignSelf: 'flex-start', justifyContent: 'flex-start', width: "100%"}}> alignSelf: 'flex-start',
alignItems: 'flex-start',
paddingHorizontal: 30,
flex: 1
}}>
<View style={{
flexDirection: 'row',
alignSelf: 'flex-start',
justifyContent: 'flex-start',
width: "100%"
}}>
<BadgeFilm name={"Science-fiction"}></BadgeFilm> <BadgeFilm name={"Science-fiction"}></BadgeFilm>
<BadgeFilm name={"Science-fiction"}></BadgeFilm> <BadgeFilm name={"Science-fiction"}></BadgeFilm>
<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}}>SPIDER-MAN
</View> No Way Home</Text>
</View>
<Text style={{color: "grey", fontSize: 20, fontWeight: "bold"}}>Jean-Marc généreux</Text> <Text style={{color: "grey", fontSize: 20, fontWeight: "bold"}}>Jean-Marc généreux</Text>
</View> </View>
<View style={{ flexDirection: 'row' ,alignItems: 'center', justifyContent: "space-evenly", paddingHorizontal: 30, height: '15%', width:'100%'}}> <View style={{
<TouchableOpacity> flexDirection: 'row',
<Image alignItems: 'center',
source={require('../assets/images/WatchLater.png')} style={{ resizeMode:"stretch", height:'65%', aspectRatio: 1,}} justifyContent: "space-evenly",
/> paddingHorizontal: 30,
height: '15%',
</TouchableOpacity> width: '100%'
<TouchableOpacity> }}>
<Image <TouchableOpacity>
source={require('../assets/images/Generate.png')} style={{resizeMode:"stretch", height:'85%',aspectRatio: 1,}} <Image
/> source={require('../assets/images/WatchLater.png')}
style={{resizeMode: "stretch", height: '65%', aspectRatio: 1,}}
</TouchableOpacity> />
<TouchableOpacity>
<Image </TouchableOpacity>
source={require('../assets/images/Favorite.png')} style={{ resizeMode:"stretch", height:'65%', aspectRatio: 1,}} <TouchableOpacity>
/> <Image
source={require('../assets/images/Generate.png')}
</TouchableOpacity> style={{resizeMode: "stretch", height: '85%', aspectRatio: 1,}}
/>
</TouchableOpacity>
<TouchableOpacity>
<Image
source={require('../assets/images/Favorite.png')}
style={{resizeMode: "stretch", height: '65%', aspectRatio: 1,}}
/>
</TouchableOpacity>
</View> </View>
</SafeAreaView> </SafeAreaView>
); );
} }
type BadgeGenreProps = { type BadgeGenreProps = {
name : String name: String
isSelected: Boolean isSelected: Boolean
} }
export function BadgeGenre(props: BadgeGenreProps) { export function BadgeGenre(props: BadgeGenreProps) {
if(props.isSelected==false){ if (props.isSelected == false) {
return ( return (
<View style={{paddingHorizontal: 20, marginHorizontal: 5,height: 35, backgroundColor: '#2E2E2E', borderRadius: 20, justifyContent: "center"}} > <View style={{
paddingHorizontal: 20,
marginHorizontal: 5,
height: 35,
backgroundColor: '#2E2E2E',
borderRadius: 20,
justifyContent: "center"
}}>
<Text style={{color: "white"}}>{props.name}</Text> <Text style={{color: "white"}}>{props.name}</Text>
</View> </View>
); );
} } else {
else{
return ( return (
<View style={{paddingHorizontal: 20, marginHorizontal: 5,height: 35, backgroundColor: '#5C5C5C', borderRadius: 20, borderWidth: 1, borderColor: "white" ,justifyContent: "center"}} > <View style={{
paddingHorizontal: 20,
marginHorizontal: 5,
height: 35,
backgroundColor: '#5C5C5C',
borderRadius: 20,
borderWidth: 1,
borderColor: "white",
justifyContent: "center"
}}>
<Text style={{color: "white"}}>{props.name}</Text> <Text style={{color: "white"}}>{props.name}</Text>
</View> </View>
@ -160,17 +206,26 @@ export function BadgeGenre(props: BadgeGenreProps) {
} }
type BadgeFilmProps = { type BadgeFilmProps = {
name : String name: String
} }
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,
</View> 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>
); );
} }

@ -4,11 +4,13 @@ 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 {getTrendingMovieList} from "../services/api";
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 +37,23 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat
}, },
}); });
// @ts-ignore
const nList = useSelector(state => state.appReducer.trendingMovies);
const dispatch = useDispatch();
useEffect(()=>{
const loadTrendingMovie = async () => {
// @ts-ignore
await dispatch(getTrendingMovieList());
};
loadTrendingMovie();
}, [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"}} >
@ -45,23 +64,14 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat
<Image <Image
source={require('../assets/images/delimiter.png')} style={{height: 2, width: 400, resizeMode:"stretch"}} source={require('../assets/images/delimiter.png')} style={{height: 2, width: 400, resizeMode:"stretch"}}
/> />
<View style={{height:40, width:400, backgroundColor:"grey", borderRadius:20, marginVertical:10, alignSelf:"center"}}> <View style={{height:40, width:'90%', backgroundColor:"grey", borderRadius:20, marginVertical:10, alignSelf:"center"}}>
<TextInput style={{width:'100%', height:40, marginHorizontal:20}} ></TextInput> <TextInput style={{width:'100%', height:40, marginHorizontal:20}} ></TextInput>
</View> </View>
<FlatList <FlatList
data={[ data={nList}
{key: 'Devin'}, renderItem={({item}) => <ListWidget name={item.original_title}
{key: 'Dan'}, imageURL={`https://image.tmdb.org/t/p/w500/${item.poster_path}`}
{key: 'Dominic'}, runtime={item.runtime} director={item.director}></ListWidget>}
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem={({item}) => <ListWidget name={item.key} ></ListWidget>}
/> />
</SafeAreaView> </SafeAreaView>
); );
@ -70,13 +80,25 @@ export default function WatchLaterScreen({ navigation }: RootTabScreenProps<'Wat
type ListWidgetProps = { type ListWidgetProps = {
name : String imageURL: string
name: String
runtime: number
director: string
} }
export function ListWidget(props: ListWidgetProps) { export function ListWidget(props: ListWidgetProps) {
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
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`;
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
filmCard: { filmCard: {
width: 70, width: 70,
@ -87,21 +109,39 @@ export function ListWidget(props: ListWidgetProps) {
}, },
}); });
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.imageURL,
</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.name}</Text>
<Text style={{color: "grey", fontWeight: "bold", fontSize: 17}}>{formatTime(props.runtime)}</Text>
<View style={{marginVertical: 10}}>
<BadgeFilm name={"Science-Ficton"}/>
</View> </View>
</View>
</View>
); );

@ -0,0 +1,23 @@
import Config from "../constants/config";
import Movie from "../components/Movie";
import {setTrendingMovieList} from "../redux/actions/actionGetTrendingMovie";
export const getTrendingMovieList = () =>{
// @ts-ignore
return async dispatch => {
try {
const trendingMoviePromise = await fetch(Config.base_url + "trending/all/day?api_key=" + Config.api_key);
const trendingListJson = await trendingMoviePromise.json();
console.log('json----------',trendingListJson);
// @ts-ignore
const trendingList: Movie[] = trendingListJson.results.map(elt => new Movie(elt["id"],elt["original_title"],elt["poster_path"], elt["runtime"],elt["vote_average"]));
dispatch(setTrendingMovieList(trendingList));
} catch (error) {
console.log('Error----------',error);
}
}
}
Loading…
Cancel
Save