Commit 5912ad32 authored by ErlendHer's avatar ErlendHer
Browse files

#10 bug: fix bug where css was bugged on mobile.

parent ffef5ee4
import React from 'react';
import React, { useEffect, useState } from 'react';
import { Image, StyleSheet, Text, View } from 'react-native';
import { AirbnbRating } from 'react-native-ratings';
import { MovieEntity } from '../store/ducks/movies/types';
import { Dimensions } from 'react-native';
interface MovieCardProps {
movie: MovieEntity;
}
const window = Dimensions.get('window');
const screen = Dimensions.get('screen');
/**
* Movie Card component
*/
const MovieCard = (props: MovieCardProps): JSX.Element => {
const { movie } = props;
const [dimensions, setDimensions] = useState({ window, screen });
const iw = () => {
return dimensions.window.width / 2 - 20;
};
const ih = () => {
return (dimensions.window.width / 2 - 20) * (443 / 300);
};
useEffect(() => {
Dimensions.addEventListener('change', ({ window, screen }) => {
setDimensions({ window, screen });
});
}, []);
return (
<View style={styles.card}>
<Image
source={{
uri: movie.poster,
}}
style={styles.poster}
resizeMode="contain"
style={[styles.poster, { width: iw(), height: ih() }]}
/>
<View style={styles.cardInfo}>
<View style={[styles.cardInfo, { maxWidth: iw() }]}>
<Text style={styles.titleText}>{movie.title}</Text>
<AirbnbRating
count={5}
......@@ -37,33 +55,37 @@ const MovieCard = (props: MovieCardProps): JSX.Element => {
const styles = StyleSheet.create({
poster: {
flex: 1,
minWidth: undefined,
height: undefined,
aspectRatio: 300 / 443,
borderTopLeftRadius: 5,
borderTopRightRadius: 5,
resizeMode: 'contain',
maxWidth: 300,
},
card: {
flex: 1,
backgroundColor: 'white',
flex: 1 / 2,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 4,
minWidth: 175,
boxShadow: '0 2px 4px 0 rgba(0,0,0,0.2)',
marginVertical: 4,
borderRadius: 5,
textAlign: 'center',
shadowColor: '#171717',
shadowOffset: { width: -2, height: 4 },
shadowOpacity: 0.2,
shadowRadius: 3,
elevation: 1,
},
titleText: {
textAlign: 'center',
fontWeight: 'bold',
},
cardInfo: {
padding: 4,
textAlign: 'center',
maxWidth: 175,
minHeight: 75,
},
rating: {
// maxWidth: 150,
},
});
export default MovieCard;
import React, { useEffect, useState } from 'react';
import { FlatList, StyleSheet, Text } from 'react-native';
import { FlatList, StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useDispatch, useSelector } from 'react-redux';
import { fetchMovies } from '../store/ducks/movies/actions';
......@@ -8,7 +8,7 @@ import { ApplicationState } from '../store/interface';
import MovieCard from './MovieCard';
const baseQuery: FetchMovieParams = {
perPage: 12,
perPage: 20,
page: 0,
orderBy: 'title',
order: 'desc',
......@@ -40,47 +40,65 @@ const MovieTable = ({ path }: { path: string }): JSX.Element => {
// Fetch movies on page change
useEffect(() => {
if (!error && !loading) {
console.log(movies);
setMovies([...movies, ...data]);
// Ensure that we don't add duplicate movies to the array
const moviesToAdd = [...movies];
data.forEach((movie: MovieEntity) => {
if (!moviesToAdd.some((m) => m.id === movie.id)) {
moviesToAdd.push(movie);
}
});
setMovies([...moviesToAdd]);
}
}, [data]);
return (
<FlatList
contentContainerStyle={styles.movieList}
data={movies}
numColumns={2}
keyExtractor={(movie) => movie.id}
onEndReached={({ distanceFromEnd }) => {
// Prevent bug where onEndReached is called multiple times
if (distanceFromEnd < 0) return;
// Prevent fetching if all movies are loaded
if (prevPageLoaded + 1 >= Math.ceil(documentCount / baseQuery.perPage))
return;
<View style={styles.movieList}>
<FlatList
style={{ width: '100%', height: '100%' }}
columnWrapperStyle={{ flex: 1, justifyContent: 'space-around' }}
contentContainerStyle={styles.movieItems}
data={movies}
numColumns={2}
keyExtractor={(movie) => movie.id}
onEndReached={({ distanceFromEnd }) => {
// Prevent bug where onEndReached is called multiple times
if (distanceFromEnd < 0) return;
// Prevent fetching if all movies are loaded
if (
prevPageLoaded + 1 >=
Math.ceil(documentCount / baseQuery.perPage)
)
return;
fetchByPage(prevPageLoaded + 1);
setPageLoaded(prevPageLoaded + 1);
}}
onEndReachedThreshold={0.5}
initialNumToRender={baseQuery.perPage}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => <MovieCard movie={item} />}
ListFooterComponent={() => (
<>{loading && <Text style={styles.loading}>Loading...</Text>}</>
)}
/>
fetchByPage(prevPageLoaded + 1);
setPageLoaded(prevPageLoaded + 1);
}}
onEndReachedThreshold={1.5}
initialNumToRender={baseQuery.perPage}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => <MovieCard movie={item} />}
ListFooterComponent={() => (
<>{loading && <Text style={styles.loading}>Loading...</Text>}</>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
movieItems: {
justifyContent: 'center',
flexGrow: 1 / 2,
backgroundColor: 'white',
},
movieList: {
marginTop: 8,
textAlign: 'center',
// justifyContent: 'center',
marginTop: 4,
width: '95%',
height: '100%',
display: 'flex',
flex: 1,
flexDirection: 'column',
gap: 8,
alignItems: 'center',
textAlign: 'center',
},
loading: {
fontWeight: 'bold',
......
......@@ -11,8 +11,10 @@ const composeEnhancers =
(window && (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
// Compose the redux store with necessary middlewares and states
export default function configureStore(initialState: ApplicationState): Store<ApplicationState> {
const middlewares = [thunk, sagaMiddleware, logger];
export default function configureStore(
initialState: ApplicationState
): Store<ApplicationState> {
const middlewares = [thunk, sagaMiddleware];
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment