Skip to content
Snippets Groups Projects
Commit d46f81b3 authored by Jon-Inge Heggstad's avatar Jon-Inge Heggstad
Browse files

Merge branch 'more-updates-to-readme' into 'master'

More updates to readme

See merge request !8
parents 521bc9a6 45119659
No related branches found
No related tags found
1 merge request!8More updates to readme
...@@ -63,7 +63,7 @@ By pressing one of the queried items, a third party component React-Navigation m ...@@ -63,7 +63,7 @@ By pressing one of the queried items, a third party component React-Navigation m
#### Sorting and filtration #### Sorting and filtration
The user can set parameters for sorting and filtration on the Home screen before typing in the search. If these options are set after the search is performed, the user will have to search again in order to make a new query. The user can set parameters for sorting and filtration on a modal accessed through the Home screen before typing in the search. If these options are set after the search is performed, the user will have to search again in order to make a new query.
### Technology and testing ### Technology and testing
...@@ -95,3 +95,7 @@ More information about our linter can be found at https://eslint.org/docs/user-g ...@@ -95,3 +95,7 @@ More information about our linter can be found at https://eslint.org/docs/user-g
#### Why we went for this solution #### Why we went for this solution
A linter is needed in order to ensure a robust codebase. Without it, we would be able to have poor code which would compile, but could have unforseen consequences during runtime. ESLint is configured for Typescript in this project. A linter is needed in order to ensure a robust codebase. Without it, we would be able to have poor code which would compile, but could have unforseen consequences during runtime. ESLint is configured for Typescript in this project.
### Development process
During the development of P4 both group members felt that we lacked knowledge regarding the functionality implemented by the other member. The reason for this was that during P3, one of us primarily worked on the back-end and redux, while the other handled the front-end. As a result of this, pair-programming was extensively used both while refactoring the back-end and redux, and developing the new React-Native application. Due to lack of time, and a lacking understanding of how to use redux with Typescript. The application we made in P3 had a lot of bugs and illogical handling of state. We only realized this after the fact. Refactoring the code allowed us to fix this, as well as reworking how we handled requests in the back-end. This resulted in the front-end developer getting a much better understanding of what was going on under the hood. Pair-programming on React Native also gave valuable insight to the back-end developer on how to make decent components in a React(/Native) application.
...@@ -10,6 +10,7 @@ import Home from "./app/views/Home.component"; ...@@ -10,6 +10,7 @@ import Home from "./app/views/Home.component";
import { MovieDetail } from "./app/views/MovieDetail.component"; import { MovieDetail } from "./app/views/MovieDetail.component";
import { ReviewList } from "./app/views/ReviewList.component"; import { ReviewList } from "./app/views/ReviewList.component";
// We use the navigator component to allow for easy navigation inside of our application.
const Stack = createStackNavigator<StackParamList>(); const Stack = createStackNavigator<StackParamList>();
const App: React.FC = (): JSX.Element => { const App: React.FC = (): JSX.Element => {
......
...@@ -2,5 +2,5 @@ import axios from "axios"; ...@@ -2,5 +2,5 @@ import axios from "axios";
// You will need to set this to your ip address when running. This is the only variable that has to be changed. // You will need to set this to your ip address when running. This is the only variable that has to be changed.
export default axios.create({ export default axios.create({
baseURL: "http://[2001:700:300:4100:597c:4fc9:563a:9e28]:3001", baseURL: "http://192.168.0.62:3001",
}); });
...@@ -4,6 +4,13 @@ import { movieSlice } from "../slices/movieSlice"; ...@@ -4,6 +4,13 @@ import { movieSlice } from "../slices/movieSlice";
import { reviewSlice } from "../slices/reviewSlice"; import { reviewSlice } from "../slices/reviewSlice";
import { systemSlice } from "../slices/systemSlice"; import { systemSlice } from "../slices/systemSlice";
/**
* store contains the redux configuration and is a combination of all the states, actions and reducers made in slices.
* Access to following:
* @constructs movieSlice
* @constructs reviewSlice
* @constructs systemSlice
*/
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
movies: movieSlice.reducer, movies: movieSlice.reducer,
...@@ -12,6 +19,8 @@ export const store = configureStore({ ...@@ -12,6 +19,8 @@ export const store = configureStore({
}, },
}); });
// We need to create a type for typescript.
export type AppState = ReturnType<typeof store.getState>; export type AppState = ReturnType<typeof store.getState>;
// We export the dispatching of our store in order to effectively use it in our components.
export const useAppDispatch = () => useDispatch<typeof store.dispatch>(); export const useAppDispatch = () => useDispatch<typeof store.dispatch>();
...@@ -18,11 +18,13 @@ export interface Movie { ...@@ -18,11 +18,13 @@ export interface Movie {
rating: number; rating: number;
} }
// Type of the state found in the store
type MovieState = { type MovieState = {
searchTerm: string; searchTerm: string;
movies: Array<Movie>; movies: Array<Movie>;
}; };
// Our slices, this is essentially a combination of our state, reducers and actions found in our store.
export const movieSlice = createSlice({ export const movieSlice = createSlice({
name: "movie-slice", name: "movie-slice",
initialState: { initialState: {
......
...@@ -8,10 +8,12 @@ export interface Review { ...@@ -8,10 +8,12 @@ export interface Review {
review: string; review: string;
} }
// Type of the state found in the store
type ReviewState = { type ReviewState = {
reviews: Array<Review>; reviews: Array<Review>;
}; };
// Our slices, this is essentially a combination of our state, reducers and actions found in our store.
export const reviewSlice = createSlice({ export const reviewSlice = createSlice({
name: "review-slice", name: "review-slice",
initialState: { initialState: {
......
import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// State user for pagination and other system variables // Base model for out system state
export interface System { export interface System {
count: number; count: number;
} }
// Type of the state found in the store
type SystemState = { type SystemState = {
count: number; count: number;
}; };
// Our slices, this is essentially a combination of our state, reducers and actions found in our store.
export const systemSlice = createSlice({ export const systemSlice = createSlice({
name: "system-slice", name: "system-slice",
initialState: { initialState: {
......
import React, { useEffect, useState } from "react"; import React, { useState } from "react";
import { View, FlatList, StyleSheet } from "react-native"; import { View, FlatList, StyleSheet } from "react-native";
import axios from "axios"; import axios from "axios";
import { AppState, useAppDispatch } from "../store/redux/store"; import { AppState, useAppDispatch } from "../store/redux/store";
import { SearchHandler } from "../components/SearchHandler.component"; import { SearchHandler } from "../components/SearchHandler.component";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { ListItem } from "react-native-elements";
import api from "../api"; import api from "../api";
import { Movie, movieSlice } from "../store/slices/movieSlice"; import { Movie, movieSlice } from "../store/slices/movieSlice";
import { systemSlice } from "../store/slices/systemSlice";
import { MovieListItem } from "./MovieListItem.component"; import { MovieListItem } from "./MovieListItem.component";
import { sys } from "typescript";
const Home: React.FC = (): JSX.Element => { const Home: React.FC = (): JSX.Element => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
...@@ -19,7 +16,9 @@ const Home: React.FC = (): JSX.Element => { ...@@ -19,7 +16,9 @@ const Home: React.FC = (): JSX.Element => {
const count = useSelector((state: AppState) => state.system.count); const count = useSelector((state: AppState) => state.system.count);
const [refreshing, setRefreshing] = useState(false); const [refreshing, setRefreshing] = useState(false);
// This does not work, dispatch is async, so we will have to rework pagination. The list works.
// As it stands, this simply clear the movie page, implemented in case anything gets bugged.
// The intended use of this function doesn't really make sense in a movie DB
const refreshMovies = () => { const refreshMovies = () => {
setRefreshing(true); setRefreshing(true);
dispatch(movieSlice.actions.clearMovies()); dispatch(movieSlice.actions.clearMovies());
...@@ -42,8 +41,6 @@ const Home: React.FC = (): JSX.Element => { ...@@ -42,8 +41,6 @@ const Home: React.FC = (): JSX.Element => {
.catch((e) => console.log(e)); .catch((e) => console.log(e));
}; };
// TODO: add useEffect to re-render on state change?
return ( return (
<View style={styles.container}> <View style={styles.container}>
<SearchHandler /> <SearchHandler />
...@@ -55,7 +52,7 @@ const Home: React.FC = (): JSX.Element => { ...@@ -55,7 +52,7 @@ const Home: React.FC = (): JSX.Element => {
ItemSeparatorComponent={() => <View></View>} ItemSeparatorComponent={() => <View></View>}
refreshing={refreshing} refreshing={refreshing}
onRefresh={refreshMovies} onRefresh={refreshMovies}
onEndReached={fetchMoreMovies} onMomentumScrollEnd={() => fetchMoreMovies()}
/> />
</View> </View>
</View> </View>
......
...@@ -22,8 +22,10 @@ const MovieDetail = (): JSX.Element => { ...@@ -22,8 +22,10 @@ const MovieDetail = (): JSX.Element => {
const navigation = useNavigation<ReviewScreenNavigationProp>(); const navigation = useNavigation<ReviewScreenNavigationProp>();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
// We get the movie from the navigation component when a user clicks on it
const { movie } = route.params; const { movie } = route.params;
// Fetch all the reviews for the movie
const showReviews = async () => { const showReviews = async () => {
axios axios
.get(`${api.defaults.baseURL}/reviews/${movie.Column_1}`) .get(`${api.defaults.baseURL}/reviews/${movie.Column_1}`)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment