Skip to content

Conversation

@purvasheth
Copy link
Owner

No description provided.

@purvasheth purvasheth changed the title PR for Review of Video Library [FE] PR for Video Library [FE] May 5, 2021
@Janaki2399
Copy link

Hey Purva, I totally loved your app. The code is very clean too.
I have few suggestions with the folder structure.
-You can create a separate folder for context
-In few pages, you have listed all the components in the same file for example video listing page. Instead, you can extract each of those components into a separate file. In the components folder you can create a separate folder like video, can group all the components of the videos page into that folder. This way the page would have only the main structure.
-You can also rename your JSX instead of js. It would be easier to distinguish between both.

Also for the functions, in few places, the arrow function is used and in few places, regular function syntax is used. You can change all to arrow functions so that your app will only have Es6 syntax and it will be consistent.

const { _id, name, videos, defaultPlaylist } = playlist;
return (
<Fragment key={_id}>
<PlaylistHeader

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can create a playlist card component and extract this out. The main page structure would look more cleaner.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A playlist is a group of videos and does not have a card as such. So, I made the code readable by breaking it into more components. Thanks for noticing this.

navigate("/page-not-found");
}
})();
return () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice that you have cleaned up the useEffect.I should do it too

useEffect(() => {
if (mongooseVideoId) {
if (history.length === 0) {
(async () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel it is getting a bit verbose here. Try extracting it to a separate function.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good Idea. Created multiple functions for this

export function ToggleIconGroup({ video, likedVideos, watchLater }) {
return (
<>
<ToggleIcon playlist={likedVideos || defaultPlaylist} video={video} />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This || thing is so cool. I will use it in mine also. I used to pass an additional prop for this

}
} else {
const success = await removeVideoFromPlaylist(video._id);
if (success) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can extract these also to a separate function. It would be easier to understand.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again a great suggestion. Updated this

@purvasheth
Copy link
Owner Author

purvasheth commented May 8, 2021

Hey Purva, I totally loved your app. The code is very clean too.
I have few suggestions with the folder structure.
-You can create a separate folder for context
-In few pages, you have listed all the components in the same file for example video listing page. Instead, you can extract each of those components into a separate file. In the components folder you can create a separate folder like video, can group all the components of the videos page into that folder. This way the page would have only the main structure.
-You can also rename your JSX instead of js. It would be easier to distinguish between both.

Also for the functions, in few places, the arrow function is used and in few places, regular function syntax is used. You can change all to arrow functions so that your app will only have Es6 syntax and it will be consistent.

Thanks a lot for your Review. All your suggestions are great!
I'll make these changes.

  • For the folder structure, I have tried to group by functionality i.e all files related to 'Videos' are together. I don't know which is better, group by functionality or group by type.
  • Good catch on the video listing page having more components. I forgot to move components to different files.
  • As for the inconsistency in using arrow functions, I have used arrow functions for methods inside components and normal functions for components. My reason for using normal functions for components is because I try to follow the Airbnb react guide. https://github.com/airbnb/javascript/tree/master/react#class-vs-reactcreateclass-vs-stateless

Copy link

@Jaynil1611 Jaynil1611 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Great work @purvasheth, Very nice and consistent UI
  • The code is very well maintained and the naming of the components is also perfect.

Here are my few suggestions

  • You can use index.js at the root folder wherever you feel it is required while using nested imports.
  • Use ternary operator where you are using if-else for small code
  • Just a suggestion, single file going over 100 lines, you can extract the components to separate files and import them

Comment on lines +2 to +11
import { VideoListing } from "./pages/Videos/VideoListing";
import { Playlists } from "./pages/Playlists/Playlists";
import { PlaylistDetail } from "./pages/Playlists/PlaylistDetail";
import { Routes, Route } from "react-router-dom";
import { NavigationBar } from "./components/NavigationBar";
import { VideoDetail } from "./pages/Videos/VideoDetail";
import { PageNotFound } from "./pages/PageNotFound";
import { History } from "./pages/History/History";
import { SearchResults } from "./pages/SearchResults";
import { ToastContainer } from "react-toastify";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing separate imports for the same folder, you can use index.js inside page folder and re-export all nested components inside pages folder
e.g.

Suggested change
import { VideoListing } from "./pages/Videos/VideoListing";
import { Playlists } from "./pages/Playlists/Playlists";
import { PlaylistDetail } from "./pages/Playlists/PlaylistDetail";
import { Routes, Route } from "react-router-dom";
import { NavigationBar } from "./components/NavigationBar";
import { VideoDetail } from "./pages/Videos/VideoDetail";
import { PageNotFound } from "./pages/PageNotFound";
import { History } from "./pages/History/History";
import { SearchResults } from "./pages/SearchResults";
import { ToastContainer } from "react-toastify";
import { VideoListing, Playlists, PlaylistDetail,... } from "./pages";

Comment on lines +18 to +26
<Routes>
<Route path="/" element={<VideoListing />} />
<Route path="/playlists" element={<Playlists />} />
<Route path="/playlists/:playlistId" element={<PlaylistDetail />} />
<Route path="/video/:videoId" element={<VideoDetail />} />
<Route path="/history" element={<History />} />
<Route path="/search" element={<SearchResults />} />s
<Route path="*" element={<PageNotFound />} />
</Routes>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract this to a router.js file

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the number of routes is less, I think it's ok to keep them in this file.

import { NavLink } from "react-router-dom";
import { usePlaylists } from "../pages/Playlists/playlists-context";
import { SET_VIDEOS } from "../pages/Videos/videos-reducer";
import { useAxios } from "../custom hooks/useAxios";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use consistent naming convention custom hooks rename to custom-hooks

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Will update this.

Comment on lines +57 to +59
(!isLikedVideosIdSet || !isWatchLaterIdSet) &&
i < playlists.length
) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could extract this logic out to function to improve readability

</label>
);
}
function CreatePlaylist({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could extract out CreatePlaylist and it's related components to new file

<h1>{name}</h1>
<div className="flex">
{videos.map((video) => {
return (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, here you can remove return same as before

);
}

function PlaylistHeader({ name, _id, defaultPlaylist }) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract this component and below component to different file

Comment on lines +32 to +37
playlists: playlists.map((playlist) =>
playlist._id !== playlistId
? playlist
: { ...playlist, videos: playlist.videos.concat(video) }
),
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract this and similar reducer actions to another function and use them,
And you can refactor it to this in ADD_VIDEO_ && REMOVE_VIDEO_

Suggested change
playlists: playlists.map((playlist) =>
playlist._id !== playlistId
? playlist
: { ...playlist, videos: playlist.videos.concat(video) }
),
};
playlists: playlists.map((playlist) =>
playlist._id === playlistId
? { ...playlist, videos: playlist.videos.concat(video) } : playlist
),
};


return (
<div key={id} className="card card--shadow m-1">
<Thumbnail onClick={openVideo} id={id} className="clickable" />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The onClick={openVideo} function should be on the upper div and not on Thumbnail, due to which clicking on an avatar or video title, the video is not opening up.

const [activeCategory, setActiveCategory] = useState("All");
return (
<div className="container">
<h1>Video Listing</h1>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of VideoListing, you can rename it to Explore Videos or anything else

@purvasheth
Copy link
Owner Author

purvasheth commented May 11, 2021

  • Great work @purvasheth, Very nice and consistent UI
  • The code is very well maintained and the naming of the components is also perfect.

Here are my few suggestions

  • You can use index.js at the root folder wherever you feel it is required while using nested imports.
  • Use ternary operator where you are using if-else for small code
  • Just a suggestion, single file going over 100 lines, you can extract the components to separate files and import them

All your suggestions were great!
Tried to implement them as much as possible.
Thanks a lot for your review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants