Changeset 2086ea2 in Klonkt for src/assets/js
- Timestamp:
- 08/12/2026 09:16:09 PM (3 months ago)
- Children:
- 39dab6b
- Parents:
- 5412cbb
- File:
-
- 1 edited
-
src/assets/js/ward.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/ward.js
r5412cbb r2086ea2 423 423 } 424 424 425 /** De controle kost per guardian een remote fetch, dus hij komt ná het tekenen. *//** De controle kost per guardian een remote fetch, dus hij komt ná het tekenen. */ 425 /** 426 * De composer: schrijven met foto, geluid of video. 427 * 428 * De media gaan eerst apart naar /ward/api/upload (dezelfde bak als de app), 429 * en de post draagt daarna alleen de url mee. Zo blijft de post-payload klein 430 * en kan de server elke upload los valideren en verrijken (poster, waveform). 431 */ 432 function wireComposer() { 433 const dlg = document.getElementById('compose-dialog'); 434 const openBtn = document.getElementById('compose-open'); 435 const text = document.getElementById('compose-text'); 436 const mediaBox = document.getElementById('compose-media'); 437 const status = document.getElementById('compose-status'); 438 const sendBtn = document.getElementById('compose-send'); 439 let media = []; // { url, mediaType, name } 440 let uploading = false; 441 442 function reset() { 443 text.value = ''; 444 media = []; 445 mediaBox.replaceChildren(); 446 status.textContent = ''; 447 updateSend(); 448 } 449 function updateSend() { 450 // Een lege post kan niet: tekst OF media, en nooit tijdens een upload. 451 sendBtn.disabled = (!text.value.trim() && !media.length) || uploading; 452 } 453 function renderMedia() { 454 mediaBox.replaceChildren(); 455 media.forEach((m, i) => { 456 const chip = el('div', 'media-chip'); 457 if (m.mediaType.startsWith('image/')) { 458 const img = el('img'); img.src = m.url; img.alt = m.name || ''; chip.append(img); 459 } else { 460 chip.append(el('span', 'kind', m.mediaType.startsWith('audio/') ? '🎤' : '🎬')); 461 chip.append(el('span', 'name', m.name || '')); 462 } 463 const x = el('button', 'drop', '✕'); x.type = 'button'; 464 x.addEventListener('click', () => { media.splice(i, 1); renderMedia(); updateSend(); }); 465 chip.append(x); 466 mediaBox.append(chip); 467 }); 468 } 469 470 async function upload(file) { 471 if (media.length >= 4) return; 472 // 32 MB is de servergrens; hier alvast vangen scheelt een mislukte upload. 473 if (file.size > 32 * 1024 * 1024) { status.textContent = state.strings.tooBig; return; } 474 uploading = true; status.textContent = state.strings.uploading; updateSend(); 475 try { 476 const fd = new FormData(); 477 fd.append('file', file); 478 const r = await fetch('/ward/api/upload', { method: 'POST', body: fd }); 479 if (r.ok) { media.push(await r.json()); renderMedia(); status.textContent = ''; } 480 else status.textContent = (await r.json().catch(() => ({}))).error === 'media_type' 481 ? 'Dat bestandstype kan niet.' : 'Uploaden lukte niet.'; 482 } catch { status.textContent = 'Uploaden lukte niet.'; } 483 uploading = false; updateSend(); 484 } 485 486 openBtn.addEventListener('click', () => { reset(); dlg.showModal(); }); 487 document.getElementById('compose-cancel').addEventListener('click', () => dlg.close()); 488 text.addEventListener('input', updateSend); 489 490 dlg.querySelectorAll('input[type=file]').forEach((inp) => { 491 inp.addEventListener('change', () => { 492 if (inp.files[0]) upload(inp.files[0]); 493 inp.value = ''; // zelfde bestand opnieuw kunnen kiezen 494 }); 495 }); 496 497 sendBtn.addEventListener('click', async () => { 498 if (sendBtn.disabled) return; 499 sendBtn.disabled = true; 500 try { 501 const r = await fetch('/ward/api/post', { 502 method: 'POST', 503 headers: { 'Content-Type': 'application/json' }, 504 body: JSON.stringify({ 505 text: text.value, 506 media, 507 visibility: document.getElementById('compose-vis').value, 508 }), 509 }); 510 if (r.ok) { dlg.close(); loadFeed(); } 511 else status.textContent = 'Plaatsen lukte niet.'; 512 } catch { status.textContent = 'Plaatsen lukte niet.'; } 513 updateSend(); 514 }); 515 } 516 517 /** De controle kost per guardian een remote fetch, dus hij komt ná het tekenen. */ 426 518 async function loadChecks() { 427 519 if (!state.guardians.length) return; … … 449 541 wireBuoy(); 450 542 wireSky(); 543 wireComposer(); 451 544 loadFeed(); 452 545 renderOffers();
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)