From 3a1ec6cdf692300cbf52f2c2f2a957f2ccb34174 Mon Sep 17 00:00:00 2001 From: Nayan Date: Fri, 18 Oct 2024 06:50:25 +0530 Subject: [PATCH] added: playlist page & api functionality --- Genres List.txt | 28 +++ src/constants/constant.js | 17 +- src/pages/Collection/Collection.jsx | 6 +- src/pages/Collection/Collection.module.css | 27 +++ src/pages/Login/Login.jsx | 6 +- src/pages/Playlist/Playlist.jsx | 207 ++++++++++++++++++++- src/pages/Playlist/Playlist.module.css | 0 7 files changed, 282 insertions(+), 9 deletions(-) create mode 100644 Genres List.txt delete mode 100644 src/pages/Playlist/Playlist.module.css diff --git a/Genres List.txt b/Genres List.txt new file mode 100644 index 0000000..138d90a --- /dev/null +++ b/Genres List.txt @@ -0,0 +1,28 @@ +Music /genre/0JQ5DAqbMKFSi39LMRT0Cy +Made for you /genre/0JQ5DAt0tbjZptfcdMSKl3 +Explore all category /genre/0JQ5DArNBzkmxXHCqFLx3c +Daily mix /genre/section0JQ5DACFo5h0jxzOyHOsIo +Your artist mixes /genre/section0JQ5DACFo5h0jxzOyHOsIa +Featured playlist /genre/section0JQ5DAzQHECxDlYNI6xD1g +Uniquely yours /genre/section0JQ5DACFo5h0jxzOyHOsIe +Handpicked new release /genre/section0JQ5IMCbQBLAlPhkJ41ypw +New release /genre/0JQ5DAqbMKFz6FAsUtgAab +Your genre mixes /genre/section0JQ5DACFo5h0jxzOyHOsI9 +Your decade mixes /genre/section0JQ5DACFo5h0jxzOyHOsIb +Your mood mixes /genre/section0JQ5DACFo5h0jxzOyHOsIc +Your niche mixes /genre/section0JQ5DATaxswzruE2nWp3Lr +The best new release /genre/section0JQ5IMCbQBLiGLtWsAvnNG +Recently played /genre/recently-played +Popular equal playlist /genre/section0JQ5IMCbQBLmdV4K4hLrHt +Playlist from our editors /genre/0JQ5DAqbMKFSi39LMRT0Cy +Jump back in /section/0JQ5DAIiKWzVFULQfUm85X +Popular album /section/0JQ5DAnM3wGh0gz1MXnu3B +Today's biggest hits /section/0JQ5DAnM3wGh0gz1MXnu3M +More of what you like /section/0JQ5DAnM3wGh0gz1MXnu3J +India's best /section/0JQ5DAuChZYPe9iDhh2mJz +Charts /section/0JQ5DAnM3wGh0gz1MXnu5g +Popular radio /section/0JQ5DAnM3wGh0gz1MXnu4h +Popular artist /section/0JQ5DAnM3wGh0gz1MXnu3C +For that 'pasandida insaan' /section/0JQ5IMCbQBLkvpuwqL2UWr +Spotify playlist /section/0JQ5DAuChZYPe9iDhh2mJz +Featured charts /section/0JQ5DAzQHECxDlYNI6xD1g diff --git a/src/constants/constant.js b/src/constants/constant.js index 9ead2e2..592f0d2 100644 --- a/src/constants/constant.js +++ b/src/constants/constant.js @@ -3,7 +3,8 @@ const Base_URL = 'https://api.spotify.com/v1'; const Liked_Songs = '/me/tracks?limit=50'; const Albums = '/me/albums'; const Playlist = '/me/playlists'; -const Artists = '/me/following?type=artist'; +const PlaylistWithId = '/playlists'; +const Artists = '/me/following?type=artist&limit=50'; const Several_Category = 'browse/categories'; const Several_Albums = '/albums/{id}'; const New_Release = '/browse/new-releases'; @@ -16,6 +17,13 @@ const Several_Artists = '/artists/{id}'; const Several_BrowserCategory = '/browse/categories'; const Search_Item = '/search'; const Profile = '/me'; +const Recently_Played = '/me/player/recently-played'; +const Recommendation = + '/recommendations?seed_artists={artist_id}&seed_genres={genre}&seed_tracks={track_id}'; +const Today_Hits = '/search?q=playlist:"Today\'s Biggest Hits"&type=playlist'; +const Charts = '/search?q=charts&type=playlist'; +const County_Best = `/browse/categories?country=`; +const User = '/users'; export { Token_URL, @@ -23,6 +31,7 @@ export { Liked_Songs, Albums, Playlist, + PlaylistWithId, Artists, Several_Category, Several_Albums, @@ -36,4 +45,10 @@ export { Several_BrowserCategory, Search_Item, Profile, + Recently_Played, + Recommendation, + Today_Hits, + Charts, + County_Best, + User, }; diff --git a/src/pages/Collection/Collection.jsx b/src/pages/Collection/Collection.jsx index 0bb6920..4745abc 100644 --- a/src/pages/Collection/Collection.jsx +++ b/src/pages/Collection/Collection.jsx @@ -8,7 +8,7 @@ import { IoPlay } from 'react-icons/io5'; import NavBar from '../../components/NavBar/NavBar'; import { Link, useNavigate } from 'react-router-dom'; import { useAuth } from '../../hooks/useAuth'; -import { Liked_Songs } from '../../constants/constant'; +import { Liked_Songs, User } from '../../constants/constant'; import equ from '../../assets/images/equaliser-animated-green.gif'; import { DataContext } from '../../context/DataCacheContext'; import { ThreeDots } from 'react-loader-spinner'; @@ -112,6 +112,10 @@ function Collection() {
+ {profileData {profileData ? profileData.display_name : 'user'} diff --git a/src/pages/Collection/Collection.module.css b/src/pages/Collection/Collection.module.css index a4d3258..b53faa1 100644 --- a/src/pages/Collection/Collection.module.css +++ b/src/pages/Collection/Collection.module.css @@ -55,6 +55,17 @@ display: flex; align-items: center; } +.name { + display: flex; + align-items: center; + justify-content: center; +} +.name img { + width: 2rem; + height: 2rem; + border-radius: 3rem; + margin-right: 0.5rem; +} .songManageSection { display: flex; align-items: center; @@ -92,6 +103,10 @@ button { .desc { font-size: medium; } +.desc h4 { + font-weight: 400; + color: #b8b8b8e0; +} .desc h5 { color: #000000; } @@ -255,6 +270,9 @@ button { .songAddedTime { display: none; } + .name img { + display: none; + } } @media only screen and (min-width: 768px) { .innerSection { @@ -268,6 +286,15 @@ button { font-size: 3rem; } } +@media only screen and (min-width: 1024px) { + .imgSection div img { + width: 200px; + height: 200px; + } + .title h1 { + font-size: 4rem; + } +} @keyframes scroll { 0% { transform: translateX(0%); diff --git a/src/pages/Login/Login.jsx b/src/pages/Login/Login.jsx index 75cd8eb..34644a2 100644 --- a/src/pages/Login/Login.jsx +++ b/src/pages/Login/Login.jsx @@ -7,7 +7,7 @@ function Login() { const clientId = import.meta.env.VITE_CLIENT_ID; const redirectUri = import.meta.env.VITE_HOME_URL; const scope = - 'user-read-private user-read-email playlist-modify-private playlist-modify-public playlist-read-private user-top-read user-library-read user-follow-read'; + 'user-read-private user-read-email playlist-modify-private playlist-modify-public playlist-read-private user-top-read user-library-read user-follow-read user-read-recently-played'; let url = 'https://accounts.spotify.com/authorize'; url += '?response_type=token'; url += '&client_id=' + encodeURIComponent(clientId); @@ -32,8 +32,8 @@ function Login() {
- Get Started,to your musical journey with spotify, - simply log in with your existing account or
+ Get Started,to your musical journey with spotify + client, simply log in with your existing account or
create a new one. diff --git a/src/pages/Playlist/Playlist.jsx b/src/pages/Playlist/Playlist.jsx index 98c14dd..470fceb 100644 --- a/src/pages/Playlist/Playlist.jsx +++ b/src/pages/Playlist/Playlist.jsx @@ -1,14 +1,213 @@ -import React from 'react'; -import styles from './Playlist.module.css'; +import React, { useState, useEffect } from 'react'; +import styles from '../Collection/Collection.module.css'; import { Icon } from '../../Icons'; import { FaArrowLeft } from 'react-icons/fa6'; import { RiMore2Line } from 'react-icons/ri'; import { LuClock3 } from 'react-icons/lu'; +import { IoPlay } from 'react-icons/io5'; import NavBar from '../../components/NavBar/NavBar'; -import { Link } from 'react-router-dom'; +import { Link, useNavigate, useParams } from 'react-router-dom'; +import { useAuth } from '../../hooks/useAuth'; +import { PlaylistWithId, User } from '../../constants/constant'; +import equ from '../../assets/images/equaliser-animated-green.gif'; +import { ThreeDots } from 'react-loader-spinner'; function Playlist() { - return <>; + const navigate = useNavigate(); + const [cardHover, setCardHover] = useState(false); + const [playlistData, setPlaylistData] = useState(null); + const [playlistOwner, setPlaylistOwner] = useState(null); + const { fetchData } = useAuth(); + const { playlistId } = useParams(); + + const DateConverter = (zuluTime) => { + const date = new Date(zuluTime); + const months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + ]; + const day = String(date.getUTCDate()).padStart(2, '0'); + const month = months[date.getUTCMonth()]; + const year = date.getUTCFullYear(); + return `${day} ${month} ${year}`; + }; + + const msToTime = (milliseconds) => { + const totalSeconds = Math.floor(milliseconds / 1000); + + const minutes = Math.floor((totalSeconds % 3600) / 60); + const seconds = totalSeconds % 60; + + const formattedMinutes = String(minutes).padStart(2, '0'); + const formattedSeconds = String(seconds).padStart(2, '0'); + + return `${formattedMinutes}:${formattedSeconds}`; + }; + useEffect(() => { + // do { + fetchData(`${PlaylistWithId}/${playlistId}`) + .then((res) => { + setPlaylistData(res); + fetchData(`${User}/${res.owner.id}`) + .then((res) => { + setPlaylistOwner(res); + }) + .catch((err) => { + console.log(err); + }); + }) + .catch((err) => { + console.log(err); + }); + // } while (savedTracks != null); + }, [playlistId]); + + return ( +
+ {playlistData ? ( +
+
+ +
+ +
+
+
+ {playlistData +
+
+
+
+ {playlistData && playlistData.type} +
+
+

{playlistData && playlistData.name}

+
+
+

{playlistData && playlistData.description}

+
+
+
+ {playlistOwner + +

{playlistOwner && playlistOwner.display_name}

+ + + +  • {playlistData.tracks.total} songs + +
+
+
+
+
+ + + + + + + + + + + + {playlistData.tracks.items.map((data, index) => { + return ( + + + + + + + + + ); + })} + +
#titlealbumdate added + +
+ {cardHover ? : {index + 1}} + {/* */} + +
+ +
+
+
+ + {data.track.name} + +
+
+ {data.track.artists.map((obj, index) => { + return ( + + {obj.name}, + + ); + })} +
+
+
+
+ + {data.track.album.name} + +
+
+ {DateConverter(data.added_at)} + + {msToTime(data.track.duration_ms)} + + +
+
+
+ ) : ( +
+ +
+ )} +
+ ); } export default Playlist; diff --git a/src/pages/Playlist/Playlist.module.css b/src/pages/Playlist/Playlist.module.css deleted file mode 100644 index e69de29..0000000