From 14c0dea7e46752624cf358e6d5bae5a08371343c Mon Sep 17 00:00:00 2001 From: Honey Date: Sat, 8 Aug 2026 12:55:29 +0200 Subject: [PATCH] =?UTF-8?q?fix(scrobble):=20'Alles'=20(all-time)=20stats?= =?UTF-8?q?=20returned=20nothing=20=E2=80=94=20from=3D0=20mapped=20to=20no?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The client sends from=0 for the all-time range, but the string "0" is truthy, so it was routed through _toEpochSec which maps 0 -> now, producing an empty window. Parse 'from' directly (0/absent/invalid -> all-time) instead. Affects web + Android. Co-Authored-By: Claude Opus 4.8 --- scrobble/scrobble-server.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scrobble/scrobble-server.js b/scrobble/scrobble-server.js index 77111d1..1839e0b 100644 --- a/scrobble/scrobble-server.js +++ b/scrobble/scrobble-server.js @@ -173,9 +173,11 @@ app.get('/scrobble/stats', async (req, res) => { if (!user) return res.status(401).json({ error: 'unauthorized' }); const tz = Math.trunc(Number(req.query.tz) || 0); - // Default window = all time. Route through _toEpochSec only when provided (it maps 0 → now). - const from = req.query.from ? _toEpochSec(req.query.from) : 0; - const to = req.query.to ? _toEpochSec(req.query.to) : Math.floor(Date.now() / 1000) + 1; + // Default window = all time. Parse `from` directly — do NOT route through _toEpochSec, which maps + // 0 → now (so the client's explicit from=0 for "all time" would wrongly become an empty window). + const fromN = Number(req.query.from); + const from = Number.isFinite(fromN) && fromN > 0 ? (fromN > 1e12 ? Math.floor(fromN / 1000) : Math.floor(fromN)) : 0; + const to = req.query.to ? _toEpochSec(req.query.to) : Math.floor(Date.now() / 1000) + 1; const bucket = _STATS_FMT[req.query.bucket] ? req.query.bucket : 'day'; const fmt = _STATS_FMT[bucket]; const limit = Math.min(Math.max(parseInt(req.query.limit, 10) || 20, 1), 100);