web_react/spotify_api/src/components/main/Main.jsx

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