-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
299 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { atom } from 'recoil' | ||
|
||
export const playlistState = atom({ | ||
key: 'playlistState', | ||
default: null, | ||
}) | ||
|
||
export const playlistIdState = atom({ | ||
key: 'playlistIdState', | ||
default: '37i9dQZF1EUMDoJuT8yJsl', | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { useSession } from 'next-auth/react' | ||
import { ChevronDownIcon } from '@heroicons/react/outline' | ||
import { useEffect, useState } from 'react' | ||
import { shuffle } from 'lodash' | ||
import { useRecoilState, useRecoilValue } from 'recoil' | ||
import { playlistIdState, playlistState } from '../atoms/playlistAtom' | ||
import useSpotify from '../hooks/useSpotify' | ||
import Songs from './Songs' | ||
|
||
const colors = [ | ||
'from-indigo-500', | ||
'from-blue-500', | ||
'from-green-500', | ||
'from-red-500', | ||
'from-yellow-500', | ||
'from-pink-500', | ||
'from-purple-500', | ||
] | ||
|
||
function Center() { | ||
const spotifyApi = useSpotify() | ||
const { data: session } = useSession() | ||
const [color, setColor] = useState(null) | ||
const playlistId = useRecoilValue(playlistIdState) | ||
const [playlist, setPlaylist] = useRecoilState(playlistState) | ||
|
||
console.log('Playlist - ', playlist) | ||
|
||
useEffect(() => { | ||
setColor(shuffle(colors).pop()) | ||
}, [playlistId]) | ||
|
||
useEffect(() => { | ||
spotifyApi | ||
.getPlaylist(playlistId) | ||
.then((data) => setPlaylist(data.body)) | ||
.catch((error) => console.log(error)) | ||
}, [spotifyApi, playlistId]) | ||
|
||
return ( | ||
<div className="flex-grow h-screen overflow-y-scroll scrollbar-hide"> | ||
<header className="absolute top-5 right-8"> | ||
<div | ||
className="flex items-center bg-black space-x-3 | ||
opacity-90 hover:opacity-80 cursor-pointer rounded-full p-1 pr-2 text-white text-sm" | ||
> | ||
<img | ||
className="rounded-full w-10 h-10" | ||
src={session?.user.image} | ||
alt="avatar" | ||
/> | ||
<h2>{session?.user.name}</h2> | ||
<ChevronDownIcon className="h-5 w-5" /> | ||
</div> | ||
</header> | ||
<section | ||
className={`flex items-end space-x-7 | ||
bg-gradient-to-b to-black ${color} h-80 text-white p-8`} | ||
> | ||
<img | ||
className="w-44 h-44 shadow-2xl" | ||
src={playlist?.images[0]?.url} | ||
alt="playlist image" | ||
/> | ||
<div> | ||
<p>PLAYLIST</p> | ||
<h1 className="text-2xl md:text-3xl xl:text-5xl font-bold"> | ||
{playlist?.name} | ||
</h1> | ||
</div> | ||
</section> | ||
|
||
<div> | ||
<Songs /> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export default Center |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { millisToMinutesAndSeconds } from '../lib/time' | ||
|
||
function Song({ order, track }) { | ||
// console.log(track) | ||
return ( | ||
<div className="grid grid-cols-2"> | ||
<div className="flex items-center space-x-4"> | ||
<p>{order + 1}</p> | ||
<img | ||
className="w-10 h-10" | ||
src={track.track.album.images[0].url} | ||
alt="track image" | ||
/> | ||
<div> | ||
<p>{track.track.name}</p> | ||
<p>{track.track.artists[0].name}</p> | ||
</div> | ||
</div> | ||
<div | ||
className="flex items-center justify-between | ||
ml-auto md:ml-0" | ||
> | ||
<p className="hidden md:inline">{track.track.album.name}</p> | ||
<p>{millisToMinutesAndSeconds(track.track.duration_ms)}</p> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export default Song |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useRecoilValue } from 'recoil' | ||
import { playlistState } from '../atoms/playlistAtom' | ||
import Song from './Song' | ||
|
||
function Songs() { | ||
const playlist = useRecoilValue(playlistState) | ||
|
||
return ( | ||
<div className="flex flex-col px-8 space-y-1 pb-20 text-white"> | ||
{playlist?.tracks.items.map((track, index) => ( | ||
<Song key={track.track.id} order={index} track={track} /> | ||
))} | ||
</div> | ||
) | ||
} | ||
|
||
export default Songs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { signIn, useSession } from 'next-auth/react' | ||
import { useEffect } from 'react' | ||
import SpotifyWebApi from 'spotify-web-api-node' | ||
// import spotifyApi from '../lib/spotify' | ||
|
||
const spotifyApi = new SpotifyWebApi({ | ||
clientId: process.env.NEXT_PUBLIC_CLIENT_ID, | ||
clientSecret: process.env.NEXT_PUBLIC_CLIENT_SECRET, | ||
}) | ||
|
||
function useSpotify() { | ||
const { data: session, status } = useSession() | ||
|
||
useEffect(() => { | ||
if (session) { | ||
// If refresh token attempt fails, direct user to login | ||
if (session.error === 'RefreshAccessTokenError') { | ||
signIn() | ||
} | ||
|
||
spotifyApi.setAccessToken(session.user.accessToken) | ||
} | ||
}, [session]) | ||
return spotifyApi | ||
} | ||
|
||
export default useSpotify |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { constSelector } from 'recoil' | ||
|
||
export const millisToMinutesAndSeconds = (millis) => { | ||
const minutes = Math.floor(millis / 60000) | ||
const seconds = ((millis % 60000) / 1000).toFixed(0) | ||
|
||
return seconds == 60 | ||
? minutes + 1 + ':00' | ||
: minutes + ':' + (seconds < 10 ? '0' : '') + seconds | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.