Skip to content

Commit

Permalink
feat(ui): indicate currently playing playlist/album/artist
Browse files Browse the repository at this point in the history
fixes (#68)
  • Loading branch information
brandonsaldan committed Jan 6, 2025
1 parent e80de01 commit 888358b
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 21 deletions.
22 changes: 22 additions & 0 deletions src/hooks/useMediaState.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState, useEffect, useCallback } from "react";
import { getCurrentDevice } from "@/services/deviceService";
import local from "next/font/local";

export function useMediaState(accessToken, handleError) {
const [currentPlayback, setCurrentPlayback] = useState(null);
Expand Down Expand Up @@ -31,6 +32,7 @@ export function useMediaState(accessToken, handleError) {
setCurrentPlayback(null);
setCurrentlyPlayingAlbum(null);
setCurrentlyPlayingTrackUri(null);
localStorage.removeItem("playingLikedSongs");
return;
}

Expand All @@ -40,9 +42,29 @@ export function useMediaState(accessToken, handleError) {
setCurrentPlayback(null);
setCurrentlyPlayingAlbum(null);
setCurrentlyPlayingTrackUri(null);
localStorage.removeItem("playingLikedSongs");
return;
}

if (data.context?.uri) {
if (!data.context.uri.includes("collection")) {
localStorage.removeItem("playingLikedSongs");
}
const mixFlags = Object.keys(localStorage).filter((key) =>
key.startsWith("playingMix-")
);
mixFlags.forEach((flag) => {
if (localStorage.getItem(flag) !== data.context.uri) {
localStorage.removeItem(flag);
}
});
} else if (!data.item) {
localStorage.removeItem("playingLikedSongs");
Object.keys(localStorage)
.filter((key) => key.startsWith("playingMix-"))
.forEach((key) => localStorage.removeItem(key));
}

setCurrentPlayback({
...data,
device: {
Expand Down
9 changes: 6 additions & 3 deletions src/pages/_app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ export default function App({ Component, pageProps }) {
if (typeof window === "undefined") return;

try {
await checkNetworkConnectivity(localStorage.getItem("spotifyAccessToken"));
await checkNetworkConnectivity(
localStorage.getItem("spotifyAccessToken")
);
} catch (error) {
setAuthState({
authSelectionMade: false,
Expand Down Expand Up @@ -560,9 +562,10 @@ export default function App({ Component, pageProps }) {

return (
<main
className={`overflow-hidden relative min-h-screen rounded-2xl ${mainFontClasses}`}
className={`overflow-hidden relative min-h-screen rounded-2xl ${mainFontClasses}`}
style={{
fontFamily: "var(--font-inter), var(--font-noto-sans-sc), var(--font-noto-sans-tc), var(--font-noto-serif-jp), var(--font-noto-sans-kr), var(--font-noto-naskh-ar), var(--font-noto-sans-dv), var(--font-noto-sans-he), var(--font-noto-sans-bn), var(--font-noto-sans-ta), var(--font-noto-sans-th), var(--font-noto-sans-gk)",
fontFamily:
"var(--font-inter), var(--font-noto-sans-sc), var(--font-noto-sans-tc), var(--font-noto-serif-jp), var(--font-noto-sans-kr), var(--font-noto-naskh-ar), var(--font-noto-sans-dv), var(--font-noto-sans-he), var(--font-noto-sans-bn), var(--font-noto-sans-ta), var(--font-noto-sans-th), var(--font-noto-sans-gk)",
fontOpticalSizing: "auto",
}}
>
Expand Down
3 changes: 3 additions & 0 deletions src/pages/collection/tracks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ const LikedSongsPage = ({
});
}

localStorage.setItem("playingLikedSongs", "true");

const savedShuffleState =
localStorage.getItem("shuffleEnabled") === "true";

Expand Down Expand Up @@ -225,6 +227,7 @@ const LikedSongsPage = ({
try {
const device = await getCurrentDevice(accessToken, handleError);
const activeDeviceId = device == null ? null : device.id;
localStorage.setItem("playingLikedSongs", "true");

if (device && !device.is_active) {
await fetch("https://api.spotify.com/v1/me/player", {
Expand Down
92 changes: 83 additions & 9 deletions src/pages/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function Home({
currentlyPlayingAlbum,
showBrightnessOverlay,
handleError,
currentPlayback,
}) {
const [showDonationModal, setShowDonationModal] = useState(false);
const router = useRouter();
Expand Down Expand Up @@ -289,8 +290,27 @@ export default function Home({
{likedSongs.name}
</h4>
</LongPressLink>
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px]">
{likedSongs.tracks.total.toLocaleString()} Songs
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px] flex items-center">
{currentPlayback?.context?.uri?.includes(
"collection"
) ||
(currentPlayback?.context === null &&
localStorage.getItem("playingLikedSongs") ===
"true") ? (
<>
<div className="w-5 ml-0.5 mr-3 mb-2">
<section>
<div className="wave0"></div>
<div className="wave1"></div>
<div className="wave2"></div>
<div className="wave3"></div>
</section>
</div>
Now Playing
</>
) : (
`${likedSongs.tracks.total.toLocaleString()} Songs`
)}
</h4>
</div>
)}
Expand Down Expand Up @@ -326,9 +346,27 @@ export default function Home({
{playlist.name}
</h4>
</LongPressLink>
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px]">
{playlist.tracks?.total?.toLocaleString() || 0}{" "}
Songs
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px] flex items-center">
{currentPlayback &&
currentPlayback.context &&
currentPlayback.context.uri ===
`spotify:playlist:${playlist.id}` ? (
<>
<div className="w-5 ml-0.5 mr-3 mb-2">
<section>
<div className="wave0"></div>
<div className="wave1"></div>
<div className="wave2"></div>
<div className="wave3"></div>
</section>
</div>
Now Playing
</>
) : (
`${
playlist.tracks?.total?.toLocaleString() || 0
} Songs`
)}
</h4>
</div>
))}
Expand Down Expand Up @@ -365,8 +403,24 @@ export default function Home({
{artist.name}
</h4>
</LongPressLink>
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px]">
{artist.followers.total.toLocaleString()} Followers
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px] flex items-center">
{currentPlayback?.item?.artists?.some(
(a) => a.id === artist.id
) ? (
<>
<div className="w-5 ml-0.5 mr-3 mb-2">
<section>
<div className="wave0"></div>
<div className="wave1"></div>
<div className="wave2"></div>
<div className="wave3"></div>
</section>
</div>
Now Playing
</>
) : (
`${artist.followers.total.toLocaleString()} Followers`
)}
</h4>
</div>
))}
Expand Down Expand Up @@ -398,8 +452,28 @@ export default function Home({
{mix.name}
</h4>
</LongPressLink>
<h4 className="text-[28px] font-[560] text-white/60 truncate tracking-tight max-w-[280px]">
{mix.tracks.length} Songs
<h4 className="text-[28px] font-[560] text-white truncate tracking-tight max-w-[280px] flex items-center">
{(() => {
const playingMixId = localStorage.getItem(
`playingMix-${mix.id}`
);
return currentPlayback?.context?.uri ===
playingMixId ? (
<>
<div className="w-5 ml-0.5 mr-3 mb-2">
<section>
<div className="wave0"></div>
<div className="wave1"></div>
<div className="wave2"></div>
<div className="wave3"></div>
</section>
</div>
Now Playing
</>
) : (
`${mix.tracks.length} Songs`
);
})()}
</h4>
</div>
))}
Expand Down
10 changes: 10 additions & 0 deletions src/pages/mix/[mixId].jsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const MixPage = ({

const playMix = async () => {
try {
const mixId = router.query.mixId;
const userResponse = await fetch("https://api.spotify.com/v1/me", {
headers: {
Authorization: `Bearer ${accessToken}`,
Expand All @@ -142,6 +143,10 @@ const MixPage = ({
}
);
const playlistData = await createPlaylistResponse.json();
localStorage.setItem(
`playingMix-${mixId}`,
`spotify:playlist:${playlistData.id}`
);

const tracksToAdd = tracks.map((track) => track.uri);
await fetch(
Expand Down Expand Up @@ -234,6 +239,7 @@ const MixPage = ({

const playTrack = async (trackUri, trackIndex) => {
try {
const mixId = router.query.mixId;
const userResponse = await fetch("https://api.spotify.com/v1/me", {
headers: {
Authorization: `Bearer ${accessToken}`,
Expand All @@ -257,6 +263,10 @@ const MixPage = ({
}
);
const playlistData = await createPlaylistResponse.json();
localStorage.setItem(
`playingMix-${mixId}`,
`spotify:playlist:${playlistData.id}`
);

const tracksToAdd = tracks.map((track) => track.uri);
await fetch(
Expand Down
18 changes: 9 additions & 9 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,6 @@ section {
padding-top: 8px;
}

[class*="wave"] {
aspect-ratio: 0.125/1;
background-color: #ffffff;
border-radius: 15px;
width: 0.1vw;
}

@keyframes waveform {
0% {
transform: scaleY(0.5);
Expand All @@ -134,8 +127,8 @@ section {

[class*="wave"] {
aspect-ratio: 0.125/1;
/*This can all be written on one line:*/
animation: waveform var(--wavefreq) ease-in-out 0.1s infinite forwards;
animation: waveform var(--wavefreq) ease-in-out infinite forwards;
animation-delay: var(--wave-offset);
background-color: #ffffff;
border-radius: 15px;
width: 1vw;
Expand All @@ -144,30 +137,37 @@ section {
:root {
--m: 11.5;
--wavefreq: calc(100ms * var(--m));
--wave-offset: -1.5s;
}

.wave1 {
--wavefreq: calc(200ms * var(--m));
animation-delay: calc(var(--wave-offset) - 0.2s);
}

.wave2 {
--wavefreq: calc(300ms * var(--m));
animation-delay: calc(var(--wave-offset) - 0.3s);
}

.wave3 {
--wavefreq: calc(400ms * var(--m));
animation-delay: calc(var(--wave-offset) - 0.4s);
}

.wave4 {
--wavefreq: calc(500ms * var(--m));
animation-delay: calc(var(--wave-offset) - 0.5s);
}

.wave5 {
--wavefreq: calc(600ms * var(--m));
animation-delay: calc(var(--wave-offset) - 0.6s);
}

.wave6 {
--wavefreq: calc(700ms * var(--m));
animation-delay: calc(var(--wave-offset) - 0.7s);
}

.track-name-container {
Expand Down

0 comments on commit 888358b

Please sign in to comment.