android: the library's file stats on the cards, the artist's own plays, the thumbnail prewarm
The desktop Library's per-record file stats on the phone (library_album_stats, one call for the whole library): FLAC 24/96 or MP3 320k badges on the cards, the size on the list rows and the record page. The artist page's own listening (artist_play_stats): the time played as a chip, the most played track under "On this phone". The whole-library thumbnail warm a moment after boot, at the cards' edge, one decode at a time behind the tiles' gate.
This commit is contained in:
1 parent
26928b706d
commit
991d52d0cc
8 files changed
+63
-11
No files matched your search
@@ -9,6 +9,8 @@ export const lib = $state({
|
||||
recents: [], // library rows only, with an album_id
|
||||
follows: [],
|
||||
playlists: [],
|
||||
/** album id → { secs, bytes, avg_kbps, bit_depth, sample_rate, formats, last_played_at } — the desktop's library_album_stats */
|
||||
stats: {},
|
||||
version: "",
|
||||
username: null,
|
||||
loaded: false,
|
||||
@@ -104,6 +106,7 @@ export async function watchLibrary() {
|
||||
timer = setTimeout(async () => {
|
||||
try { lib.albums = await api.libraryAlbums(); } catch { /* keep */ }
|
||||
await refreshRecents();
|
||||
void refreshStats();
|
||||
}, 600);
|
||||
});
|
||||
/* a playlist mutation (the desktop's commands emit it) re-lists them */
|
||||
@@ -122,6 +125,24 @@ export async function loadLibrary() {
|
||||
try { lib.follows = (await api.followedArtists()) || []; } catch { lib.follows = []; }
|
||||
try { lib.playlists = (await api.listPlaylists()) || []; } catch { lib.playlists = []; }
|
||||
lib.loaded = true;
|
||||
void refreshStats();
|
||||
}
|
||||
|
||||
/** The files' own aggregates per record — one call for the whole library
|
||||
* (the desktop's RECENTS_FLOOR_SECS, 45, is the floor a play must reach
|
||||
* to count as the last one). */
|
||||
export async function refreshStats() {
|
||||
try {
|
||||
const rows = (await api.libraryAlbumStats(45)) || [];
|
||||
lib.stats = Object.fromEntries(rows.map((r) => [r.album_id, r]));
|
||||
} catch { /* the cards stay quiet */ }
|
||||
}
|
||||
/** "FLAC 24/96" for a lossless record, "MP3 320k" for a lossy one. */
|
||||
export function statLabel(st) {
|
||||
if (!st || !st.formats?.length) return "";
|
||||
const f = String(st.formats[0]).toUpperCase();
|
||||
if (st.bit_depth && st.sample_rate) return f + " " + st.bit_depth + "/" + (st.sample_rate % 1000 === 0 ? st.sample_rate / 1000 : (st.sample_rate / 1000).toFixed(1));
|
||||
return st.avg_kbps ? f + " " + st.avg_kbps + "k" : f;
|
||||
}
|
||||
|
||||
export async function refreshPlaylists() {
|
||||
|
||||
Reference in new issue
Block a user