From de957386fa30c154ede1fae27be40f53d8fd67d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= Date: Wed, 27 Dec 2023 18:01:33 +0000 Subject: [PATCH] Add live updates for timer and queue --- src/app/actions.ts | 7 +++---- src/app/timer.tsx | 27 +++++++++++++++++++++++++++ src/app/titlebar.tsx | 10 +++++++++- src/app/track_cover.tsx | 9 +++++---- 4 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 src/app/timer.tsx diff --git a/src/app/actions.ts b/src/app/actions.ts index 7e0fa4e..6628ab6 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -16,9 +16,8 @@ export async function searchTracks(query: string) { export async function pushTrack(uri: string) { const spotify = await getSpotify(); - if (spotify === null) - return Promise.reject(new Error("Spotify API not initialized")); + if (spotify === null) throw new Error("Spotify API not initialized"); - if ((await spotify.user.player.addItem(uri)) === true) Promise.resolve(); - else Promise.reject(new Error("Failed to push track")); + const success = await spotify.user.player.addItem(uri); + if (!success) throw new Error("Failed to push track"); } diff --git a/src/app/timer.tsx b/src/app/timer.tsx new file mode 100644 index 0000000..914f7d7 --- /dev/null +++ b/src/app/timer.tsx @@ -0,0 +1,27 @@ +"use client"; + +import { formatDuration } from "@/utils/ui"; +import { useEffect, useState } from "react"; + +interface TimerProps { + timestamp: number; + duration: number; +} + +export function Timer({ timestamp, duration }: TimerProps) { + const [now, setNow] = useState(Date.now()); + + useEffect(() => { + const interval = setInterval(() => setNow(Date.now()), 200); + + return () => clearInterval(interval); + }, []); + + return ( + <> + {formatDuration(Math.min(Math.max(now - timestamp, 0), duration))} + {" / "} + {formatDuration(duration)} + + ); +} diff --git a/src/app/titlebar.tsx b/src/app/titlebar.tsx index 403c621..8407705 100644 --- a/src/app/titlebar.tsx +++ b/src/app/titlebar.tsx @@ -1,18 +1,26 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import Image from "next/image"; import styles from "./titlebar.module.css"; import Search from "./search"; import Modal from "./modal"; +import { useRouter } from "next/navigation"; interface Props { active: boolean; } export default function TitleBar({ active }: Props) { + const router = useRouter(); const [isOpen, setIsOpen] = useState(false); + useEffect(() => { + const interval = setInterval(() => router.refresh(), 5 * 1000); + + return () => clearInterval(interval); + }, [router]); + return ( <>
diff --git a/src/app/track_cover.tsx b/src/app/track_cover.tsx index 04fd01a..aa21980 100644 --- a/src/app/track_cover.tsx +++ b/src/app/track_cover.tsx @@ -1,7 +1,7 @@ import Image from "next/image"; import * as Spotify from "spotify-api.js"; -import { formatDuration } from "@/utils/ui"; import styles from "./track_cover.module.css"; +import { Timer } from "./timer"; interface Props { currentPlayback: Spotify.CurrentPlayback; @@ -33,9 +33,10 @@ export default function TrackCover({ currentPlayback }: Props) {
- {formatDuration(currentPlayback.progress)} - {" / "} - {formatDuration(track.duration)} +