feat: sort genre pills by total play count via backend
Page loads instantly with song-count order, then silently re-sorts once the backend aggregates play counts across all songs. Result cached 20 min server-side to avoid repeated full-library fetches. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
790f02e5b4
commit
4f83eebe79
3 files changed
+39
-2
No files matched your search
@@ -18,7 +18,7 @@ const CONFIG = require('./lib/config');
|
||||
const { jobs, updateJob, log } = require('./lib/jobs');
|
||||
const { lookupItunesTrackMeta, fetchItunesTracks, searchItunesAlbumTracks } = require('./lib/metadata');
|
||||
const { downloadTrack, downloadAlbumTracks } = require('./lib/downloader');
|
||||
const { buildRomajiIndex, clearRomajiCache, isTokenizerReady } = require('./lib/romaji');
|
||||
const { buildRomajiIndex, clearRomajiCache, isTokenizerReady, fetchNdSongs } = require('./lib/romaji');
|
||||
|
||||
// ─── INIT ─────────────────────────────────────────────────────────────────────
|
||||
const app = express();
|
||||
@@ -92,6 +92,32 @@ app.delete('/api/romaji-index', (req, res) => {
|
||||
res.json({ ok: true });
|
||||
});
|
||||
|
||||
// GET /api/genre-playcounts?ndUrl=...&user=...&pass=...
|
||||
// Returns { [genre]: totalPlayCount } sorted by plays desc, cached for 20 min.
|
||||
const _genrePlayCache = new Map();
|
||||
const GENRE_PLAY_TTL = 20 * 60 * 1000;
|
||||
app.get('/api/genre-playcounts', async (req, res) => {
|
||||
const { ndUrl, user, pass } = req.query;
|
||||
if (!ndUrl || !user || !pass) return res.status(400).json({ error: 'missing params' });
|
||||
const key = `${ndUrl}|${user}`;
|
||||
const cached = _genrePlayCache.get(key);
|
||||
if (cached && Date.now() - cached.ts < GENRE_PLAY_TTL) return res.json(cached.data);
|
||||
try {
|
||||
const songs = await fetchNdSongs(ndUrl, user, pass);
|
||||
const totals = {};
|
||||
for (const s of songs) {
|
||||
const g = s.genre;
|
||||
if (!g || !(s.playCount > 0)) continue;
|
||||
totals[g] = (totals[g] || 0) + s.playCount;
|
||||
}
|
||||
_genrePlayCache.set(key, { ts: Date.now(), data: totals });
|
||||
res.json(totals);
|
||||
} catch (e) {
|
||||
console.error('genre-playcounts error:', e);
|
||||
res.status(500).json({ error: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/spotify/track-artwork', async (req, res) => {
|
||||
const tracks = req.body.tracks || [];
|
||||
if (!tracks.length) return res.json({ results: [] });
|
||||
|
||||
Reference in new issue
Block a user