Skip to content

Commit

Permalink
refactor/improved track ui (#29)
Browse files Browse the repository at this point in the history
* refactor: improved playlist info

* refactor: improved track list

* chore: removed log in APIs

* feat: added cover info
  • Loading branch information
sirLisko authored Oct 7, 2024
1 parent 07dfcf9 commit 005978d
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 116 deletions.
20 changes: 8 additions & 12 deletions components/Result/Result.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import Link from "next/link";
import { ArrowLeft, Frown, TriangleAlert } from "lucide-react";
import duration from "humanize-duration";

import Events from "components/Events/Events";
import Tracks from "components/Tracks/Tracks";
Expand All @@ -24,22 +25,18 @@ const sanitiseDate = (dateString: string) => {
return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
};

const getMinutesAndSeconds = (ms: number) => {
const minutes = Math.floor(ms / 60000); // 60000 ms in one minute
const seconds = Math.floor((ms % 60000) / 1000); // remaining seconds
return { minutes, seconds };
};

const calculatePlaylistDuration = (songs: LinkType[]) => {
if (!songs.length) return 0;
return getMinutesAndSeconds(
return duration(
songs.reduce((acc, song) => acc + song.duration_ms, 0),
{ round: true, largest: 2 },
);
};

const generateEncoreLabel = (data: SetList) => {
const totalSetLists = data.totalSetLists;
const encores = data.encores;
console.log(encores);

if (!encores || !Object.keys(encores).length) return null;

Expand All @@ -53,7 +50,9 @@ const generateEncoreLabel = (data: SetList) => {

const encoreLabels = encoreEntries.map(([encoreNumber, count]) => {
const probability = ((count / totalSetLists) * 100).toFixed(0);
return `${ordinalSuffix(encoreNumber)} ${probability}%`;
return Object.entries(encoreEntries).length > 1
? `${ordinalSuffix(encoreNumber)} ${probability}%`
: `${probability}%`;
});

return (
Expand Down Expand Up @@ -189,10 +188,7 @@ const Result = ({ artistQuery }: Props) => {
{playlistDuration ? (
<>
• Estimated playtime:{" "}
<strong>
{playlistDuration?.minutes} minutes and{" "}
{playlistDuration?.seconds} seconds
</strong>
<strong>{playlistDuration}</strong>
</>
) : null}
</p>
Expand Down
29 changes: 23 additions & 6 deletions components/Tracks/Tracks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const Tracks = ({ tracks, links, palette }: TracksProps) => {
} else {
const newAudio = new Audio(audioUrl);
newAudio.play();
newAudio.addEventListener("ended", () => setCurrentTrack(null));
setAudio(newAudio);
setCurrentTrack(title);
}
Expand Down Expand Up @@ -65,17 +66,20 @@ const Tracks = ({ tracks, links, palette }: TracksProps) => {
};
};

const customStyle = {
"--custom-bg-color": `rgba(${palette?.DarkVibrant.rgb.join(",")}, 1)`,
} as React.CSSProperties;

return (
<ul role="list" className="space-y-2">
{tracks.map(({ count, title }) => {
{tracks.map(({ count, title, cover }) => {
const link = links?.find((link) => isSameSong(link.title, title));
const isPlaying = currentTrack === title;

return (
<li
key={title}
style={getGradientStyle(count, tracks[0].count)}
className="group flex items-center space-between justify-between rounded p-3 transition-all"
className="group relative flex items-center space-between justify-between rounded p-3 transition-all"
>
<div className="pl-12 flex items-center">
<div className="absolute left-0 top-0 h-full">
Expand All @@ -89,7 +93,7 @@ const Tracks = ({ tracks, links, palette }: TracksProps) => {
</picture>
) : (
<div
className="w-12 h-12 flex items-center justify-center rounded"
className="w-12 flex items-center justify-center rounded h-full"
style={{
background: `rgba(${palette?.Vibrant.rgb.join(",")}, 255)`,
}}
Expand All @@ -101,9 +105,15 @@ const Tracks = ({ tracks, links, palette }: TracksProps) => {
{link?.previewUrl && (
<button
onClick={() => handlePreview(link.previewUrl, title)}
className="absolute left-0 top-0 h-full p-3 rounded-full bg-transparent hover:bg-black/50 transition-colors duration-300"
className={`absolute left-0 top-0 h-full p-3 rounded-full
bg-transparent
opacity-100 md:opacity-0 group-hover:opacity-100
transition-opacity duration-300
md:group-hover:bg-black/50
md:hover:!bg-[color:var(--custom-bg-color)] hover:opacity-100`}
aria-pressed={isPlaying}
aria-label={isPlaying ? "Pause" : "Play"}
style={{ ...customStyle, opacity: isPlaying ? 1 : undefined }}
>
{isPlaying ? (
<PauseIcon
Expand All @@ -116,7 +126,14 @@ const Tracks = ({ tracks, links, palette }: TracksProps) => {
)}
</button>
)}
<span className="font-medium">{title}</span>
<div className="flex flex-col md:flex-row md:items-baseline">
<span className="font-medium">{title}</span>
{cover && (
<span className="md:ml-1 text-sm opacity-75">
(cover of <span className="italic">{cover}</span>)
</span>
)}
</div>
</div>
<div className="flex items-center space-x-2">
{link?.uri && (
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"dependencies": {
"axios": "^1.7.7",
"classnames": "^2.5.1",
"humanize-duration": "^3.32.1",
"jsonpath-plus": "^9.0.0",
"lucide-react": "^0.445.0",
"modern-css-reset": "^1.4.0",
"next": "^14.2.13",
"next": "^14.2.14",
"node-vibrant": "^3.2.1-alpha.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand All @@ -35,9 +35,10 @@
"swr": "^2.2.5"
},
"devDependencies": {
"@next/eslint-plugin-next": "^14.2.13",
"@next/eslint-plugin-next": "^14.2.14",
"@types/humanize-duration": "^3.27.4",
"@types/jest": "^29.5.13",
"@types/react": "^18.3.8",
"@types/react": "^18.3.11",
"@types/request-ip": "0.0.41",
"@types/spotify-web-api-node": "^5.0.11",
"@typescript-eslint/eslint-plugin": "^5.36.2",
Expand All @@ -48,7 +49,7 @@
"jest": "^29.7.0",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"tailwindcss": "^3.4.12",
"tailwindcss": "^3.4.13",
"typescript": "^5.6.2"
},
"keywords": [
Expand Down
1 change: 0 additions & 1 deletion pages/api/artists/[artistName]/concerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export default async (req: NextApiRequest, res: NextApiResponse<Event[]>) => {
const events = await getArtistEvent(artistName, clientIp);
res.status(HttpStatusCode.Ok).json(events);
} catch (e: any) {
console.error(e);
res
.status(e?.response?.data?.code ?? HttpStatusCode.InternalServerError)
.end(e?.response?.data?.message || "Ops! There was a problem!");
Expand Down
1 change: 0 additions & 1 deletion pages/api/artists/[artistName]/spotify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
const artistData = await getArtistTracks(artistName);
res.status(HttpStatusCode.Ok).json(artistData);
} catch (e: any) {
console.error(e);
res
.status(
e?.response?.data?.code ??
Expand Down
1 change: 0 additions & 1 deletion pages/api/tracks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
const setList = await getArtistSetlist(artistName, artistId);
res.status(HttpStatusCode.Ok).json(getAggregatedSetlists(setList));
} catch (e: any) {
console.error(e);
res
.status(e?.response?.data?.code ?? HttpStatusCode.InternalServerError)
.end(e?.response?.data?.message || "Ops! There was a problem!");
Expand Down
Loading

0 comments on commit 005978d

Please sign in to comment.