diff --git a/.eslintrc.json b/.eslintrc.json index 464e65e..eb88c19 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,6 +6,10 @@ "plugin:react/recommended", "airbnb" ], + "globals": { + "__DEV__": false, + "window": false + }, "parserOptions": { "ecmaFeatures": { "jsx": true diff --git a/.vscode/settings.json b/.vscode/settings.json index 251257a..750c1d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { - "eslint.enable": true, "editor.tabSize": 2, "editor.useTabStops": true, + "eslint.enable": true, "editor.detectIndentation": false, "editor.formatOnSave": false, "editor.codeActionsOnSave": { diff --git a/package.json b/package.json index 0d208f9..8538d14 100644 --- a/package.json +++ b/package.json @@ -11,42 +11,39 @@ "postinstall": "jetify" }, "dependencies": { - "@react-native-community/blur": "^3.6.0", - "@react-native-community/masked-view": "^0.1.10", - "@react-navigation/native": "^5.5.1", - "@react-navigation/stack": "^5.5.1", - "add": "^2.0.6", - "axios": "^0.19.2", - "moment": "^2.26.0", + "@react-native-community/masked-view": "0.1.10", + "@react-navigation/bottom-tabs": "5.7.3", + "@react-navigation/native": "5.5.1", + "@react-navigation/stack": "5.5.1", + "axios": "0.19.2", + "moment": "2.26.0", "react": "16.11.0", "react-native": "0.62.2", - "react-native-gesture-handler": "^1.6.1", - "react-native-linear-gradient": "^2.5.6", - "react-native-reanimated": "^1.9.0", - "react-native-safe-area-context": "^3.0.5", - "react-native-screens": "^2.8.0", + "react-native-gesture-handler": "1.6.1", + "react-native-linear-gradient": "2.5.6", + "react-native-reanimated": "1.9.0", + "react-native-safe-area-context": "3.0.5", + "react-native-screens": "2.8.0", "react-native-splash-screen": "3.2.0", - "react-native-vector-icons": "^6.6.0", - "react-redux": "^7.2.0", - "redux": "^4.0.5", - "redux-actions": "^2.6.5", - "redux-thunk": "^2.3.0", - "rn-placeholder": "^3.0.1", - "yarn": "^1.22.4" + "react-native-vector-icons": "6.6.0", + "react-redux": "7.2.0", + "redux": "4.0.5", + "redux-actions": "2.6.5", + "redux-thunk": "2.3.0" }, "devDependencies": { - "@babel/core": "^7.10.2", - "@babel/runtime": "^7.10.2", - "babel-jest": "^26.0.1", - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.1.0", - "eslint-plugin-import": "^2.21.2", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.20.0", - "eslint-plugin-react-hooks": "^2.5.1", - "jest": "^26.0.1", - "jetifier": "^1.6.5", - "metro-react-native-babel-preset": "^0.59.0", + "@babel/core": "7.10.2", + "@babel/runtime": "7.10.2", + "babel-jest": "26.0.1", + "eslint": "6.8.0", + "eslint-config-airbnb": "18.1.0", + "eslint-plugin-import": "2.21.2", + "eslint-plugin-jsx-a11y": "6.2.3", + "eslint-plugin-react": "7.20.0", + "eslint-plugin-react-hooks": "2.5.1", + "jest": "26.0.1", + "jetifier": "1.6.5", + "metro-react-native-babel-preset": "0.59.0", "react-test-renderer": "16.11.0" }, "jest": { diff --git a/src/App.js b/src/App.js index 57fd849..0c9cdbe 100644 --- a/src/App.js +++ b/src/App.js @@ -4,14 +4,27 @@ import { Provider as ReduxProvider, } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { createStackNavigator } from '@react-navigation/stack'; +import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons'; +import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; -import Home from './pages/Home'; +import Movies from './pages/Movies'; +import TVShows from './pages/TVShows'; import colors from './values/colors'; import { store } from './redux'; import Start from './pages/Start'; import Movie from './pages/Movie'; +import TVShow from './pages/TVShow'; + +const MovieTabIcon = ({ color, size }) => ( + +); + +const TVTabIcon = ({ color, size }) => ( + +); const APP_THEME = { dark: false, @@ -25,20 +38,43 @@ const APP_THEME = { }; const Stack = createStackNavigator(); +const Tab = createBottomTabNavigator(); -const MoviewStack = () => ( +const MovieStack = () => ( - + ); +const TVShowsStack = () => ( + + + + +); + +const AppTabs = () => ( + + + + +); + const App = () => ( - + diff --git a/src/components/Category.js b/src/components/Category.js index 38efdcf..2022e80 100644 --- a/src/components/Category.js +++ b/src/components/Category.js @@ -21,7 +21,7 @@ const styles = StyleSheet.create({ const Category = ({ id, categories }) => { const categoryName = useMemo(() => { if (!categories) return null; - return categories.find((category) => category.id === id).name; + return categories.find((category) => category.id === id)?.name || ''; }, [categories]); return ( diff --git a/src/components/HorizontalMovieCoverList.js b/src/components/HorizontalMovieCoverList.js index c2e3722..532102c 100644 --- a/src/components/HorizontalMovieCoverList.js +++ b/src/components/HorizontalMovieCoverList.js @@ -45,11 +45,13 @@ const KEY_EXTRACTOR = (item) => String(item.id); const HorizontalSpacing = () => ; -const MovieCard = memo(({ item, index, showIndex }) => { +const MovieCard = memo(({ + item, index, showIndex, mediaType, +}) => { const navigation = useNavigation(); const handleMoviePress = useCallback(() => { - navigation.push('Movie', { movie: item }); + navigation.push(mediaType === 'movie' ? 'Movie' : 'TVShow', { item }); }, [navigation, item]); return ( @@ -64,13 +66,14 @@ const MovieCard = memo(({ item, index, showIndex }) => { }); const HorizontalMovieCoverList = ({ - requestDataSource, showIndex = false, title, description, + requestDataSource, showIndex, title, description, + mediaType, }) => { const [dataSource, setDataSource] = useState(null); const [loading, setLoading] = useState(true); const renderCover = useCallback(({ item, index }) => ( - + ), []); const requestListData = useCallback(async () => { @@ -128,4 +131,8 @@ const HorizontalMovieCoverList = ({ ); }; +HorizontalMovieCoverList.defaultProps = { + showIndex: false, +}; + export default memo(HorizontalMovieCoverList); diff --git a/src/components/SliderItem.js b/src/components/SliderItem.js index c0e125d..4c2340f 100644 --- a/src/components/SliderItem.js +++ b/src/components/SliderItem.js @@ -48,18 +48,18 @@ const styles = StyleSheet.create({ const BACKDROP_ASPECT_RATIO = 16 / 9; const LINEAR_GRADIENT_COLORS = ['#14151A00', '#14151A']; -const SliderItem = memo(({ item }) => { +const SliderItem = memo(({ item, mediaType }) => { const { width } = useWindowDimensions(); const navigation = useNavigation(); const { - backdrop_path: backdropPath, title, + backdrop_path: backdropPath, title, name, genre_ids: genreIds, } = item; const handlePress = useCallback(() => { - navigation.navigate('Movie', { movie: item }); + navigation.navigate(mediaType === 'movie' ? 'Movie' : 'TVShow', { item }); }, []); const blurredImageStyle = useMemo(() => ({ @@ -136,7 +136,7 @@ const SliderItem = memo(({ item }) => { style={styles.movieTitle} numberOfLines={1} > - {title} + {title || name} {renderCategories()} @@ -170,9 +170,7 @@ SliderItem.Placeholder = memo(() => { return ( - {/* */} - {/* */} diff --git a/src/pages/Movie.js b/src/pages/Movie.js index f67099d..3e46c3a 100644 --- a/src/pages/Movie.js +++ b/src/pages/Movie.js @@ -101,7 +101,7 @@ const LINEAR_GRADIENT_COLORS = ['#14151A00', '#14151A']; const KEY_EXTRACTOR = (item) => String(item.id); const Movie = ({ route }) => { - const movie = route.params?.movie; + const { item: movie } = route.params; const [movieDetails, setMovieDetails] = useState(movie); const [moviewCredits, setMovieCredits] = useState(null); @@ -160,8 +160,8 @@ const Movie = ({ route }) => { style={styles.profileAvatar} /> - {item.name} - {item.character} + {item.name} + {item.character} ), []); @@ -263,6 +263,7 @@ const Movie = ({ route }) => { title="Relacionados" description="Filmes parecidos com este" requestDataSource={requestRelated} + mediaType="movie" /> ) : null} diff --git a/src/pages/Home.js b/src/pages/Movies.js similarity index 95% rename from src/pages/Home.js rename to src/pages/Movies.js index d597343..f90afc6 100644 --- a/src/pages/Home.js +++ b/src/pages/Movies.js @@ -40,7 +40,7 @@ const styles = StyleSheet.create({ const KEY_EXTRACTOR = (item) => String(item.id); -const Home = () => { +const Movies = () => { const [trendingDay, setTrendingDay] = useState(null); const flatlistRef = useRef(null); @@ -110,7 +110,7 @@ const Home = () => { } }, []); - const renderItem = useCallback(({ item }) => , []); + const renderItem = useCallback(({ item }) => , []); const renderEmptyComponent = () => ( @@ -141,19 +141,22 @@ const Home = () => { description="Veja quais são os melhores filmes da semana" showIndex requestDataSource={requestTrendingWeek} + mediaType="movie" /> ); }; -export default memo(Home); +export default memo(Movies); diff --git a/src/pages/TVShow.js b/src/pages/TVShow.js new file mode 100644 index 0000000..169420b --- /dev/null +++ b/src/pages/TVShow.js @@ -0,0 +1,274 @@ +import React, { + useCallback, useState, useMemo, memo, +} from 'react'; +import { + Image, View, useWindowDimensions, StatusBar, Text, + StyleSheet, ScrollView, FlatList, +} from 'react-native'; + +import axios from 'axios'; +import moment from 'moment'; +import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; +import LinearGradient from 'react-native-linear-gradient'; +import { useIsFocused } from '@react-navigation/native'; + +import useDidMount from '../hooks/useDidMount'; +import Cover from '../components/Cover'; +import HorizontalMovieCoverList from '../components/HorizontalMovieCoverList'; +import { getImageUrl } from '../helpers/url-helper'; +import colors from '../values/colors'; + +const styles = StyleSheet.create({ + header: { + marginTop: -100, + marginHorizontal: 16, + flexDirection: 'row', + alignItems: 'flex-end', + }, + textContainer: { + flex: 1, + marginLeft: 16, + }, + tvShowTitle: { + color: 'white', + fontSize: 20, + fontWeight: 'bold', + }, + dateAndTime: { + color: '#ffffff66', + }, + rating: { + color: colors.primary, + fontSize: 20, + }, + ragingContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + voters: { + marginLeft: 8, + color: colors.textSecondary, + }, + body: { + padding: 16, + }, + bodyTitle: { + color: colors.textPrimary, + fontSize: 24, + fontWeight: 'bold', + }, + bodyText: { + color: colors.textSecondary, + }, + profileContainer: { + flexDirection: 'column', + alignItems: 'center', + width: 132, + paddingHorizontal: 16, + }, + profileAvatar: { + height: 100, + width: 100, + borderRadius: 100 / 2, + position: 'absolute', + top: 0, + right: 0, + left: 0, + bottom: 0, + }, + profileAvatarContainer: { + height: 100, + width: 100, + borderRadius: 100 / 2, + backgroundColor: colors.backgroundLight, + alignItems: 'center', + justifyContent: 'center', + }, + creditName: { + marginTop: 16, + color: colors.textPrimary, + textAlign: 'center', + }, + creditCharacterName: { + color: colors.textSecondary, + textAlign: 'center', + }, +}); + +const BACKDROP_ASPECT_RATIO = 16 / 9; +const LINEAR_GRADIENT_COLORS = ['#14151A00', '#14151A']; + +const KEY_EXTRACTOR = (item) => String(item.id); + +const TVShow = ({ route }) => { + const { item: tvShow } = route.params; + + const [tvShowDetails, setTvShowDetails] = useState(tvShow); + const [tvShowCredits, setTvShowCredits] = useState(null); + + const { width } = useWindowDimensions(); + const isFocused = useIsFocused(); + + const requestDetails = useCallback(async () => { + try { + const { data } = await axios.get(`/medias/tv/${tvShow.id}`, { + params: { + language: 'pt-BR', + }, + }); + setTvShowDetails(data); + } catch (ex) { + console.warn(ex); + } + }, []); + + const requestCredits = useCallback(async () => { + try { + const { data } = await axios.get(`/medias/tv/${tvShow.id}/credits`, { + params: { + language: 'pt-BR', + }, + }); + setTvShowCredits(data); + } catch (ex) { + console.warn(ex); + } + }, []); + + const requestRelated = useCallback(async () => { + try { + const { data } = await axios.get(`/medias/tv/${tvShow.id}/recommendations`, { + params: { + language: 'pt-BR', + }, + }); + return data; + } catch (ex) { + console.warn(ex); + return null; + } + }, []); + + const renderItem = useCallback(({ item }) => ( + + + + + + {item.name} + {item.character} + + ), []); + + const backdropSource = useMemo( + () => ({ + uri: getImageUrl({ size: 'w780', path: tvShowDetails.backdrop_path }), + }), + [tvShowDetails.backdrop_path], + ); + + const backdropStyles = useMemo( + () => ({ + width, + height: width / BACKDROP_ASPECT_RATIO, + opacity: 0.8, + }), + [width], + ); + + const linearGradientStyles = useMemo(() => ({ + width, + position: 'absolute', + bottom: 0, + height: 120, + }), [width]); + + useDidMount(() => { + requestDetails(); + requestCredits(); + }); + + return ( + + + + + + + + + + + + {tvShowDetails.name} + + + {moment(tvShowDetails.release_date).format('DD/MM/YYYY')} + {' '} + - + {' '} + {tvShowDetails.runtime || '-'} + min + + + + + + + {tvShowDetails.vote_average} + + + {tvShowDetails.vote_count} + {' '} + votos + + + + + + + Sinopse + + + {tvShowDetails.overview} + + + + Creditos + + + {isFocused + ? ( + <> + + + + + ) : null} + + ); +}; + +export default memo(TVShow); diff --git a/src/pages/TVShows.js b/src/pages/TVShows.js new file mode 100644 index 0000000..9c90aee --- /dev/null +++ b/src/pages/TVShows.js @@ -0,0 +1,162 @@ +import React, { + useCallback, useState, useRef, memo, +} from 'react'; +import { + View, FlatList, StyleSheet, + ScrollView, + StatusBar, +} from 'react-native'; + +import axios from 'axios'; + +import SliderItem from '../components/SliderItem'; +import HorizontalMovieCoverList from '../components/HorizontalMovieCoverList'; +import useDidMount from '../hooks/useDidMount'; + +const styles = StyleSheet.create({ + title: { + fontSize: 24, + fontWeight: 'bold', + color: 'white', + marginLeft: 16, + }, + subtitle: { + fontSize: 16, + color: '#ffffff55', + marginLeft: 16, + marginBottom: 8, + }, + horizontalSpacing: { + width: 8, + }, + horizontalCoverList: { + paddingHorizontal: 16, + paddingBottom: 16, + }, + flatlist: { + marginBottom: 16, + }, +}); + +const KEY_EXTRACTOR = (item) => String(item.id); + +const TVShows = () => { + const [trendingDay, setTrendingDay] = useState(null); + + const flatlistRef = useRef(null); + + const requestTrendingDay = useCallback(async () => { + try { + const { data } = await axios.get('/medias/trending/tv/day', { + params: { + language: 'pt-BR', + }, + }); + + const newData = { + ...data, + results: data.results.filter((item) => Boolean(item.backdrop_path)), + }; + + setTrendingDay(newData); + } catch (ex) { + console.warn(ex); + } + }, []); + + const requestTrendingWeek = useCallback(async () => { + try { + const { data } = await axios.get('/medias/trending/tv/week', { + params: { + language: 'pt-BR', + }, + }); + + return data; + } catch (ex) { + console.warn(ex); + return null; + } + }, []); + + const requestDiscover = useCallback(async () => { + try { + const { data } = await axios.get('/medias/discover/tv', { + params: { + language: 'pt-BR', + }, + }); + + return data; + } catch (ex) { + console.warn(ex); + return null; + } + }, []); + + const requestTopRated = useCallback(async () => { + try { + const { data } = await axios.get('/medias/tv/top_rated', { + params: { + language: 'pt-BR', + region: 'BR', + }, + }); + + return data; + } catch (ex) { + console.warn(ex); + return null; + } + }, []); + + const renderItem = useCallback(({ item }) => , []); + + const renderEmptyComponent = () => ( + + + + ); + + useDidMount(() => { + requestTrendingDay(); + }, []); + + return ( + + + + + + + + ); +}; + +export default memo(TVShows); diff --git a/src/redux/ducks/index.js b/src/redux/ducks/index.js index 800c47f..63ee1b4 100644 --- a/src/redux/ducks/index.js +++ b/src/redux/ducks/index.js @@ -1,5 +1,7 @@ import { reducers as categories } from './categories'; -export const reducers = { +const reducers = { ...categories, }; + +export default reducers; diff --git a/src/redux/index.js b/src/redux/index.js index 55c99e4..95b06c6 100644 --- a/src/redux/index.js +++ b/src/redux/index.js @@ -1,21 +1,18 @@ -import { combineReducers, createStore, applyMiddleware, compose } from 'redux'; +import { + combineReducers, createStore, applyMiddleware, compose, +} from 'redux'; import thunk from 'redux-thunk'; -import { reducers as duckReducers } from './ducks'; +import duckReducers from './ducks'; const allReducers = combineReducers(duckReducers); -const mainReducer = (state, action) => { - return allReducers(state, action); -}; - -const composeEnhancers = - __DEV__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ - ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ - : compose; +const middlewares = [thunk]; export const store = createStore( - mainReducer, - composeEnhancers(applyMiddleware(thunk)), + allReducers, + compose(applyMiddleware(...middlewares)), ); + +export default null; diff --git a/src/redux/thunks/categories.js b/src/redux/thunks/categories.js index a6e29a3..0f92065 100644 --- a/src/redux/thunks/categories.js +++ b/src/redux/thunks/categories.js @@ -1,16 +1,23 @@ import axios from 'axios'; import { actions as categoriesActions } from '../ducks/categories'; -export const getCategories = () => async (dispatch, getState) => { +export const getCategories = () => async (dispatch) => { try { - const { data } = await axios.get( + const { data: movieData } = await axios.get( '/medias/genre/movie/list', { params: { language: 'pt-BR', }, }, ); - dispatch(categoriesActions.setCategories(data.genres)); + const { data: tvData } = await axios.get( + '/medias/genre/tv/list', { + params: { + language: 'pt-BR', + }, + }, + ); + dispatch(categoriesActions.setCategories([...movieData.genres, ...tvData.genres])); } catch (ex) { console.warn(ex); } diff --git a/yarn.lock b/yarn.lock index 8154b80..19f19fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.10.1" -"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.10.2", "@babel/core@^7.7.5": +"@babel/core@7.10.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.7.5": version "7.10.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.2.tgz#bd6786046668a925ac2bd2fd95b579b92a23b36a" integrity sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ== @@ -668,7 +668,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4": +"@babel/runtime@7.10.2", "@babel/runtime@^7.0.0", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4": version "7.10.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839" integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg== @@ -997,13 +997,6 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@react-native-community/blur@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.6.0.tgz#31c9e0f2770519c9b5c4f99418f192246f0d4db8" - integrity sha512-GtDBhpX2pQcjl4VopOC8FktrVufrEfYRwVeMQ2WWckqKIv2BdwvlvWvj88L1WmEdBr9UNcm3rtgz+d+YXkmirA== - dependencies: - prop-types "^15.5.10" - "@react-native-community/cli-debugger-ui@^4.9.0": version "4.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-4.9.0.tgz#4177764ba69243c97aa26829d59d9501acb2bd71" @@ -1111,11 +1104,19 @@ sudo-prompt "^9.0.0" wcwidth "^1.0.1" -"@react-native-community/masked-view@^0.1.10": +"@react-native-community/masked-view@0.1.10": version "0.1.10" resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.10.tgz#5dda643e19e587793bc2034dd9bf7398ad43d401" integrity sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ== +"@react-navigation/bottom-tabs@5.7.3": + version "5.7.3" + resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-5.7.3.tgz#0105c95cd1a35948843ad3f6464b3c25febb1ccc" + integrity sha512-sLlnxhrAdRzEvzI9jJS46DMveTu/Ij5f0cE+5F6AGUT4M5Ge4HPtTU3e4HRvXioVwj+Gn/nzRA928BtTin10gQ== + dependencies: + color "^3.1.2" + react-native-iphone-x-helper "^1.2.1" + "@react-navigation/core@^5.10.0": version "5.10.0" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-5.10.0.tgz#aee9e22a5f0f458ebeadc155f347b13eb5ff5212" @@ -1128,7 +1129,7 @@ react-is "^16.13.0" use-subscription "^1.4.0" -"@react-navigation/native@^5.5.1": +"@react-navigation/native@5.5.1": version "5.5.1" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.5.1.tgz#e669d9561e54d86b1315637b8d5630dc55ee9383" integrity sha512-5pzsfvLdnvqfrWgTMCLDFaGK6Sj30p7tAMhUGneV2oGlx0OIbhgc6/04UUMpKEmAS2PaC/GZa1LQIsSVWDewvw== @@ -1143,7 +1144,7 @@ dependencies: nanoid "^3.1.5" -"@react-navigation/stack@^5.5.1": +"@react-navigation/stack@5.5.1": version "5.5.1" resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.5.1.tgz#95efa28edbfd1323e5ad9f01f539d43ffad8decc" integrity sha512-oU2FEm+Ba6jMd5VA2WnuNfCO2HlZmGhrEX9yjBCyFj7fFCG1SB7WJdKLhZShtx3KxG/qWKphICeTLlYvkHdSpQ== @@ -1327,11 +1328,6 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== -add@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235" - integrity sha1-JI8Kn25aUo7yKV2+7DBTITCuIjU= - ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: version "6.12.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" @@ -1591,7 +1587,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== -axios@^0.19.2: +axios@0.19.2: version "0.19.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== @@ -1603,7 +1599,7 @@ axobject-query@^2.0.2: resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" integrity sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ== -babel-jest@^26.0.1: +babel-jest@26.0.1, babel-jest@^26.0.1: version "26.0.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.0.1.tgz#450139ce4b6c17174b136425bda91885c397bc46" integrity sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw== @@ -2536,7 +2532,7 @@ eslint-config-airbnb-base@^14.1.0: object.assign "^4.1.0" object.entries "^1.1.2" -eslint-config-airbnb@^18.1.0: +eslint-config-airbnb@18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.1.0.tgz#724d7e93dadd2169492ff5363c5aaa779e01257d" integrity sha512-kZFuQC/MPnH7KJp6v95xsLBf63G/w7YqdPfQ0MUanxQ7zcKUNG8j+sSY860g3NwCBOa62apw16J6pRN+AOgXzw== @@ -2561,7 +2557,7 @@ eslint-module-utils@^2.6.0: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-import@^2.21.2: +eslint-plugin-import@2.21.2: version "2.21.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c" integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA== @@ -2580,7 +2576,7 @@ eslint-plugin-import@^2.21.2: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-plugin-jsx-a11y@^6.2.3: +eslint-plugin-jsx-a11y@6.2.3: version "6.2.3" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa" integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg== @@ -2595,12 +2591,12 @@ eslint-plugin-jsx-a11y@^6.2.3: has "^1.0.3" jsx-ast-utils "^2.2.1" -eslint-plugin-react-hooks@^2.5.1: +eslint-plugin-react-hooks@2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0" integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g== -eslint-plugin-react@^7.20.0: +eslint-plugin-react@7.20.0: version "7.20.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz#f98712f0a5e57dfd3e5542ef0604b8739cd47be3" integrity sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA== @@ -2644,7 +2640,7 @@ eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz#74415ac884874495f78ec2a97349525344c981fa" integrity sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ== -eslint@^6.8.0: +eslint@6.8.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== @@ -4197,7 +4193,7 @@ jest-worker@^26.0.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^26.0.1: +jest@26.0.1: version "26.0.1" resolved "https://registry.yarnpkg.com/jest/-/jest-26.0.1.tgz#5c51a2e58dff7525b65f169721767173bf832694" integrity sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg== @@ -4206,7 +4202,12 @@ jest@^26.0.1: import-local "^3.0.2" jest-cli "^26.0.1" -jetifier@^1.6.2, jetifier@^1.6.5: +jetifier@1.6.5: + version "1.6.5" + resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.5.tgz#ea87324a4230bef20a9651178ecab978ee54a8cb" + integrity sha512-T7yzBSu9PR+DqjYt+I0KVO1XTb1QhAfHnXV5Nd3xpbXM6Xg4e3vP60Q4qkNU8Fh6PHC2PivPUNN3rY7G2MxcDQ== + +jetifier@^1.6.2: version "1.6.6" resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.6.tgz#fec8bff76121444c12dc38d2dad6767c421dab68" integrity sha512-JNAkmPeB/GS2tCRqUzRPsTOHpGDah7xP18vGJfIjZC+W2sxEHbxgJxetIjIqhjQ3yYbYNEELkM/spKLtwoOSUQ== @@ -4665,7 +4666,7 @@ metro-react-native-babel-preset@0.58.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-preset@^0.59.0: +metro-react-native-babel-preset@0.59.0: version "0.59.0" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.59.0.tgz#20e020bc6ac9849e1477de1333d303ed42aba225" integrity sha512-BoO6ncPfceIDReIH8pQ5tQptcGo5yRWQXJGVXfANbiKLq4tfgdZB1C1e2rMUJ6iypmeJU9dzl+EhPmIFKtgREg== @@ -4911,7 +4912,7 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.5" -moment@^2.26.0: +moment@2.26.0: version "2.26.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a" integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== @@ -5512,7 +5513,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.4" -prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -5576,7 +5577,7 @@ react-is@^16.12.0, react-is@^16.13.0, react-is@^16.7.0, react-is@^16.8.1, react- resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-native-gesture-handler@^1.6.1: +react-native-gesture-handler@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.6.1.tgz#678e2dce250ed66e93af409759be22cd6375dd17" integrity sha512-gQgIKhDiYf754yzhhliagLuLupvGb6ZyBdzYzr7aus3Fyi87TLOw63ers+r4kGw0h26oAWTAdHd34JnF4NeL6Q== @@ -5591,24 +5592,24 @@ react-native-iphone-x-helper@^1.2.1: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== -react-native-linear-gradient@^2.5.6: +react-native-linear-gradient@2.5.6: version "2.5.6" resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz#96215cbc5ec7a01247a20890888aa75b834d44a0" integrity sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg== -react-native-reanimated@^1.9.0: +react-native-reanimated@1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.9.0.tgz#38676c99dd585504fdc7331efb45e5f48ec7339a" integrity sha512-Aj+spgIHRiVv7ezGADxnSH1EoKrQRD2+XaSiGY0MiB/pvRNNrZPSJ+3NVpvLwWf9lZMOP7dwqqyJIzoZgBDt8w== dependencies: fbjs "^1.0.0" -react-native-safe-area-context@^3.0.5: +react-native-safe-area-context@3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.0.5.tgz#3dd9bf2fea3b51f894b9849f11108ac303bbefe5" integrity sha512-cLZtHvzm/tdCTCOCgNRUsnl9ma8MozE9vtxHQVftuY6hRt+esCBdXA5jXcuCaCj+yUe4Akw+c5BPFNUF5vOTjQ== -react-native-screens@^2.8.0: +react-native-screens@2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.8.0.tgz#9f989096fc5ccf248e0dfa93a74f1a64057e15f1" integrity sha512-fUCIQLZX+5XB0ypWX038P3zso54IFFjTsQUZJWEsjC3pp5rPItAt5SzqtJn+uVjcJaczZ+dpIuvj6IFLqkWLZQ== @@ -5618,7 +5619,7 @@ react-native-splash-screen@3.2.0: resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#d47ec8557b1ba988ee3ea98d01463081b60fff45" integrity sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg== -react-native-vector-icons@^6.6.0: +react-native-vector-icons@6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-6.6.0.tgz#66cf004918eb05d90778d64bd42077c1800d481b" integrity sha512-MImKVx8JEvVVBnaShMr7/yTX4Y062JZMupht1T+IEgbqBj4aQeQ1z2SH4VHWKNtWtppk4kz9gYyUiMWqx6tNSw== @@ -5664,7 +5665,7 @@ react-native@0.62.2: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" -react-redux@^7.2.0: +react-redux@7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d" integrity sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA== @@ -5753,7 +5754,7 @@ reduce-reducers@^0.4.3: resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.4.3.tgz#8e052618801cd8fc2714b4915adaa8937eb6d66c" integrity sha512-+CNMnI8QhgVMtAt54uQs3kUxC3Sybpa7Y63HR14uGLgI9/QR5ggHvpxwhGGe3wmx5V91YwqQIblN9k5lspAmGw== -redux-actions@^2.6.5: +redux-actions@2.6.5: version "2.6.5" resolved "https://registry.yarnpkg.com/redux-actions/-/redux-actions-2.6.5.tgz#bdca548768ee99832a63910c276def85e821a27e" integrity sha512-pFhEcWFTYNk7DhQgxMGnbsB1H2glqhQJRQrtPb96kD3hWiZRzXHwwmFPswg6V2MjraXRXWNmuP9P84tvdLAJmw== @@ -5764,12 +5765,12 @@ redux-actions@^2.6.5: reduce-reducers "^0.4.3" to-camel-case "^1.0.0" -redux-thunk@^2.3.0: +redux-thunk@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== -redux@^4.0.5: +redux@4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== @@ -5995,11 +5996,6 @@ rimraf@~2.2.6: resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= -rn-placeholder@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/rn-placeholder/-/rn-placeholder-3.0.1.tgz#5073210e9d35791e379df9604414d3c6d531a3ee" - integrity sha512-hpJiCiNXMvljCaDFdjLATYmHaU2RZg8Nv+g/VaAdLzGIMlV7/pFxvR4B+tYd93iVOMbHuKDmfqGYobAlTHOVIw== - rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -7287,8 +7283,3 @@ yargs@^15.1.0, yargs@^15.3.1: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^18.1.1" - -yarn@^1.22.4: - version "1.22.4" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.4.tgz#01c1197ca5b27f21edc8bc472cd4c8ce0e5a470e" - integrity sha512-oYM7hi/lIWm9bCoDMEWgffW8aiNZXCWeZ1/tGy0DWrN6vmzjCXIKu2Y21o8DYVBUtiktwKcNoxyGl/2iKLUNGA==