Commit c449c05c authored by ErlendHer's avatar ErlendHer
Browse files

#15 add more sound loading spinner logic and fix css errors.

parent 1afca964
......@@ -59,7 +59,7 @@ const FilterPane: React.FC<FilterPaneProps> = ({
const styles = StyleSheet.create({
container: {
marginTop: 96,
marginTop: 8,
marginHorizontal: 16,
width: '95%',
display: 'flex',
......
import { StatusBar } from 'expo-status-bar';
import * as React from 'react';
import { Platform, StyleSheet, Image, useWindowDimensions, Button, ScrollView } from 'react-native';
import {
Button,
Image,
ScrollView,
StyleSheet,
useWindowDimensions,
} from 'react-native';
import Lord from '../assets/images/lord.jpg';
import { MovieDetail } from '../models/movieDetail.model';
import ProfileInfo from './ProfileInfo';
import { Text, View } from './Themed';
import Lord from "../assets/images/lord.jpg";
import { movies } from '../store/ducks/movies';
import KeyStatisticsItem from './KeyStatisticsItem';
import Seperator from './Seperator';
import Pill from './Pill';
import WrapperStatistic from 'antd/lib/statistic/Statistic';
import Seperator from './Seperator';
import { Text, View } from './Themed';
interface MovieDetailProps {
movieDetail: MovieDetail;
}
export default function MovieDetailScreen({movieDetail}: MovieDetailProps) {
const {height} = useWindowDimensions();
export default function MovieDetailScreen({ movieDetail }: MovieDetailProps) {
const { height } = useWindowDimensions();
const styles = StyleSheet.create({
root: {
......@@ -28,10 +30,10 @@ export default function MovieDetailScreen({movieDetail}: MovieDetailProps) {
height: 350,
},
container: {
width: "100%",
width: '100%',
padding: 15,
marginVertical: 5,
alignItems: "center",
alignItems: 'center',
borderRadius: 5,
},
subText: {
......@@ -45,98 +47,101 @@ export default function MovieDetailScreen({movieDetail}: MovieDetailProps) {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'flex-start'
alignItems: 'flex-start',
},
genres: {
flex: 1,
flexWrap: "wrap",
flexDirection: "row",
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
marginTop: 15,
paddingBottom: "1rem",
}
})
paddingBottom: '1rem',
},
});
return (
<ScrollView style={styles.root}>
<View style={{alignItems: "center"}}>
<Image source={Lord} style={[styles.logo, {height: height*0.5}]} resizeMode="contain"/>
</View>
<View style={{alignItems: "center"}}>
Stars -{'>'} To be implemented
</View>
<View>
<Button onPress={() => console.log("To be implemented")} title={"Give a rating"}/>
</View>
<View style={styles.key_number_container}>
<KeyStatisticsItem title="RUNTIME" statistics={String(movieDetail.runtime)}/>
<KeyStatisticsItem title="IMDG-RATING" statistics={String(movieDetail.avgRating)}/>
<KeyStatisticsItem title="RATING" statistics={String(movieDetail.avgRating)}/>
<KeyStatisticsItem title="PGA-RATING" statistics={String(movieDetail.avgRating)}/>
</View>
<Seperator/>
<View>
<Text style={{fontSize: 22}}>
{movieDetail.year}
</Text>
<Text style={{fontSize: 18}}>
{movieDetail.title}
</Text>
<View style={styles.genres}>
{movieDetail.genres.map((genre) => <Pill text={genre}>genre</Pill>)}
</View>
</View>
<Seperator/>
<Text>
{movieDetail.plot}
</Text>
<Seperator/>
{LabelAndText("DIRECTORS", "Joshua King")}
<Seperator/>
{LabelAndText("PRODUCTION", "Paramount Pictures, W365")}
<Seperator/>
{LabelAndText("WRITERS", "Phil Hay, Matt Manfredi, Peter Chung")}
<Seperator/>
{LabelAndText("STARRING ACTORS", "Charlize Theron, Frances McDormand, Sophie Okonedo")}
<Seperator/>
<View style={{ alignItems: 'center' }}>
<Image
source={Lord}
style={[styles.logo, { height: height * 0.5 }]}
resizeMode="contain"
/>
</View>
<View style={{ alignItems: 'center' }}>
Stars -{'>'} To be implemented
</View>
<View>
<Button
onPress={() => console.log('To be implemented')}
title={'Give a rating'}
/>
</View>
<View style={styles.key_number_container}>
<KeyStatisticsItem
title="RUNTIME"
statistics={String(movieDetail.runtime)}
/>
<KeyStatisticsItem
title="IMDG-RATING"
statistics={String(movieDetail.avgRating)}
/>
<KeyStatisticsItem
title="RATING"
statistics={String(movieDetail.avgRating)}
/>
<KeyStatisticsItem
title="PGA-RATING"
statistics={String(movieDetail.avgRating)}
/>
</View>
<Seperator />
<View>
<Text style={{ fontSize: 22 }}>{movieDetail.year}</Text>
<Text style={{ fontSize: 18 }}>{movieDetail.title}</Text>
<View style={styles.genres}>
{movieDetail.genres.map((genre) => (
<Pill text={genre}>genre</Pill>
))}
</View>
</View>
<Seperator />
<Text>{movieDetail.plot}</Text>
<Seperator />
{LabelAndText('DIRECTORS', 'Joshua King')}
<Seperator />
{LabelAndText('PRODUCTION', 'Paramount Pictures, W365')}
<Seperator />
{LabelAndText('WRITERS', 'Phil Hay, Matt Manfredi, Peter Chung')}
<Seperator />
{LabelAndText(
'STARRING ACTORS',
'Charlize Theron, Frances McDormand, Sophie Okonedo'
)}
<Seperator />
<View>
Reviews -{'>'} To be implemented
</View>
<View>Reviews -{'>'} To be implemented</View>
</ScrollView>
);
}
function LabelAndText(label: string, text: string){
const styles= StyleSheet.create({
function LabelAndText(label: string, text: string) {
const styles = StyleSheet.create({
label: {
textTransform: "capitalize",
fontWeight: "bold",
textTransform: 'capitalize',
fontWeight: 'bold',
marginRight: 5,
},
container: {
flex: 1,
flexWrap: "wrap",
flexDirection: "row",
}
})
flexWrap: 'wrap',
flexDirection: 'row',
},
});
return(
return (
<View style={styles.container}>
<Text style={styles.label}>
{label}:
</Text>
<Text>
{text}
</Text>
<Text style={styles.label}>{label}:</Text>
<Text>{text}</Text>
</View>
)
}
\ No newline at end of file
);
}
import React, { useEffect, useState } from "react";
import { FlatList, StyleSheet, Text, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { useSelector } from "react-redux";
import { FetchMovieParams, MovieEntity } from "../store/ducks/movies/types";
import { ApplicationState } from "../store/interface";
import MovieCard from "./MovieCard";
import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
FlatList,
StyleSheet,
Text,
View,
} from 'react-native';
import { useSelector } from 'react-redux';
import { FetchMovieParams, MovieEntity } from '../store/ducks/movies/types';
import { ApplicationState } from '../store/interface';
import MovieCard from './MovieCard';
export type MovieTableProps = {
path: string;
query: FetchMovieParams;
movies: MovieEntity[];
currentPage: number;
moviesLoading: boolean;
onPageScroll: () => void;
};
......@@ -18,59 +24,95 @@ const MovieTable: React.FC<MovieTableProps> = ({
path,
query,
movies,
moviesLoading,
currentPage,
onPageScroll,
}: MovieTableProps) => {
const { data, documentCount, loading, error } = useSelector(
const { documentCount } = useSelector(
({ movies }: ApplicationState) => movies
);
const [isFull, setIsfull] = useState(false);
useEffect(() => {
setIsfull(!(movies.length < documentCount));
}, [movies]);
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 (currentPage >= Math.ceil(documentCount / query.perPage)) return;
// Dispatch scroll event to parent component
onPageScroll();
}}
onEndReachedThreshold={1.5}
initialNumToRender={query.perPage}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => <MovieCard movie={item} />}
ListFooterComponent={() => (
<>{loading && <Text style={styles.loading}>Loading...</Text>}</>
)}
/>
{movies.length > 0 || moviesLoading ? (
<FlatList
style={styles.movieFlatList}
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 (currentPage >= Math.ceil(documentCount / query.perPage)) {
setIsfull(true);
return;
}
setIsfull(false);
// Dispatch scroll event to parent component
onPageScroll();
}}
onEndReachedThreshold={1.5}
initialNumToRender={query.perPage}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => <MovieCard movie={item} />}
ListFooterComponent={() => (
<>
{!isFull ? (
<>
<Text style={styles.loading}>Loading...</Text>
<ActivityIndicator size="large" color="#00ff00" />
</>
) : (
<>
{movies.length > 4 && (
<Text style={styles.loading}>--- No more movies ---</Text>
)}
</>
)}
</>
)}
/>
) : (
<Text style={styles.loading}>No Movies Found</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
movieItems: {
justifyContent: "center",
justifyContent: 'center',
flexGrow: 1 / 2,
backgroundColor: "white",
backgroundColor: 'white',
},
movieFlatList: {
width: '100%',
height: '100%',
marginBottom: 4,
},
movieList: {
marginTop: 4,
width: "95%",
height: "95%",
display: "flex",
alignItems: "center",
textAlign: "center",
width: '95%',
height: '95%',
alignItems: 'center',
textAlign: 'center',
flex: 1,
},
loading: {
fontWeight: "bold",
marginBottom: 8,
flex: 1,
fontSize: 20,
fontWeight: 'bold',
marginBottom: 16,
textAlign: 'center',
},
});
......
import React, { useState, useEffect, useCallback } from "react";
import { StyleSheet } from "react-native";
import { useDispatch, useSelector } from "react-redux";
import FilterPane, { FilterPaneProps } from "../components/FilterPane";
import React, { useState, useEffect, useCallback } from 'react';
import { StyleSheet } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import FilterPane, { FilterPaneProps } from '../components/FilterPane';
import MovieTable, { MovieTableProps } from "../components/MovieTable";
import { View } from "../components/Themed";
import MovieTable, { MovieTableProps } from '../components/MovieTable';
import { View } from '../components/Themed';
import {
FilterKeys,
FilterValues,
SortDirection,
SortKeys,
} from "../constants/filterOptions/interface";
import { fetchMovies } from "../store/ducks/movies/actions";
} from '../constants/filterOptions/interface';
import { fetchMovies } from '../store/ducks/movies/actions';
import {
FetchMovieParams,
initialQuery,
MovieEntity,
} from "../store/ducks/movies/types";
import { ApplicationState } from "../store/interface";
import { RootTabScreenProps } from "../types";
} from '../store/ducks/movies/types';
import { ApplicationState } from '../store/interface';
import { RootTabScreenProps } from '../types';
export default function MovieTableScreen({
navigation,
}: RootTabScreenProps<"Movies">) {
}: RootTabScreenProps<'Movies'>) {
const dispatch = useDispatch();
const [currentPage, setCurrentPage] = useState<number>(1);
const [movies, setMovies] = useState<MovieEntity[]>([]);
const [query, setQuery] = useState<FetchMovieParams>(initialQuery);
const [moviesLoading, setMoviesLoading] = useState<boolean>(false);
const { data, loading, error } = useSelector(
({ movies }: ApplicationState) => movies
......@@ -50,6 +51,7 @@ export default function MovieTableScreen({
});
setMovies([...moviesToAdd]);
}
setMoviesLoading(false);
// Reset loaded content when component unmounts
return () => {
setMovies([]);
......@@ -60,6 +62,7 @@ export default function MovieTableScreen({
// Update the query state with new values
// Reset pagination increments and loaded movies, if reset is true
function updateQuery(newQuery: FetchMovieParams, reset = true) {
setMoviesLoading(true);
let { page, ...other } = newQuery;
if (reset) {
setMovies([]);
......@@ -117,10 +120,11 @@ export default function MovieTableScreen({
// Map properties to the movie table component
const mapStateToMovieTableProps: MovieTableProps = {
path: "/screens/TabOneScreen.tsx",
path: '/screens/TabOneScreen.tsx',
query,
movies,
currentPage,
moviesLoading,
onPageScroll: useCallback(() => handlePageScroll(), [query]),
};
......@@ -135,19 +139,18 @@ export default function MovieTableScreen({
const styles = StyleSheet.create({
container: {
flex: 1,
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
width: "100%",
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
},
title: {
fontSize: 20,
fontWeight: "bold",
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: "90%",
width: '90%',
},
});
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