Changeset d68ee3a in Klonkt for src/assets/js/mod/playlist-editor.js
- Timestamp:
- 08/16/2026 01:53:01 PM (3 weeks ago)
- Branches:
- main
- Children:
- aebde2b
- Parents:
- d8f7d9c
- File:
-
- 1 edited
-
src/assets/js/mod/playlist-editor.js (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/mod/playlist-editor.js
rd8f7d9c rd68ee3a 6 6 7 7 import { pageData } from './lib.js'; 8 9 /** 10 * De teksten van deze modal, uit het gegevensblok van partials/playlist-editor.ejs. 11 * 12 * EIGEN BLOK en niet pageData(): die pakt met querySelector er EEN, en deze 13 * modal hangt onder pagina's die er zelf al een hebben. Een tweede blok zou 14 * daar genegeerd worden. 15 * 16 * De terugval is bewust de sleutelnaam en niet de Nederlandse tekst: ontbreekt 17 * er iets, dan zie je DAT er iets ontbreekt in plaats van een pagina die er 18 * half vertaald uitziet en waarvan niemand merkt welke helft. 19 */ 20 let _T = null; 21 function T(sleutel) { 22 if (_T === null) { 23 try { 24 const el = document.querySelector('script[type="application/json"][data-playlist-editor-i18n]'); 25 _T = el ? (JSON.parse(el.textContent) || {}) : {}; 26 } catch (e) { _T = {}; } 27 } 28 return _T[sleutel] != null ? _T[sleutel] : sleutel; 29 } 8 30 9 31 (function() { … … 54 76 if (Array.isArray(j.tracks)) tracks = j.tracks; 55 77 } catch (e) { 56 alert( 'Tracks ophalen mislukt');78 alert(T('e_tracks')); 57 79 return; 58 80 } 59 81 if (!tracks.length) { 60 alert( 'Geen audio-tracks beschikbaar. Upload eerst tracks via Admin → Audio.');82 alert(T('e_geen_tracks')); 61 83 return; 62 84 } … … 75 97 backdrop.className = 'pl-modal-backdrop'; 76 98 backdrop.innerHTML = ` 77 <div class="pl-modal" role="dialog" aria-label=" Playlist editor">99 <div class="pl-modal" role="dialog" aria-label="${T('dialoog')}"> 78 100 <div class="pl-modal-header"> 79 <h3>${isEdit ? '✎ Playlist bewerken' : '+ Nieuwe playlist'}</h3>80 <button type="button" class="pl-modal-close" aria-label=" Sluiten">×</button>101 <h3>${isEdit ? '✎ ' + T('t_edit') : '+ ' + T('t_new')}</h3> 102 <button type="button" class="pl-modal-close" aria-label="${T('sluiten')}">×</button> 81 103 </div> 82 104 <div class="pl-modal-body"> … … 85 107 <div class="pl-meta-grid"> 86 108 <label class="pl-field pl-field-full"> 87 <span> Titel *</span>109 <span>${T('titel')}</span> 88 110 <input type="text" id="pli-title" maxlength="200" autofocus value="${esc(initial.title)}"> 89 111 </label> 90 112 <label class="pl-field"> 91 <span> Artiest</span>113 <span>${T('artiest')}</span> 92 114 <input type="text" id="pli-artist" maxlength="200" value="${esc(initial.artist)}"> 93 115 </label> 94 116 <label class="pl-field"> 95 <span> Jaar</span>117 <span>${T('jaar')}</span> 96 118 <input type="number" id="pli-year" min="1900" max="2099" value="${initial.year || ''}"> 97 119 </label> 98 120 <label class="pl-field"> 99 <span> Type</span>121 <span>${T('type')}</span> 100 122 <select id="pli-kind"> 101 <option value="album" ${initial.kind === 'album' ? 'selected' : ''}>💿 Album (genummerd)</option>102 <option value="playlist" ${initial.kind === 'playlist' ? 'selected' : ''}>📃 Playlist (track-covers)</option>123 <option value="album" ${initial.kind === 'album' ? 'selected' : ''}>💿 ${T('k_album')}</option> 124 <option value="playlist" ${initial.kind === 'playlist' ? 'selected' : ''}>📃 ${T('k_playlist')}</option> 103 125 </select> 104 126 </label> 105 127 <label class="pl-field pl-uitgave"> 106 <span> Uitgavedatum</span>128 <span>${T('uitgave')}</span> 107 129 <input type="date" id="pli-release-date" value="${esc(initial.release_date || '')}"> 108 130 </label> 109 131 <label class="pl-field pl-uitgave"> 110 <span> MusicBrainz release-id</span>132 <span>${T('mb_release')}</span> 111 133 <input type="text" id="pli-mb-release" maxlength="36" spellcheck="false" 112 134 placeholder="00000000-0000-0000-0000-000000000000" … … 114 136 </label> 115 137 <div class="pl-field pl-field-full"> 116 <span> Cover</span>138 <span>${T('cover')}</span> 117 139 <div class="pl-cover-row"> 118 140 <span class="pl-cover-thumb" id="pli-cover-thumb"> … … 121 143 : `<span class="pl-cover-empty">🎨</span>`} 122 144 </span> 123 <input type="text" id="pli-cover" placeholder=" https://… of upload" value="${esc(initial.cover)}" style="flex:1">145 <input type="text" id="pli-cover" placeholder="${T('cover_url')}" value="${esc(initial.cover)}" style="flex:1"> 124 146 </div> 125 147 <div class="pl-cover-upload-row"> 126 148 <input type="file" id="pli-cover-file" accept="image/jpeg,image/png,image/webp,image/gif" hidden> 127 <button type="button" class="pl-btn-small" id="pli-cover-pick">📷 Foto kiezen…</button>149 <button type="button" class="pl-btn-small" id="pli-cover-pick">📷 ${T('cover_kies')}</button> 128 150 <span class="pl-cover-status" id="pli-cover-status"></span> 129 151 </div> … … 131 153 </div> 132 154 <div class="pl-section-title"> 133 Tracks in playlist<span class="pl-track-count" id="pli-count">0</span>134 <small> (sleep ⠿ om te ordenen)</small>155 ${T('tracks_in')} <span class="pl-track-count" id="pli-count">0</span> 156 <small>${T('sleep_hint')}</small> 135 157 </div> 136 158 <div id="pli-selected" class="pl-selected-list"></div> 137 159 </div> 138 160 <div class="pl-editor-right"> 139 <div class="pl-section-title"> Beschikbare tracks</div>140 <input type="search" id="pli-search" placeholder=" Zoek..." class="pl-search-input">161 <div class="pl-section-title">${T('beschikbaar')}</div> 162 <input type="search" id="pli-search" placeholder="${T('zoek')}" class="pl-search-input"> 141 163 <div id="pli-available" class="pl-available-list"></div> 142 164 </div> … … 144 166 </div> 145 167 <div class="pl-modal-footer"> 146 <button type="button" class="btn" id="pli-cancel"> Annuleren</button>168 <button type="button" class="btn" id="pli-cancel">${T('annuleren')}</button> 147 169 <button type="button" class="btn btn-primary" id="pli-save" disabled> 148 ${isEdit ? 'Opslaan' : 'Aanmaken'}170 ${isEdit ? T('opslaan') : T('aanmaken')} 149 171 </button> 150 172 </div> … … 199 221 // requireAuth) dat een /media/-URL teruggeeft — dat heeft GEEN playlist-id 200 222 // nodig, dus uploaden kan ook al vóór het aanmaken. De URL belandt in het 201 // cover-veld en wordt bij 'Aanmaken'/'Opslaan'met de playlist meegestuurd.223 // cover-veld en wordt bij het opslaan met de playlist meegestuurd. 202 224 const coverFileInput = $('#pli-cover-file'); 203 225 const coverPickBtn = $('#pli-cover-pick'); … … 210 232 if (!file) return; 211 233 if (!/^image\//.test(file.type)) { 212 coverStatus.textContent = 'Alleen afbeeldingen';234 coverStatus.textContent = T('e_alleen_afb'); 213 235 coverStatus.className = 'pl-cover-status is-error'; 214 236 return; 215 237 } 216 coverStatus.textContent = 'Uploaden…';238 coverStatus.textContent = T('bezig'); 217 239 coverStatus.className = 'pl-cover-status'; 218 240 const fd = new FormData(); … … 223 245 ); 224 246 const j = await r.json(); 225 if (!r.ok || !j.url) throw new Error(j.error || 'Upload mislukt');247 if (!r.ok || !j.url) throw new Error(j.error || T('e_upload')); 226 248 const url = j.url || ''; 227 249 coverEl.value = url; … … 232 254 coverStatus.className = 'pl-cover-status is-ok'; 233 255 } catch (err) { 234 coverStatus.textContent = 'Mislukt: '+ err.message;256 coverStatus.textContent = T('e_mislukt') + err.message; 235 257 coverStatus.className = 'pl-cover-status is-error'; 236 258 } … … 245 267 countEl.textContent = selected.length; 246 268 if (selected.length === 0) { 247 selectedEl.innerHTML = '<div class="pl-empty"> Klik tracks rechts om toe te voegen.</div>';269 selectedEl.innerHTML = '<div class="pl-empty">' + T('leeg_sel') + '</div>'; 248 270 updateSaveBtn(); 249 271 return; … … 256 278 : `<span class="pl-row-cover pl-row-cover-empty">♪</span>`; 257 279 return `<div class="pl-row" data-id="${esc(id)}" data-pos="${i}"> 258 <span class="pl-row-handle" aria-label=" Verslepen">⠿</span>280 <span class="pl-row-handle" aria-label="${T('versleep')}">⠿</span> 259 281 <span class="pl-row-num">${i + 1}</span> 260 282 ${cover} … … 263 285 ${t.artist ? `<span class="pl-row-artist">${esc(t.artist)}</span>` : ''} 264 286 </span> 265 <button type="button" class="pl-row-x" data-id="${esc(id)}" aria-label=" Verwijderen">×</button>287 <button type="button" class="pl-row-x" data-id="${esc(id)}" aria-label="${T('verwijder')}">×</button> 266 288 </div>`; 267 289 }).join(''); … … 286 308 }); 287 309 if (matches.length === 0) { 288 availEl.innerHTML = '<div class="pl-empty"> Geen resultaten.</div>';310 availEl.innerHTML = '<div class="pl-empty">' + T('geen_res') + '</div>'; 289 311 return; 290 312 } … … 297 319 ? `<span class="pl-row-cover"><img src="${esc(t.cover)}" alt=""></span>` 298 320 : `<span class="pl-row-cover pl-row-cover-empty">♪</span>`; 299 return `<div class="${cls.join(' ')}" data-id="${esc(t.id)}" ${t.playable ? '' : 'title="Track heeft geen audio-bestand"'}>321 return `<div class="${cls.join(' ')}" data-id="${esc(t.id)}" ${t.playable ? '' : `title="${T('geen_audio')}"`}> 300 322 ${cover} 301 323 <span class="pl-row-info"> … … 391 413 const orig = saveBtn.textContent; 392 414 saveBtn.disabled = true; 393 saveBtn.textContent = 'Opslaan...';415 saveBtn.textContent = T('bezig_opslaan'); 394 416 395 417 const payload = { … … 410 432 const j = await api('POST', url, payload); 411 433 if (!j.ok) { 412 alert( 'Opslaan mislukt: '+ (j.error || 'onbekend'));434 alert(T('e_opslaan') + (j.error || 'onbekend')); 413 435 saveBtn.disabled = false; 414 436 saveBtn.textContent = orig; … … 421 443 } 422 444 } catch (err) { 423 alert( 'Opslaan mislukt: '+ err.message);445 alert(T('e_opslaan') + err.message); 424 446 saveBtn.disabled = false; 425 447 saveBtn.textContent = orig;
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)