kodflix's People
kodflix's Issues
Add the TV show title overlay on hover-over
The TV show covers introduced on #2 look great, but some users are struggling to identify certain shows by just looking at the cover.
Our UX department suggests to add a show title overlay on hover over
image
https://www.kodiri.com/platform/videos/kodflix/5c16e627a008e40e25252f55
Add synopsis & cover to the details page of each TV show
https://github.com/rmallols/kodflix/issues/16
We're already displaying the TV show title on the details page of each TV show.
Let's add now the synopsis and the cover. It's also a good opportunity to keep improving our UI, so please play around with background & font colors, gutters, etc
Bonus: Please look after the mobile layout!
https://kodiri.com/platform/videos/kodflix/5c2fa7f91f00fb0ef12a2bb4
Technical guidance:
-
Add a
synopsis
attribute to each entry on the list of shows. Fill them with some relevant info. -
Display the
synopsis
(left) andimage
(right) on theDetails
component, followingflexbox
guidelines:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/ -
Re-arrange the layout for mobile, using
media queries
e.g. by simply switching fromdisplay: flex
todisplay: block
https://www.w3schools.com/Css/css_rwd_mediaqueries.asp
You can also add some gutters:
https://www.w3schools.com/cssref/pr_padding.asp -
On the main CSS file (
App.css
) set a generic font and background colour for the rootbody
tag
https://www.w3schools.com/cssref/pr_text_color.asp
https://www.w3schools.com/cssref/pr_text_color.asp
Improve the gallery layout
At the moment, our gallery layout comes at 2 flavours:
desktop: 3 covers per row
mobile: 1 cover per row
That's fine, however users with large screens (e.g. UHD, 4K) are telling us cover look too large, so they'd like to have elements sharing the same container
https://kodiri.com/platform/videos/kodflix/5c23d644fb815c3bd5592389
Hint: Simplify the layout by keeping all the covers on a single row. Then, play around with the flex-wrap and flex-basis attributes
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
BONUS: We don't necessarily expect to end up having the same size for every cover. This is a limitation of the CSS flex model, which can be handled with the very new grid system:
https://medium.com/samsung-internet-dev/common-responsive-layouts-with-css-grid-and-some-without-245a862f48df
Run frontend and backend servers in parallel
https://github.com/rmallols/kodflix/issues/21
We still need two commands to startup frontend and backend servers:
- frontend:
npm start
. - backend:
npm start-backend
.
We want to start both servers using a single command using npm
.
Technical guidance:
-
At the moment, both servers are running on the same URL (on port 3000). We have to change one of the ports as we cannot have multiple servers running on the same port at the same time. Hence, replace the port on
app.js
, from3000
to3001
. -
Install npm-run-all. Note the changes on
package.json
-
Create a new task
start-all
onpackage.json
to run both npm tasks in parallel:npm-run-all -p <task1> <task2>
.
...
"scripts": {
...
"start-all": "npm-run-all..."
...
"}"
...
- Prove both servers work:
http://localhost:3000
-> We get the frontend server, with the TV show covershttp://localhost:3001
-> We get the backend server, with the TV show data
Please note, at this stage both servers are still disconnected. That means, data is not coming to the frontend from the backend. But that's fine, will connect both servers shortly.
Improve setup of backend server
https://github.com/rmallols/kodflix/issues/20
Up until now, the setup of the backend server has two main issues:
-
Changes aren't 'hot-reloaded'. That means, every time we introduce a change on the backend code, we are forced to restart the server.
-
We have to manually type a very long, error prone command to start up the server (
node src/backend/...
Please introduce the necessary changes to get rid / minimise these issues, in order to get our productivity improved.
Technical guidance:
-
To bring hot reloading to our backend JavaScript, we have to install a tool like nodemon. Then, by replacing
node
withnodemon
on the startup command, we'll get our changes automatically reloaded by refreshing the browser, so we won't have to restart the server every time. -
All our commands should be based on
npm
, which quickly became the industry standard. How to run scripts with npm. So just create a new script onpackage.json
calledstart-backend
, and assign the command we've been manually typing to start the backend server.
Hence, from now on, to start the backend server, we'll just have to runnpm run start-backend
.
Replace the TV show frontend data source, with the backend one
https://github.com/rmallols/kodflix/issues/24
We are ready to fully replace the TV show data source, from the frontend to the backend. This will notably facilitate future tasks, like e.g. database integration.
Please apply the necessary changes on both the Gallery
and Details
components.
Technical guidance:
1. Introduce state
on the Gallery
component, like we did on #13. Save the array of shows
we were already retrieving from the backend. Update the loop on the render
method to display the shows from the new state, rather than from the external getShows
module.
2. With these changes, we haven't solved the problem of displaying the TV cover yet. Historically speaking, we literally imported them on the frontend (e.g. import breakingBad from './cover/images/breaking-bad
. This created a big (huge!) string with the image content. As we are now delivering the content from the backend, we shouldn't do that any more. Data fetched from the backend should be simple & easy to manage. Hence, from now on on the Cover
component we'll figure out the image resource based on its id:
<img src={require(`<path-to-image>`)} alt='' />
The path will be dynamic, based on the image id
. But we can easily solve this problem by using the new and shiny template interpolation mechanism
If an image doesn't load, please ensure the name of the image file matches its corresponding id
.
3. Time to follow the very same principle on the Details
component (remember, when we click on any cover). Let's recap how the logic worked here:
- If the TV show was found (based on its
id
), then display the show details - If not, then redirect to a
not-found
page.
This is still valid, but there's a subtle (but very important) thing to note. Now the data will arrive from the backend, asynchronously. This is a very important principle in the JavaScript world. (Almost) nothing is 'immediate', it may take a while to be available (imagine you're checking the app on the phone, with poor broadband speed. Because of that, by definition TV shows will never be immediately available, so we'd always redirect to the not-found
page. To amend that, the logic should look like:
- If the TV show exists:
- If it's empty (that means, it doesn't have any property on it yet), we can assume the request to the backend is still in progress -> Do nothing here, just show an empty
div
. We'll see shortly how to handle loading situations accordingly. - If it's been filled (that means, the backend already facilitated its details), then display the show details.
- If it's empty (that means, it doesn't have any property on it yet), we can assume the request to the backend is still in progress -> Do nothing here, just show an empty
- If not, then redirect to a
not-found
page.
4. Prove everything still works as expected. If so, just delete the list of shows we originally set on the frontend (#12)
Bonus:
The images are being accessed from multiple components (Cover
and Details
, but you can imagine the list will probably grow). Hence, it'd be great to refactor the folder structure a bit.
Please create a new src/frontend/common/images
folder, and obviously ensure the path to the images on Cover
and Details
is correctly amended.
Replace TV show titles with covers
Depends on: #3
So OK, we can identify TV shows by their title, but the user interface isn't really appealing. That's what we want to replace them with the corresponding covers.
Display them in 2 rows (3 covers per row). All the covers will have the same size (width & height).
image
https://www.kodiri.com/platform/videos/kodflix/5c16e081e07a520e099fc6c0
https://github.com/rmallols/kodflix/issues/2
Deploy kodflix to production!
https://github.com/rmallols/kodflix/issues/17
Historically speaking, all the feedback we've received came from our internal / beta customers.
They're quite happy with the current state of the art, so now it's time to make kodflix publicly available!
That would imply we'll have a public URL access, so everybody around the world could check it.
https://kodiri.com/platform/videos/kodflix/5c2fac094f8a290eb464a545
Technical guidance:
We'll deploy our applications to the cloud using Heroku
https://www.heroku.com
It's a very popular framework, with really nice docs and extensive community support.
On top of that, it's free for personal projects, with some limitations (e.g. apps tend to 'sleep', which means first time you access it after a period of inactivity, it'll take few seconds to respond).
Setup process will just take few minutes.
- Sign up on Heroku: https://signup.heroku.com/
- Follow the getting started guide until the
Deploy the app
step: https://devcenter.heroku.com/articles/getting-started-with-nodejs
Please ignore thePrepare the app
step - your app is already prepared indeed :).
Hint: On the last step (Deploy the app
) we'll create our app into the cloud. The default command the guide suggests is heroku create
. As per described, it will create our app with a random name so we'd suggest to set an appropriate name straight away, e.g. heroku create your-app-name
Also note you cannot use kodflix
(heroku create kodflix
) as an app name since it's been already taken (by me :)) so feel free to use any personal naming conventions you feel comfortable with, e.g. heroku create kodflix-yourName
From now on, you can decide where to push your changes:
git push origin master
-> changes will be persisted on your GitHub accountgit push heroku master
-> changes will be published
You can trigger both commands from Visual Studio (... -> Push To...
)
The sample app has been already deployed:
https://kodflix.herokuapp.com/
Create a Gallery component to show the covers
Now we already know how to create components, so let's keep refactoring our app.
It's now time to move the list of covers to it's specific component (Gallery).
This will help with routing / navigation on the next steps
https://kodiri.com/platform/videos/kodflix/5c1ad86701df830e144d976b
Introduce routing / navigation
Depends on #9
We want to allow users clicking on each cover to navigating to the details page.
The goal here is to prove we can change the URL address by clicking on each cover.
URLs must be unique, but the targeted content will be the same (for now).
So,
Original url address: http://localhost:3000/
New url address (when clicking on any cover): http://localhost:3000/details
Content of the new url address: Hello, this will be the details page for each Movie & TV show :)
image
image
https://kodiri.com/platform/videos/5c1add26d0f7e90e08832429/play
Technical guidance:
How to manage routing with React:
https://facebook.github.io/create-react-app/docs/adding-a-router
https://reacttraining.com/react-router/web/example/basic
Hint: Create a new component (Details) to host the content of the new url address
Introduce a back-end server
https://github.com/rmallols/kodflix/issues/18
Up until now, the npm start
we've running on a daily basis managed to start up what we called the 'frontend server', which has been useful to provide browser-oriented content (JavaScript, HTML, CSS, images, etc).
Now, we'd like to start talking about the 'backend server'. That means, running JavaScript 'behind a wall' via Node.js to:
- Enable security (stuff running in the browser is not safe enough!)
- Allow integration with third party components (e.g. to saving our list of shows in a database).
The full setup of the backend server will take few steps. For now, let's start simple.
-
Let's create a logic folder structure. Move all the files and folder inside the
src
folder (exceptindex.js
andindex.css
) to a newsrc/frontend
folder. Please note you may have to amend some module imports onindex.js
to match with the new folder layout. -
Prove everything still works as expected.
-
Install Express.js:
npm install express --save
. Note the changes onpackage.json
-
Create a new folder,
src/backend
. Add a new file on it,app.js
. It will be our entry point for the backend JavaScript from now on. -
Set
app.js
with the 'hello world' example provided by Express:
https://expressjs.com/en/starter/hello-world.html -
Stop the frontend server (e.g. pressing
ctrl+c
) and start the backend one running:node src/backend/app.js
-
Refresh the browser and check you get a
Hello world
message:
Keep a unique details URL for each TV show
At the moment, the details page for every TV show share the same URL (http://localhost:3000/details)
This makes impossible to distinguish across multiple shows (how will we know which content is expected to be shown?).
Based on that, now it's time to set unique URLs for each show by:
Set and id (alongside the existing title and image
Redirect to http://localhost:3000/ when user clicks on the cover
image
image
https://kodiri.com/platform/videos/kodflix/5c23d62cfb815c3bd5592388
Enable the backend server in prod
https://github.com/rmallols/kodflix/issues/23
Push the recent changes to prod: git push heroku master
.
Running two Node.js servers in parallel is fine locally, but it's not allowed on Heroku. In other words, we have to merge them into a single server (with a single port).
Technically speaking, we want to achieve this approach:
- Local development: keep both servers running in parallel (frontend + backend), so we can still take advantage of their individual benefits (e.g. hot reloading in both sides).
- Production: merge both servers.
Technical guidance:
1. Local development server(s)
We got that already on #22. For readability reasons, let's just rename start
with start-frontend
and start-all
with start-dev
.
In other words, we'll start our dev server (frontend + backend) by running npm run start-dev
2. Production development server
Before going into details, it's important to note up until now create-react-app
has been building our production bundles for us, by running the npm run build command internally.
This command creates a new folder called build
(more about this below).
As we can use just a single server, we'll use the backend one. We essentially need a couple of changes on app.js
- Serve files from the
build folder
:app.use(express.static(path.join(__dirname, '<path-to-build-folder>')));
- Route the
index.html
file (the entry point of our app) on thebuild
folder by default:
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, '<path-to-build-folder>', 'index.html'));
});
More about routing with Node.js and Express
NOTE: At the moment, our backend port is set to 3001
. Heroku
doesn't allow to set static ports, so we have to inherit it from its settings: const port = process.env.PORT || 3001;
Finally, we have to fine tune the start
task, which is automatically triggered by heroku
every time we deploy new stuff with git push heroku master
. Using the npm-run-all
command, we have to:
- Build everything (that means, populate a
build
folder with all the prod assets. - Start the backend server.
Merged servers running in production (note we can use https
, which prevents from some errors being shown!)
Show the TV show title on the details page
So it's time to start adding content to the details page of each TV show.
Let's, for the time being, add the title. E.g.
We advise to:
- Get the list of TV shows from the
Details
component. Note we already did that on theGallery
one to display the list of covers - Save the Id of the current TV show. URL params can be found under
this.props.match.params.<name_of_routing_param>
More about Reactprops
https://facebook.github.io/react-native/docs/props.html - Find the TV show matching the saved Id above
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find - Display the title of the matched TV show
https://kodiri.com/platform/videos/kodflix/5c2fa7b61f00fb0ef12a2bb2
Add your favourite movie cover
It must fit 100% of the available width, regardless of the current resolution
https://kodiri.com/platform/videos/kodflix/5c044b12aed7bd628cbd27ad
Animate the TV show title overlay
At the moment, the TV show title is either 'visible' or 'invisible'
UX team suggest to show it up progressively to enhance the app sweetness.
https://kodiri.com/platform/videos/5c1ad63901df830e144d9769/play
Componentize the TV show element
The new overlay introduced in #5 is great, users like it.
The mechanism, however, doesn't scale well, as we need to copy&paste it for each TV cover.
Transform the TV show element into a single component, and move it to a new file for scalability purposes.
https://kodiri.com/platform/videos/kodflix/5c1ad64901df830e144d976a
https://github.com/rmallols/kodflix/issues/7
Hint: Managing components with React:
https://reactjs.org/docs/react-component.html
https://reactjs.org/docs/components-and-props.html#composing-components
https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#importing-a-component
Connect the frontend and backend servers
https://github.com/rmallols/kodflix/issues/22
Right, both frontend and backend servers are running in parallel (thanks to the start-all
npm task), but they are still disconnected from each other. Let's integrate them!
Please prove we can retrieve the list of TV shows on the frontend from the backend.
Technical guidance:
- Due to security reasons, to enable requests from a given url to a different one (in our case,
http://localhost:3000
->http://localhost:3001
). We can do that by enabling a proxy from the frontend to the backend.
//Add this as a root prop of your package.json
"proxy": "http://localhost:3001"
-
Restart the server and call
/rest/shows
from the frontend using fetch. -
You can then display the list of tv shows on the network tab. You can also display them in the devTools console, using console.log.
Move the covers data model to a proper front-end data source
We're hosting the following info about each TV show:
id
title
cover image
We're hosting these details directly on the HTML markup. This approach has some problems:
Data is hard to find, filter, etc
We cannot reuse data easily (e.g. we'd like to show the TV show title again on the /details view
JavaScript comes with a bunch of data structures to getting rid of these problems.
E.g.
Objects: https://www.w3schools.com/Js/js_objects.asp
Arrays: https://www.w3schools.com/js/js_arrays.asp
So the steps here are:
Create an array of objects to handle the TV show details
Iterate over it
For each item, display the corresponding cover
https://kodiri.com/platform/videos/kodflix/5c23dd525fcf740e981b3e39
Hint: Create a new module (a JavaScript file) to host the gallery items (e.g. gallery-get.js) and import it from the gallery component
How to export / import modules in JavaScript
https://medium.com/craft-academy/es6-modules-imports-and-exports-1e5b552ddca9
Hint: how to use the map function on arrays:
https://www.w3schools.com/jsref/jsref_map.asp
https://stackoverflow.com/questions/38282997/rendering-an-array-map-in-react
https://thinkster.io/tutorials/iterating-and-rendering-loops-in-react (scroll down for the tutorial)
rmallols/kodflix#12
Show a single TV show on each row for mobile devices
User Experience (UX) is important towards keeping apps enjoyable regardless of where they are executed (desktop, mobile, TV, smartwatch, etc).
Please change the TV show layout to ensuring covers are easily reachable on smaller screen sizes
https://www.kodiri.com/platform/videos/kodflix/5c16e1a4e07a520e099fc6c1
https://github.com/rmallols/kodflix/issues/4
Return a list of shows from the backend
https://github.com/rmallols/kodflix/issues/19
We want to keep progressively moving the data logic (for security and accessibility reasons) from the frontend to the backend.
Change the logic on the backend side to return the list of TV shows with the following info:
id
title
synopsis
We'll ignore the image cover for the time being, as requires some rethinking.
Technical guidance:
-
Create a new file, with the list of shows. Please note, in the backend side, we cannot user the
import / export
pattern, since it hasn't been fully implemented by Node.js yet.
For the time being, we have to use its equivalentexports / require
pattern (formally known ascommonJs
http://openmymind.net/2012/2/3/Node-Require-and-Exports/ -
Replace the current root path in
app.js
, fromapp.get('/...'
to a more convenient architecture, based on rest:app.get('/rest/shows'...
-
When
http://localhost:3000/rest/shows
is requested, it should return the list of TV shows
Rest requests will be properly inspected from the browser devTools. In Chrome, we can find it on:
Tools -> More Tools -> Developer Tools -> Network tab
Introduce component state
The state is a core concept in React. Its main purpose is to update the UI immediately as soon as soon as the data model changes:
https://www.tutorialspoint.com/reactjs/reactjs_state.htm
Live demo:
https://jsfiddle.net/67675ag9
Let's initialise the state for the Details component (loaded when a TV show is clicked, on localhost:3000/details. Following the links above:
create a new state property called message with the original text we've displayed up until now (Hello, this will be the details page for each Movie & TV show :)
Display the message on the screen
After 3 seconds, update the message to Coming soon! :)
https://kodiri.com/platform/videos/kodflix/5c23dd6a5fcf740e981b3e3a
Hint: use the setTimeout function to change the message after 3 seconds:
https://www.w3schools.com/Jsref/met_win_settimeout.asp
Hint: use arrow functions, when possible
https://codeburst.io/javascript-arrow-functions-for-beginners-926947fc0cdc
Add 6 TV show titles
Display them in 2 rows (3 covers per row).
Titles will be set as big headings, aligned to the middle (horizontally), and with 30px margin each
image
https://user-images.githubusercontent.com/264750/41350152-0e00aec6-6f0a-11e8-8c49-20c4fcbcb045.png
Redirect to a "not-found" page when the targeted show doesn't exist
https://github.com/rmallols/kodflix/issues/15
Sometimes, users try to access to the TV show by changing the URL manually.
That's what they get when they do it correctly:
That's what they get when they type something wrong in there:
That's not great! we should redirect them to a kind of 'not-found' page whenever we don't know the show they're trying to access
https://kodiri.com/platform/videos/kodflix/5c2fa7c31f00fb0ef12a2bb3
Technical guidance:
-
Create a new
NotFound
component, and return an error message (e.g.Ooops, it looks like this page doesn't exist :(
)
BONUS: As this a very basic component, it may be a good opportunity to start usingfunctional components
for simplicity reasons
https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc -
Create a new
/not-found
route onApp.js
Please use<switch>
to ensuring no other routers are matched
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Switch.md -
Ensure you can access the new route (
http://localhost:3000/not-found
) while the TV show links still work (e.g.http://localhost:3000/breaking-bad
) -
On the
Details
components, if we cannot retrieve the corresponding TV show, then redirect to the/not-found
page using theRedirect
component
https://www.w3schools.com/js/js_if_else.asp
https://tylermcginnis.com/react-router-programmatically-navigate/
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.