summaryrefslogtreecommitdiff
path: root/scrobbles.js
diff options
context:
space:
mode:
Diffstat (limited to 'scrobbles.js')
-rw-r--r--scrobbles.js69
1 files changed, 69 insertions, 0 deletions
diff --git a/scrobbles.js b/scrobbles.js
new file mode 100644
index 0000000..a05cd82
--- /dev/null
+++ b/scrobbles.js
@@ -0,0 +1,69 @@
+/*
+ * sophies.rocks
+ *
+ * Copyright (C) 2026 Zofia Szweda
+ *
+ * This file is part of sophies.rocks.
+ *
+ * sophies.rocks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * sophies.rocks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with sophies.rocks. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+const LIBREFM_USER = 'sophii.xyz';
+const LIBREFM_API_KEY = '00000000000000000000000000000000';
+const LIBREFM_CACHE_KEY = 'scrobbles-cache';
+const LIBREFM_CACHE_TTL_MS = 60_000;
+
+async function loadScrobbles(limit = 7) {
+ const cached = localStorage.getItem(LIBREFM_CACHE_KEY);
+ if (cached) {
+ const { data, ts } = JSON.parse(cached);
+ if (Date.now() - ts < LIBREFM_CACHE_TTL_MS) return data;
+ }
+
+ const url = `https://libre.fm/2.0/?method=user.getrecenttracks&user=${LIBREFM_USER}&api_key=${LIBREFM_API_KEY}&format=json&limit=${limit}`;
+ const res = await fetch(url);
+ if (!res.ok) throw new Error('Could not fetch scrobbles');
+ const data = await res.json();
+ const tracks = data.recenttracks?.track ?? [];
+
+ localStorage.setItem(LIBREFM_CACHE_KEY, JSON.stringify({ data: tracks, ts: Date.now() }));
+ return tracks;
+}
+
+async function renderScrobbles() {
+ const list = document.querySelector('#recent-scrobbles ul');
+ try {
+ const tracks = await loadScrobbles();
+ if (tracks.length === 0) {
+ list.innerHTML = '<li>No scrobbles yet.</li>';
+ return;
+ }
+ list.innerHTML = '';
+ tracks.forEach(track => {
+ const li = document.createElement('li');
+ const artist = track.artist?.['#text'] ?? '';
+ const nowPlaying = track['@attr']?.nowplaying === 'true';
+ li.innerHTML = `
+ <a href="${track.url}">${track.name}</a>
+ <div>${artist}${nowPlaying ? ' - listening now' : ''}</div>
+ `;
+ list.appendChild(li);
+ });
+ } catch (err) {
+ console.error('Failed to load libre.fm scrobbles:', err);
+ list.innerHTML = "<li>Couldn't load scrobbles right now.</li>";
+ }
+}
+
+renderScrobbles();