| 1 | // Afspeellijsten in beheer -- verplaatst uit inline script, shaer-bqr.
|
|---|
| 2 | //
|
|---|
| 3 | // Servergegevens (het csrf-token en drie teksten) komen uit pageData();
|
|---|
| 4 | // interpolatie kan niet in een statisch bestand.
|
|---|
| 5 |
|
|---|
| 6 | import { pageData } from './lib.js';
|
|---|
| 7 |
|
|---|
| 8 | // Element-bedrading per render, dus init() per paginawissel (shaer-5s1).
|
|---|
| 9 | export function init() { run(); }
|
|---|
| 10 |
|
|---|
| 11 | function run() {
|
|---|
| 12 | (function() {
|
|---|
| 13 | const _d = pageData();
|
|---|
| 14 | const csrf = _d.csrf || '';
|
|---|
| 15 |
|
|---|
| 16 | document.getElementById('pl-new-btn')?.addEventListener('click', () => {
|
|---|
| 17 | if (typeof window.openPlaylistEditor === 'function') {
|
|---|
| 18 | window.openPlaylistEditor({ mode: 'create', onSaved: () => location.reload() });
|
|---|
| 19 | }
|
|---|
| 20 | });
|
|---|
| 21 |
|
|---|
| 22 | // Click-to-copy on shortcodes
|
|---|
| 23 | document.querySelectorAll('[data-copy]').forEach(el => {
|
|---|
| 24 | el.addEventListener('click', async () => {
|
|---|
| 25 | try {
|
|---|
| 26 | await navigator.clipboard.writeText(el.dataset.copy);
|
|---|
| 27 | el.classList.add('is-copied');
|
|---|
| 28 | const original = el.textContent;
|
|---|
| 29 | el.textContent = '✓ ' + (_d.copied || '');
|
|---|
| 30 | setTimeout(() => { el.classList.remove('is-copied'); el.textContent = original; }, 1200);
|
|---|
| 31 | } catch (_) { /* fall back to selection */ }
|
|---|
| 32 | });
|
|---|
| 33 | });
|
|---|
| 34 |
|
|---|
| 35 | document.querySelectorAll('[data-pl-edit]').forEach(btn => {
|
|---|
| 36 | btn.addEventListener('click', () => {
|
|---|
| 37 | if (typeof window.openPlaylistEditor === 'function') {
|
|---|
| 38 | window.openPlaylistEditor({ mode: 'edit', id: btn.dataset.id, onSaved: () => location.reload() });
|
|---|
| 39 | }
|
|---|
| 40 | });
|
|---|
| 41 | });
|
|---|
| 42 |
|
|---|
| 43 | document.querySelectorAll('[data-pl-delete]').forEach(btn => {
|
|---|
| 44 | btn.addEventListener('click', async () => {
|
|---|
| 45 | const id = btn.dataset.id;
|
|---|
| 46 | const title = btn.dataset.title || id;
|
|---|
| 47 | if (!confirm((_d.delConfirm || '').replace('{title}', title))) return;
|
|---|
| 48 | try {
|
|---|
| 49 | const r = await fetch(`/admin/playlists/api/${encodeURIComponent(id)}/delete`, {
|
|---|
| 50 | method: 'POST',
|
|---|
| 51 | headers: { 'X-CSRF-Token': csrf },
|
|---|
| 52 | credentials: 'same-origin',
|
|---|
| 53 | });
|
|---|
| 54 | const j = await r.json();
|
|---|
| 55 | if (j.ok) location.reload();
|
|---|
| 56 | else alert((_d.delFailed || '') + ': ' + (j.error || ''));
|
|---|
| 57 | } catch (err) {
|
|---|
| 58 | alert((_d.delFailed || '') + ': ' + err.message);
|
|---|
| 59 | }
|
|---|
| 60 | });
|
|---|
| 61 | });
|
|---|
| 62 |
|
|---|
| 63 | // P52 — deep-link from playlist embed (?edit=<id>) auto-opens the editor.
|
|---|
| 64 | // openPlaylistEditor is defined synchronously by the included partial, so
|
|---|
| 65 | // it's available by the time this IIFE runs.
|
|---|
| 66 | (function deepLinkEdit() {
|
|---|
| 67 | const params = new URLSearchParams(location.search);
|
|---|
| 68 | const editId = params.get('edit');
|
|---|
| 69 | if (!editId) return;
|
|---|
| 70 | if (typeof window.openPlaylistEditor !== 'function') return;
|
|---|
| 71 | // Strip the query param immediately so reload after save doesn't re-open.
|
|---|
| 72 | history.replaceState({}, '', location.pathname);
|
|---|
| 73 | window.openPlaylistEditor({
|
|---|
| 74 | mode: 'edit',
|
|---|
| 75 | id: editId,
|
|---|
| 76 | onSaved: () => location.reload(),
|
|---|
| 77 | });
|
|---|
| 78 | })();
|
|---|
| 79 | })();
|
|---|
| 80 | }
|
|---|