A movie info mobile app that displays a list of movies from The Movie Database (TMDb) API. The app shows top movies for each year and users can filter by genre, the app also loads top movies from next years as the user scrolls through the list.
Make sure you have completed the React Native - Environment Setup instructions till "Creating a new application" step, before proceeding to run the application.
Preferences used:
- React Native CLI
- Development OS:
macOS
- Target OS:
Android
- Package manager:
yarn
- Open terminal on your system and navigate to directory where you want to clone the project
- Run this command
git clone https://github.com/Ramanpreet6262/Moviefix.git
- Navigate inside the project directory created
cd Moviefix
- And run this command to install the dependencies
yarn install
First, you will need to start Metro, the JavaScript bundler that ships with React Native.
To start Metro, run the following command from the root of your React Native project:
yarn start
Let Metro Bundler run in its own terminal. Open a new terminal from the root of your React Native project. Run the following command to start your Android app:
yarn android
Note: Haven't tested for IOS yet so not sure whether it will work there or not
If everything is set up correctly, you should see the app running in your Android Emulator shortly provided you have set up your emulator correctly.
And if app doesn't run and metro server is showing options to select from like these: (ideally this should not happen and it will auto run android but just in case)
i - run on iOS
a - run on Android
d - open Dev Menu
r - reload app
Press a
to run on Android
You've successfully run the app on your local machine. 🥳
- Layout and UI is made keeping figma prototype as an inspiration
- Movies are displayed sorted in descending order of popularity and meta data info is shown on each card
- Movies are shown grouped year wise and by default list starts from 2012 with 20 movies for each year
- Only single direction scroll to load more movies is working i.e. load movies of next year when user scrolls down until the current year
- API integration is done with APIs from TMDB
- Filtering functionality and UI basis selection of one or more genres is in place. (Using OR logic if multiple genres are selected)
- Have used restyle by shopify to create theme and UI components
- Used TypeScript
- Implemented in React Native
- Smooth scrolling is working (But if users scrolls very fast and data for next year is not fetched yet so then user can see a loader at bottom)
- Search movie functionality
- Bi-directional scroll
- Skeleton loaders can be added
- No data component with image/gif
- Better Error component with image/gif
- Further optimising scrolling by prefetching data for next year
- Setup and run the project for IOS enviornment as well
- Addition of unit, integration and E2E tests
- Addition of CI CD pipelines to improve dev exp and productivity
- Whenever
onStartReached
callback is called and new data is appened at the start of the list that is brought from the API, list re renders to show the data from very start and in this wayonStartReached
keeps hitting resulting in an infinite loop of calling previous year APIs. - A similar issue is open in React native repository as well from quite some time now
- Though I tried some tweaks to make it work but to no avail. Spent some time here but didn't dive deep much due to time constraints and limited bandwidth available.
- I know better solutions exist then React Native's FlatList & SectionList. One of the popular and performant library is FlashList, it also offers SectionList and my initial plan was to use this only. References to support my take: Shopify blog, Tweet, Tweet
- But didn't go ahead with this as it doesn’t support bi-directional scroll (It is built on top of recyclerlistview and that uses quite old version of react native under the hood and this functionality of
onStartReached
came in Virtualised list of React native in0.72
version recently) and I didn't have bandwidth to build custom solution though it didn't work with default React Native implementation as well 🙈