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);