// De afspeellijst-editor -- verplaatst uit inline script, shaer-bqr.
//
// Servergegevens komen uit pageData(); interpolatie kan niet in een statisch
// bestand. Inline script wordt bovendien geweigerd zodra deze pagina via een
// link BINNEN de site binnenkomt (shaer-0i6).
import { pageData } from './lib.js';
/**
* De teksten van deze modal, uit het gegevensblok van partials/playlist-editor.ejs.
*
* EIGEN BLOK en niet pageData(): die pakt met querySelector er EEN, en deze
* modal hangt onder pagina's die er zelf al een hebben. Een tweede blok zou
* daar genegeerd worden.
*
* De terugval is bewust de sleutelnaam en niet de Nederlandse tekst: ontbreekt
* er iets, dan zie je DAT er iets ontbreekt in plaats van een pagina die er
* half vertaald uitziet en waarvan niemand merkt welke helft.
*/
let _T = null;
function T(sleutel) {
if (_T === null) {
try {
const el = document.querySelector('script[type="application/json"][data-playlist-editor-i18n]');
_T = el ? (JSON.parse(el.textContent) || {}) : {};
} catch (e) { _T = {}; }
}
return _T[sleutel] != null ? _T[sleutel] : sleutel;
}
(function() {
// Idempotency: if window.openPlaylistEditor already defined (multiple
// partial includes on a single page), skip re-binding.
if (typeof window.openPlaylistEditor === 'function') return;
const CSRF = pageData().csrf || '';
function esc(s) {
return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({
'&':'&','<':'<','>':'>','"':'"',"'":'''
}[c]));
}
function fmtDur(sec) {
if (!sec) return '';
const m = Math.floor(sec / 60), s = sec % 60;
return `${m}:${String(s).padStart(2, '0')}`;
}
async function api(method, url, body) {
const opts = {
method, credentials: 'same-origin',
headers: { 'X-CSRF-Token': CSRF },
};
if (body !== undefined) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(body);
}
const r = await fetch(url, opts);
return r.json();
}
/**
* Public entry point: open the editor.
* opts: { mode: 'create'|'edit', id?, onSaved? }
* onSaved is called with { id, playlist } after a successful save.
*/
window.openPlaylistEditor = async function(opts) {
opts = opts || {};
const mode = opts.mode === 'edit' ? 'edit' : 'create';
const isEdit = mode === 'edit';
// Load all audio tracks for the picker
let tracks = [];
try {
const j = await api('GET', '/admin/playlists/api/tracks');
if (Array.isArray(j.tracks)) tracks = j.tracks;
} catch (e) {
alert(T('e_tracks'));
return;
}
if (!tracks.length) {
alert(T('e_geen_tracks'));
return;
}
// Existing playlist data when editing
let initial = { title: '', artist: '', year: '', cover: '', kind: 'album', release_date: '', mb_release_id: '', track_ids: [] };
if (isEdit && opts.id) {
try {
const j = await api('GET', '/admin/playlists/api/' + encodeURIComponent(opts.id));
if (j.ok) initial = { ...initial, ...j.playlist };
} catch (e) {}
}
// ── DOM ────────────────────────────────────────────────────────
const backdrop = document.createElement('div');
backdrop.className = 'pl-modal-backdrop';
backdrop.innerHTML = `