Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Victorjspinto assignment =) #58

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

victorjspinto
Copy link

@victorjspinto victorjspinto commented Jul 1, 2024

Here is the small prototype of the Playlist feature 🌟 .

I tried to do this in the simplest way possible and without many new libraries or user cases to keep it simple and also due to the time available.

I hope you enjoy it!

Here are some highlights

Hooks for Playlist and Tracks main operations

I implemented a few react hooks that provide mostly the operations required in the front end. That way, we keep the front end simple and reuse logic/rules across different components.

Favorites and Playlists

Just using a low-hanging-fruit and implementing 2 features with a single backend endpoint. So I provide both Playlist and Favorites (favorites are only one click away, so maybe users will use it more often/be more used to it).

Adding react-query

React queries allow me to create simple API calls and allow me to avoid duplicate calls to the service endpoints. This is pretty useful when used together with the hooks mentioned previously. That way I don't need to create a single component with all state/dependencies just to avoid extra API calls. This also allows us to avoid the issue of prop drilling.

React context for the global player

I refactored the player so now we have a single state manager for the Player (what's currently playing and actions to play/stop the playlist). That way, both Tracks and Playlists pages can command the player using the available hooks

Backend

This was a good exercise to learn more about Python. My main experiences are NodeJS, Java, and more recently GoLang. What I would love to explore more are:

  • authentication

Configure some kind of authentication so we can provide different data to different users (right now, I have not implemented it).

  • metrics

Produce metrics of how many operations are being performed and the latency/amount of time per operation. Good also to check db query performance!

  • logs

Provide good logs so we can easily verify problems!

  • caching of some APIS

Specially the /tracks/ API looks like a good candidate, with both internal cache (Redis / MemCached) or external cache (CDNs)

Hope it's a good starting point for discussions =)

<button className={styles.addToPlaylist + ` ${styles.addToPlaylist}-${track.id}`} onClick={() => setIsMenuVisible(true)}>
{/* context menu */}
{isMenuVisible && (<div className={`${styles.playlistSelector} ${isMenuVisible ? styles.playlistSelectorVisible : ''}`}>
<form onSubmit={onSubmitNewPlaylist}>
Copy link
Author

Choose a reason for hiding this comment

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

Simple as possible, I would love to have more proper validations / etc...


useEffect(() => {
const onClick = (e) => {
if (e.target.closest(`.${styles.addToPlaylist}-${track.id}`)) return
Copy link
Author

Choose a reason for hiding this comment

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

Simple way to implement a context menu, so it opens when we click in the + icon and closes if we click anywhere outside.

I created this className with the track.id because if all tracks have the same addToPlaylist class in their buttons, clicking in the + in another track did not close the previous one.


if (playlist.tracks.length === 1) {
// delete playlist
return await deletePlaylistApiCall(playlist.id)
Copy link
Author

Choose a reason for hiding this comment

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

if I remove the last track of a playlist, I delete the playlist intead

const useTracks = () => {
const [tracks, setTracks] = useState([]);

useEffect(() => {
Copy link
Author

Choose a reason for hiding this comment

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

TODO: I could also use react-query here (again, time constraints)

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.

1 participant