import { getItem, getAlbumTracks } from '../embyApi.js'; import { createParty } from '../party.js'; import { navigate } from '../router.js'; import { escapeHtml, formatDuration } from '../tiles.js'; const TICKS_PER_SECOND = 10000000; // Emby/.NET convention: 1 tick = 100ns, same as everywhere else this app touches durations/positions /** Route `/album/:id` - the last level of the music hierarchy: one album's * tracks, each startable as its own listen party (mirrors series.js's * episode list, but flat - an album has no further sub-level the way a * series' seasons do). */ export async function renderAlbum(root, params) { const albumId = params.id; root.innerHTML = '

Chargement...

'; let album; let tracks; try { [album, tracks] = await Promise.all([getItem(albumId), getAlbumTracks(albumId)]); } catch (err) { root.innerHTML = '

Impossible de charger cet album.

'; return; } root.innerHTML = `

${escapeHtml(album.name)}${album.year ? ` (${album.year})` : ''}

${album.artistName ? `

${escapeHtml(album.artistName)}

` : ''} Voir sur Emby
`; root.querySelector('#back').addEventListener('click', () => history.back()); const listEl = root.querySelector('#trackList'); if (!tracks.length) { listEl.innerHTML = '

Aucun morceau dans cet album.

'; return; } listEl.innerHTML = tracks.map((t) => `
${t.indexNumber != null ? t.indexNumber : ''} ${escapeHtml(t.name)} ${t.durationTicks ? formatDuration(t.durationTicks / TICKS_PER_SECOND) : ''}
`).join(''); listEl.querySelectorAll('.startPartyBtn').forEach((btn) => { btn.addEventListener('click', async () => { btn.disabled = true; btn.textContent = 'Démarrage...'; try { const party = await createParty(btn.dataset.itemId); navigate(`/party/${party.partyId}`); } catch (err) { alert(err.message); btn.disabled = false; btn.textContent = 'Écouter ensemble'; } }); }); }