Changeset 5190152 in Klonkt for src/assets/js


Ignore:
Timestamp:
07/19/2026 05:38:25 PM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
e9c9ae1
Parents:
feced2c
git-author:
Robin <roboburr@…> (07/19/2026 05:38:00 PM)
git-committer:
Robin <roboburr@…> (07/19/2026 05:38:25 PM)
Message:

Feature: rich editor on the edit forms too (klonkt-demo-c7f, last slice)

Editing a sent reply (Messages + the interact page's manage list) now opens the
same shared editor as new replies, instead of a bare textarea. Prutter stays
plain on purpose (Robin: not part of this).

  • reply-editor partial: initialHtml/initialText prefill for edit mode, and a noAttach flag that omits the media UI (an edit never touches attachments). JS grew canAttach guards so the component runs without the attach elements; pasted files are still swallowed there rather than becoming base64 blobs.
  • deliverOutboxUpdate(site, id, text, {html, language}): rich path with the same sanitize + enrichment + mention-first-paragraph logic as deliverReply; language updated via COALESCE (bogus codes keep the old one); attachments survive untouched. Plain path unchanged.
  • /fediverse/:id/edit passes content + language; listOutbox and the Messages sent-projection carry language so the select preselects correctly.
  • The interact page's edit-toggle focuses the rich editor when present.

2 new tests (93 green). Browser-verified on /messages: prefilled editor
(mention-stripped HTML + plain fallback + language preselected, no paperclip),
edit saved -> content replaced with markup, mention re-attached inline,
language nl->en, no console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/assets/js/reply-editor.js

    rfeced2c r5190152  
    3636    var attField = form.querySelector('input[name="attachments"]');
    3737    var fileInput = form.querySelector('.re-file');
     38    var canAttach = !!(attWrap && attField && fileInput);   // edit mode renders without media
    3839    var attachments = [];
    3940
    4041    function syncAtt() {
     42      if (!canAttach) return;
    4143      attField.value = attachments.length ? JSON.stringify(attachments) : '';
    4244      attWrap.hidden = attachments.length === 0;
     
    6264    }
    6365    function uploadFiles(files) {
     66      if (!canAttach) return;
    6467      Array.prototype.forEach.call(files, function (file) {
    6568        if (!/^(image|audio|video)\//.test(file.type) || attachments.length >= 4) return;
     
    9396      e.preventDefault();
    9497      var cmd = btn.getAttribute('data-cmd');
    95       if (cmd === 'attach') { fileInput.click(); return; }   // no editor focus: keeps the picker usable on mobile
     98      if (cmd === 'attach') { if (fileInput) fileInput.click(); return; }   // no editor focus: keeps the picker usable on mobile
    9699      ed.focus();
    97100      if (cmd === 'bold') document.execCommand('bold');
     
    104107      }
    105108    });
    106     fileInput.addEventListener('change', function () {
     109    if (fileInput) fileInput.addEventListener('change', function () {
    107110      uploadFiles(fileInput.files);
    108111      fileInput.value = '';
     
    114117      var cd = e.clipboardData || window.clipboardData;
    115118      if (cd.files && cd.files.length) {
    116         e.preventDefault();
    117         uploadFiles(cd.files);
     119        e.preventDefault();            // never let the browser inline-paste a file as base64
     120        uploadFiles(cd.files);         // no-op without the attach UI (edit mode)
    118121        return;
    119122      }
     
    125128
    126129    // Drag/drop media onto the editor.
     130    if (canAttach) {
    127131    ed.addEventListener('dragover', function (e) {
    128132      if (e.dataTransfer && Array.prototype.some.call(e.dataTransfer.types || [], function (t) { return t === 'Files'; })) {
     
    139143      }
    140144    });
     145    }
    141146
    142147    // Full-screen compose on mobile: enter on focus, leave via ×.
Note: See TracChangeset for help on using the changeset viewer.