ThangLuuQuoc / cinemapp

React native exercise about consume the TMDB API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CinemApp

React native exercise about consume the TMDB API.

This time I'm gonna make a faster (I hope) exercise with the TMDB API, which allow us to consume all the movie library in their database.

Initial tools

First of all, I need the main idea for the app, so, I drew an scratch on my notebook with my color pens.

As a result, now I know (with a high probability) what's I'm going to do.

enter image description here

Yes, is rustic, archaic maybe, but enough for my main purpose.

From the last image I can recognize the next elements:

  • Splash screen
  • Main screen
  • Basic movie screen
  • Extended movie screen

That's all, now, I would like to write some features for every screen, ir order to get more detail before start to write code.

Splash screen

Just an icon in the middle of the screen. Obviously, right now I'm thinking about what kind of animation I will do, but, I in this moment a prefer thinking in a basic non-animated version to think in a hundred of possibilities.

Main screen

This screen has access to the three categories for this example: Popular, Top rated, and Upcoming.

From here, the user can access to search a movie, and back to the main screen. I drew a link to profile, but, to be honest, I don't think I'll have time enough to do that, so, I'll remove it.

The user will see an horizontal scroll with the movies in this category as well. Every movie section has the official poster about the movie that it represent.

Basic movie screen

Basically, here I'll show the basics about the movie:

  • Poster
  • Ranking value
  • Title
  • Original title
  • Genres
  • Short description
  • Favorite button
  • Play trailer button
  • Extends data button

Extended movie screen

Similar to the last screen, but, here we can find:

  • Title
  • Release year
  • Stars ranking
  • Numeric ranking
  • Total votes
  • Complete description
  • Back button
  • Share button

I think that I'll make some changes, but I'll try to keep this structure. Also, from the beginning, I need to code thinking about the Animated API, in order to achieve them easier in the future.

Next step is to structure the application (in order to have clear how do I need to create my folders), but, I'm haven't time to make a nice digital graphic, so, I'll write it right here:

  • Main app (App.js)
    • Components
    • Assets
    • Screens
    • Providers

Components

This folder is going to have some little components for almost every part in the app. I'll try to encapsulate as many as I can.

Assets

Fonts, images, etc.

Screens

This is the place to keep the main interfaces, such as Splash, Main screen, Movie screens, etc.

Providers

This folder is going to have controllers in order to manage the internal database, http connections, and business logic.

First code commit

After add the first commit into the repository, I would like to remember what kind of libraries/resources I'm going to use in order to complete the app:

From the above list, there are two thinks that I've never used in React Native: the TMDb API, and the Youtube Component, so, I need to study a little bit about them.

Also I figured out that I've never worked with SQLite3 in React Native, but, after a little while reading the documentation, I realized that is exactly the same library I used to work with jQuery Mobile in many projects a few years ago, so, I need to take care about it because I don't want surprises with this technology.

Let's started to code.

First of all, I'm gonna make the basic structure and navigation system. Then, I'm gonna to add some details one at time.

I started with the TMDb API, so, I needed to make the registration process, and then, to request the API access in order to use the services.

That didn't hurt, and soon I started to make queries from Postman. So, at this time I get the data for the categories in the app:

Get upcoming

  • Popular api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=XXXX
  • Top rated api.themoviedb.org/3/discover/movie?sort_by=vote_average.desc&api_key=XXXX
  • Upcoming api.themoviedb.org/3/movie/upcoming?page=1&language=en-US&api_key=XXXX

The Discover API examples section in the documentation offer some useful snippets.

At this moment I realized that the JSON response seems not to have all the data that I need. For example, I can't find the Youtube URL to the video, and all the properties video are false.

I got all the general data that I need:

  • Votes
  • Title
  • Original title
  • Genres (at last the ID's). I don't know how to extract the name genres, by the way.
  • Poster
  • Average qualification
  • Description
  • Release date
  • There is a property called popularity. Right now, I don't what's that exactly.
  • Original language from the movie

Until now is enough for my purpose, excepto by the video link. I need to learn how to extract that information. Actually, It would be cool to extract the actors list, but I think that's is not a very good idea because I've don't even started to write any line.

After a while checking the forum, I found a good answer from (I think) the guy who give support to the API, but, it's not perfect, because I need to make a second query to get the video list:

api.themoviedb.org/3/movie/299536/videos?api_key=XXXX

enter image description here

Where 299536 is the movie ID. In this case, Avengers, infinity wars.

In the same answer, this guy said that we can add another parameter to our regular queries to get the videos in the same response, but it doesn't works, at least for me, so, I left that option for now.

Just for curiosity, I wrote images instead videos in the last URL, and then I got the list of images from that movie. Very useful option.

api.themoviedb.org/3/movie/299536/images?api_key=XXXX

One last query: Actors :)

To get the actors, I needed to write credits instead images in the last URL

api.themoviedb.org/3/movie/299536/credits?api_key=XXXX

This services give photo, name, role played, votes, votes average, and other properties, but I got enough information until now.

Now that I have all the data, I can, finally, code the Splash screen interface.

I would like to do the same animation effect that I have in my CV project at the intro, where I emulated a "fluid" integration between the Xcode splash screen, and my own react-native Splash screen.

After a little while, I got back to the action, and I finished a first release candidate for the Splash Animation.

Below I put a gif that shows how is going.

Basically, I applied the same idea in the previous project , where I used react-native-splash-screen plugin the handle a fluid splash screen experience, as I tried to explain it in the below graphic:

enter image description here

So, what just happened? Normally, this is the process:

  1. Xcode launch the regular Splash screen.
  2. After that, the Javascript bridge is started to load.
  3. React native load the first screen.

But thanks to the react-native-splash-screen plugin, I can "hide" the loading process of the bridge, and keep showing the natural Splash Screen from Xcode meanwhile the first screen from the RN project is loaded. So, the final process is:

  1. Xcode launch the regular Splash screen.
  2. JS Bridge (JSB) is started to load, and at the same time, keep showing the Xcode Splash screen.
  3. JSB finished the load, and hide Xcode Splash screen, and immediately, the first RN interfaces is loaded.

This behavior allows me give the user a great experience.

Then, I made an animation in order to create an app flow until the main interface.

Now, is time to create the main interface, and I have a idea that I want to implement.

After struggling with some things, I decided keep it as simple as I can, because I haven't time enough (you know, house chores and food doesn't make by itself), so, I made the minimal interface with basic components, like View, ScrollView, FlatList, Image, and Text:

After that, I started to think in an idea, not as simple, but not so complex, and, in a few minutes, I got the effect that I wanted at the beginning :)

I just turn the Views component to Animated.View, and I started to play with the height of the Main Movie:

<Animated.View style={{ width: screenWidth }}>
    <Animated.View style={{ height: this.mainMovieHeight }}>
        <Image source={require('./../assets/img/movie.jpg')} />
    </Animated.View>
    <Animated.View style={{ width: screenWidth }}>
        {
        data.map((item) => (
        <Animated.View key={item.id} style={{ backgroundColor: '#555555', height: 150 }}>
            <Text style={{
                                    fontFamily: 'ObliviousFont',
                                    fontSize: 15,
                                    left: 5,
                                    top: 3,
                                    color: 'white'
                                }}>
                {item.name}
            </Text>
            <View style={{ marginTop: 5 }}>
                <FlatList horizontal={true} data={moviesData} renderItem={({ item })=> (
                    <TouchableHighlight onPress={()=> this.onPressMovie()} style={{ marginLeft: 5, height: 150 }}>
                        <Image source={require('./../assets/img/movie_small.jpg')} />
                    </TouchableHighlight>
                    )}
                    />
            </View>
        </Animated.View>
        ))
        }
    </Animated.View>
</Animated.View>

As you can see, I got the mainMovieHeight variable controlling the height of the main movie.

When one movie is pressed, the main movie is expanded:

changeVariable(variable, v, delay) {
    return Animated.timing(
        variable, {
            toValue: v,
            duration: defaultTimeAnimation,
            delay: delay
        }
    );
}

onPressMovie = () => {
    this.changeVariable(this.mainMovieHeight, this.state.finalHeighMainMovie, 0).start();
}

Obviously, this is only a first test in order to make a clean version.

About

React native exercise about consume the TMDB API

License:MIT License


Languages

Language:JavaScript 63.7%Language:Objective-C 18.3%Language:Python 8.0%Language:Java 6.5%Language:Ruby 3.4%