Skip to content

Commit

Permalink
Use Spotify-api.js built-in getCurrentPlayback
Browse files Browse the repository at this point in the history
  • Loading branch information
au2001 committed Dec 26, 2023
1 parent 63a118a commit 80e0f95
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 55 deletions.
19 changes: 9 additions & 10 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
import { getQueue, getPlaybackState } from "@/utils/queue";
import { getQueue, getCurrentPlayback } from "@/utils/queue";
import styles from "./page.module.css";
import { redirect } from "next/navigation";
import TrackCover from "./track_cover";
import TrackList from "./track_list";
import Form from "./form";

export default async function Home() {
const queue = await getQueue();
const playback = await getPlaybackState();
const [queue, currentPlayback] = await Promise.all([
getQueue(),
getCurrentPlayback(),
]);
if (queue === null) redirect("/login");

return (
<main className={styles.main}>
<Form />

{playback !== null && playback.currentlyPlaying !== null && (
{currentPlayback?.isPlaying && currentPlayback.item?.type === "track" && (
<>
<h1>Currently playing</h1>
<TrackCover
track={playback.currentlyPlaying}
progress={playback.progress}
/>
<TrackCover currentPlayback={currentPlayback} />
</>
)}

{queue.queue.length > 0 && (
{queue.length > 0 && (
<>
<h1>Queue</h1>
<TrackList items={queue.queue}></TrackList>
<TrackList items={queue}></TrackList>
</>
)}
</main>
Expand Down
16 changes: 9 additions & 7 deletions src/app/track_cover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { formatDuration } from "@/utils/ui";
import styles from "./track.module.css";

interface Props {
track: Spotify.Track;
progress: number | undefined;
currentPlayback: Spotify.CurrentPlayback;
}

export default function TrackCover({ track, progress }: Props) {
export default function TrackCover({ currentPlayback }: Props) {
const track = currentPlayback.item as Spotify.Track;

return (
<table className={styles.table}>
<tbody>
Expand All @@ -22,7 +23,7 @@ export default function TrackCover({ track, progress }: Props) {
src={track.album?.images[0].url ?? ""}
width={200}
height={200}
></Image>
/>
</td>
<td className={styles.absorbing_column}>
<div className={styles.title}>{track.name}</div>
Expand All @@ -31,9 +32,10 @@ export default function TrackCover({ track, progress }: Props) {
</div>
</td>
<td>
<div className={styles.duration}>{`${formatDuration(
progress ?? 0,
)} / ${formatDuration(track.duration)}`}</div>
<div className={styles.duration}>
{formatDuration(currentPlayback.progress)} /{" "}
{formatDuration(track.duration)}
</div>
</td>
</tr>
</tbody>
Expand Down
15 changes: 7 additions & 8 deletions src/app/track_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ export function TrackItem({ index, track, onClick }: ItemProps) {
return (
<tr
onClick={onClick}
className={[
styles.row,
onClick == undefined ? styles.queue_track : styles.track,
].join(" ")}
role={"gridcell"}
className={`${styles.row} ${
onClick == undefined ? styles.queue_track : styles.track
}`}
role="gridcell"
>
<td className={styles.index}>{`${index + 1}.`}</td>
<td className={styles.index}>{index}.</td>
<td>
<Image
alt="album cover"
Expand All @@ -41,7 +40,7 @@ export function TrackItem({ index, track, onClick }: ItemProps) {
src={track.album?.images[0].url ?? ""}
width={200}
height={200}
></Image>
/>
</td>
<td>
<div className={styles.title}>{track.name}</div>
Expand Down Expand Up @@ -69,7 +68,7 @@ export default function TrackList({ items, onClick }: ListProps) {
<tbody>
{items.map((track, index) => (
<TrackItem
index={index}
index={index + 2}
key={track.id}
track={track}
onClick={onClick}
Expand Down
29 changes: 6 additions & 23 deletions src/utils/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,16 @@ export async function getQueue() {
if (spotify === null) return null;

// Spotify-api.js does not support getting the user's queue (yet), so we do it manually
const queue = await spotify.fetch("/me/player/queue");
const { queue } = await spotify.fetch("/me/player/queue");

return {
currentlyPlaying:
queue.currently_playing?.type === "track"
? new Spotify.Track(queue.currently_playing, spotify)
: null,

queue: (queue.queue as any[]).flatMap((track) =>
track.type === "track" ? new Spotify.Track(track, spotify) : [],
),
};
return (queue as any[]).flatMap((track) =>
track.type === "track" ? new Spotify.Track(track, spotify) : [],
);
}

export async function getPlaybackState() {
export async function getCurrentPlayback() {
const spotify = await getSpotify();
if (spotify === null) return null;

// Spotify-api.js does not support getting the user's queue (yet), so we do it manually
const state = await spotify.fetch("/me/player/currently-playing");

return {
isPlaying: state.is_playing,
progress: state.progress_ms,
currentlyPlaying:
state.currently_playing_type === "track"
? new Spotify.Track(state.item, spotify)
: null,
};
return await spotify.user.player.getCurrentPlayback("track");
}
10 changes: 3 additions & 7 deletions src/utils/ui.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
export const formatDuration = (milliseconds: number) => {
const seconds = Math.floor((milliseconds / 1000) % 60);
const minutes = Math.floor((milliseconds / 1000 / 60) % 60);
const hours = Math.floor((milliseconds / 1000 / 60 / 60) % 24);
return [
hours.toString().padStart(2, "0"),
minutes.toString().padStart(2, "0"),
seconds.toString().padStart(2, "0"),
].join(":");
const minutes = Math.floor(milliseconds / 1000 / 60);

return `${minutes}:${seconds.toFixed().padStart(2, "0")}`;
};

0 comments on commit 80e0f95

Please sign in to comment.