147 lines
No EOL
4.8 KiB
JavaScript
147 lines
No EOL
4.8 KiB
JavaScript
import React, { useEffect } from 'react'
|
|
import './main.css'
|
|
import { AiFillClockCircle } from "react-icons/ai";
|
|
import { useStateProvider } from '../../util/StateProvider';
|
|
import axios from 'axios';
|
|
import { reducerCases } from '../../util/Constants';
|
|
|
|
const Main = () => {
|
|
const [{token, selectedPlaylistId, selectedPlaylist}, dispatch] = useStateProvider();
|
|
useEffect(() => {
|
|
const getInitialPlaylist = async () => {
|
|
const response = await axios.get(`https://api.spotify.com/v1/playlists/${selectedPlaylistId}`,
|
|
{
|
|
headers:{
|
|
Authorization:"Bearer "+token,
|
|
"Content-Type": "application/json"
|
|
},
|
|
}
|
|
);
|
|
const selectedPlaylist = {
|
|
id: response.data.id,
|
|
name: response.data.name,
|
|
description: response.data.description.startsWith("<a") ? "" : response.data.description,
|
|
image: response.data.images[0].url,
|
|
tracks: response.data.tracks.items.map(({track}) => ({
|
|
id: track.id,
|
|
name: track.name,
|
|
artists: track.artists.map((artist) => artist.name),
|
|
image: track.album.images[2].url,
|
|
duration: track.duration_ms,
|
|
album: track.album.name,
|
|
context_uri: track.album.uri,
|
|
track_number: track.track_number,
|
|
})),
|
|
}
|
|
dispatch({type: reducerCases.SET_PLAYLISTS, selectedPlaylist})
|
|
};
|
|
getInitialPlaylist();
|
|
}, [token, dispatch, selectedPlaylistId])
|
|
|
|
const minAndSec = (ms) => {
|
|
const minutes = Math.floor(ms/60000);
|
|
const seconds = ((ms % 60000)/1000).toFixed(0);
|
|
return minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
|
|
}
|
|
|
|
const playTrack = async (id, name, artists, image, context_uri, track_number) => {
|
|
//PREMIUM_REQUIRED
|
|
const response = await axios.put('https://api.spotify.com/v1/me/player/play',
|
|
{
|
|
context_uri,
|
|
offset:{
|
|
position: track_number - 1
|
|
},
|
|
position_ms: 0,
|
|
},
|
|
{
|
|
headers: {
|
|
Authorization:"Bearer "+token,
|
|
"Content-Type": "application/json"
|
|
}
|
|
}
|
|
);
|
|
if(response.status === 204){
|
|
const currentlyPlaying = {id, name, artists, image}
|
|
|
|
dispatch({type: reducerCases.SET_PLAYING, currentlyPlaying})
|
|
dispatch({type: reducerCases.SET_PLAYER_STATE, playerState: true})
|
|
}else dispatch({type: reducerCases.SET_PLAYER_STATE, playerState: true})
|
|
}
|
|
|
|
|
|
return (
|
|
<div className='Main'>
|
|
{
|
|
selectedPlaylist && (
|
|
<>
|
|
<div className="main-playlist">
|
|
<div className="main-image">
|
|
<img src={selectedPlaylist.image} alt="" />
|
|
</div>
|
|
<div className="main-detail">
|
|
<span className="main-type">Playlist</span>
|
|
<h1 className='main-title'>{selectedPlaylist.name}</h1>
|
|
<p className="main-desc">{selectedPlaylist.description}</p>
|
|
</div>
|
|
</div>
|
|
<div className="main-list">
|
|
<div className="main-header">
|
|
<div className="header-col">
|
|
<span>#</span>
|
|
</div>
|
|
<div className="header-col">
|
|
<span>Title</span>
|
|
</div>
|
|
<div className="header-col album">
|
|
<span>Album</span>
|
|
</div>
|
|
<div className="header-col">
|
|
<span><AiFillClockCircle/></span>
|
|
</div>
|
|
</div>
|
|
<div className="main-tracks">
|
|
{selectedPlaylist.tracks.map(({
|
|
id,
|
|
name,
|
|
artists,
|
|
image,
|
|
duration,
|
|
album,
|
|
context_uri,
|
|
track_number,
|
|
}, index) => {
|
|
return(
|
|
<div className="main-row" key={id} onClick={() => playTrack(id, name, artists, image, context_uri, track_number)}>
|
|
<div className="main-col">
|
|
<span>{index+1}</span>
|
|
</div>
|
|
<div className="main-col detail">
|
|
<div className="image">
|
|
<img src={image} alt="track" />
|
|
</div>
|
|
<div className="main-info">
|
|
<span className="main-name">{name}</span>
|
|
<span>{artists.join(", ")}</span>
|
|
</div>
|
|
</div>
|
|
<div className="main-col album">
|
|
<span>{album}</span>
|
|
</div>
|
|
<div className="main-col">
|
|
<span>{minAndSec(duration)}</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
)}
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Main |