Feature: rich replies phase 1 — shared editor, mobile full-screen, language (klonkt-demo-c7f)
Replying to fediverse comments used bare textareas in four places. This adds
ONE shared, progressively-enhanced editor component and mounts it on the two
new-reply spots (inline thread reply in fedi-node, and authorize_interaction);
the edit forms and prutter follow with the media phase.
- partials/reply-editor.ejs + assets/js/reply-editor.js + css: renders a plain
textarea that works without JS; the JS upgrades it to a contenteditable with
a small toolbar (bold/italic/link/list/quote) and a language select. Assets
load once per render even when the partial repeats per comment.
- Mobile (max-width 700px): focusing the editor opens a FULL-SCREEN compose
overlay (top bar with cancel and send, scroll lock), the right pattern on
phones. Two real-world fixes came out of browser verification: site CSS gives
thread forms display:contents, which collapses the form box and breaks both
flex and position:fixed (now overridden with !important); and the overlay sits
at z-index 1200, above the bottom tab bar (1050) and sheets (1100).
- Server: fedi-reply and authorize_interaction accept content (editor HTML) +
language next to text. deliverReply sanitizes the HTML
(HtmlSanitizerService), runs the same mention/hashtag/URL enrichment as the
plain path, and places the parent mention inline in the first paragraph (own
paragraph before block content, merged paragraph around bare inline text).
Plain-text path unchanged (no-JS fallback).
- ap_outbox.language (additive) -> contentMap on the outgoing Note.
5 new tests (sanitize, mention placement, plain path unchanged, empty-html
reject, bogus language dropped); 88 green. Live-verified in the browser:
desktop upgrade, mobile full-screen (enter/cancel/scroll-lock), and a real
submit landing in ap_outbox with markup + language intact.
Co-Authored-By: Claude Opus 4.8 <noreply@…>