Last.FM live tile. #3

Merged
mikhail merged 4 commits from tiles/lastfm into main 2025-12-04 08:20:35 +02:00
Showing only changes of commit 99feee6179 - Show all commits

View file

@ -6,6 +6,8 @@ Music tile.
<script lang="ts"> <script lang="ts">
import type { RecentTrack } from "$lib/server/clients/last-fm"; import type { RecentTrack } from "$lib/server/clients/last-fm";
import { onDestroy, onMount } from "svelte";
import Tile from "../common/Tile.svelte"; import Tile from "../common/Tile.svelte";
import TileImagePage from "../pages/TileImagePage.svelte"; import TileImagePage from "../pages/TileImagePage.svelte";
import TileTextPage from "../pages/TileTextPage.svelte"; import TileTextPage from "../pages/TileTextPage.svelte";
@ -13,20 +15,63 @@ Music tile.
import iconLastFm from "$lib/assets/icons/last-fm.webp"; import iconLastFm from "$lib/assets/icons/last-fm.webp";
import TileIconPage from "../pages/TileIconPage.svelte"; import TileIconPage from "../pages/TileIconPage.svelte";
const { /**
* Update interval delay (in milliseconds).
*/
const UPDATE_INTERVAL_DELAY = 1 * 60 * 1000;
/**
* Link to the Last.FM website.
*/
const LASTFM_URL = "https://last.fm";
/**
* Properties.
*/
let {
row, row,
column, column,
size, size,
track, track: initialTrack,
}: { }: {
row: number; row: number;
column: number; column: number;
size: "small" | "medium" | "wide" | "large"; size: "small" | "medium" | "wide" | "large";
track?: RecentTrack; track?: RecentTrack;
} = $props(); } = $props();
/**
* Current track data.
*/
let track = $state(initialTrack);
/**
* Update interval.
*/
let updateInterval: NodeJS.Timeout;
/**
* Fetch the current track and put it in state.
*/
async function updateTrack() {
const response = await fetch("/api/music");
if (!response.ok) {
return; // NOTE: if non-ok status, don't update
}
track = await response.json();
}
// NOTE: update interval set/clear functions
onMount(() => {
updateInterval = setInterval(updateTrack, UPDATE_INTERVAL_DELAY);
});
onDestroy(() => clearInterval(updateInterval));
</script> </script>
<Tile {row} {column} {size} icon={iconLastFm} link={track.url}> <Tile {row} {column} {size} icon={iconLastFm} link={track?.url ?? LASTFM_URL}>
{#if track} {#if track}
<TileImagePage image={track.cover} /> <TileImagePage image={track.cover} />
<TileTextPage <TileTextPage