diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte
index 5b8453c..7bd1e14 100644
--- a/frontend/src/routes/admin/+page.svelte
+++ b/frontend/src/routes/admin/+page.svelte
@@ -136,13 +136,41 @@
}
}
- // In-site reply (plain text, sent via SMTP; only stored on successful send).
+ // In-site reply (Markdown-ish: textarea + toolbar; server renders sanitized HTML).
let replyingId = $state(null);
let replyText = $state('');
let replyBusy = $state(false);
let replyErr = $state('');
+ let replyTextarea = $state(null);
function openReply(f) { replyingId = f.id; replyText = ''; replyErr = ''; }
function cancelReply() { replyingId = null; replyText = ''; replyErr = ''; }
+
+ // Wrap the current selection (e.g. **bold**), restoring focus + selection.
+ function mdWrap(token) {
+ const el = replyTextarea;
+ if (!el) return;
+ const s = el.selectionStart, e = el.selectionEnd;
+ const sel = replyText.slice(s, e) || 'text';
+ replyText = replyText.slice(0, s) + token + sel + token + replyText.slice(e);
+ queueMicrotask(() => {
+ el.focus();
+ el.selectionStart = s + token.length;
+ el.selectionEnd = s + token.length + sel.length;
+ });
+ }
+ // Prefix each selected line (e.g. "- " or "## ").
+ function mdPrefix(prefix) {
+ const el = replyTextarea;
+ if (!el) return;
+ const s = el.selectionStart, e = el.selectionEnd;
+ const start = replyText.lastIndexOf('\n', s - 1) + 1;
+ let end = replyText.indexOf('\n', e);
+ if (end === -1) end = replyText.length;
+ const block = replyText.slice(start, end) || 'item';
+ const prefixed = block.split('\n').map((ln) => prefix + ln).join('\n');
+ replyText = replyText.slice(0, start) + prefixed + replyText.slice(end);
+ queueMicrotask(() => el.focus());
+ }
async function sendReply(f) {
const msg = replyText.trim();
if (!msg || replyBusy) return;
@@ -434,7 +462,12 @@
{#each f.replies as r (r.id)}
↪ Replied · {fwhen(r.sent_at)}
-
{r.message}
+ {#if r.message_html}
+
+
{@html r.message_html}
+ {:else}
+
{r.message}
+ {/if}
{/each}
@@ -442,7 +475,12 @@
{#if replyingId === f.id}
-
+
+
+
+
+
+
{#if replyErr}
{replyErr}
{/if}