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