feat(chat): quote with the '>' line prefix instead of guillemets

The Quote button produced `@[user] »text« ` — a shape mc-webui invented back
when it could not send newlines, and one that other MeshCore clients neither
write nor understand. It now writes the quote on its own line behind a '>'
and leaves the cursor underneath it, matching the plain-text convention some
users already type by hand.

processQuotes() styles both syntaxes, so messages sent by older builds keep
their formatting. The '>' match is anchored to a line start or a leading
@[mention] badge and looks for the escaped '>', so neither "5 > 3" in
prose nor the brackets of generated tags can trigger it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-07-27 11:58:53 +02:00
parent 993013e0f5
commit 17398e8e41
4 changed files with 49 additions and 9 deletions
+6 -2
View File
@@ -1531,11 +1531,15 @@ function truncateToBytes(text, maxBytes) {
}
/**
* Insert a quote into the message input.
* Insert a quote into the message input, leaving the cursor on a fresh line
* for the reply. Uses the `>` line prefix rather than the guillemets of older
* versions, so the quote also reads as one in clients that don't style it.
*/
function insertQuote(username, quotedText) {
const input = document.getElementById('messageInput');
input.value = `@[${username}] »${quotedText}« `;
// One '>' per line — a quoted multi-line message stays fully quoted.
const quoted = quotedText.split('\n').map(line => `>${line}`).join('\n');
input.value = `@[${username}] ${quoted}\n`;
updateCharCounter();
input.focus();
}
+20 -6
View File
@@ -134,18 +134,32 @@ function processChannelLinks(text) {
}
/**
* Convert »quoted text« to styled quote blocks
* Convert quoted text to styled quote blocks. Two syntaxes are recognised:
* `>quoted line` (current, also what other MeshCore clients use) and
* `»quoted text«` (what mc-webui produced before 2.2.0 — still rendered so
* older messages keep their styling).
* @param {string} text - HTML-escaped text
* @returns {string} - Text with styled quotes
*/
function processQuotes(text) {
// Match »...« pattern (guillemets) including optional trailing whitespace
const quotePattern = /»([^«]+)«\s*/g;
return text.replace(quotePattern, (_match, quoted) => {
// Display without guillemets (styling is enough) + line break after
// Legacy guillemets: the markers are dropped (styling replaces them) and
// the pattern eats the space separating quote from reply, hence the <br>.
const legacyPattern = /»([^«]+)«\s*/g;
text = text.replace(legacyPattern, (_match, quoted) => {
return `<span class="quote-text">${quoted}</span><br>`;
});
// `>quoted line`. The text arrives HTML-escaped, so a typed '>' shows up as
// '&gt;' and the '>' of generated tags can never match. Anchored to the
// start of a line or to a leading @[mention] badge, so "5 &gt; 3" mid
// sentence is left alone. The trailing newline stays in place — the message
// containers are pre-wrap and render it as the break.
const quotePattern = /(^|\n|<\/span>[ \t]*)&gt;[ \t]*([^\n]*)/g;
return text.replace(quotePattern, (match, prefix, quoted) => {
if (!quoted.trim()) return match;
return `${prefix}<span class="quote-text">${quoted}</span>`;
});
}
/**
+13
View File
@@ -163,6 +163,19 @@ Archives are created automatically at midnight (00:00 UTC) each day. The live vi
Click the reply button on any message to insert `@[UserName]` into the text field, then type your reply.
### Quoting a Message
Click the quote button (") on any message to quote it. The quoted text is put on its own line prefixed with `>`, and the cursor lands on the line below it, ready for your answer:
```
@[daniel5120] >Are we still on for tonight?
Yes, 8pm works.
```
The `>` prefix is the plain-text quoting convention used across the internet and by other MeshCore clients, so your quote reads correctly for everyone, not just mc-webui users. mc-webui shows the quoted line in an italic, tinted block. Quotes typed by hand are styled the same way, as are the `»quoted text«` guillemets mc-webui used before version 2.2.0.
Long messages open a dialog first, offering the full text or a truncated version — see **Max quote length** in [Settings](#settings).
### Message Actions
Your own messages carry a small row of action buttons:
+10 -1
View File
@@ -10,7 +10,16 @@ For deep technical notes, see [architecture.md](architecture.md). For the full g
## Unreleased
_Nothing yet since 2.1.0._
### New features
- **Quotes now use the `>` convention everyone else already uses.** Quoting a message used to wrap it in guillemets — `@[Daniel] »Hejka« Cześć!` — a shape mc-webui invented back when it couldn't send multi-line messages. It now puts the quote on its own line behind a `>` and drops the cursor underneath it, so a reply reads as a quote in the standard MeshCore app and every other client too, not just here:
```
@[Daniel] >Are we still on for tonight?
Yes, 8pm works.
```
Quotes you type by hand get the same italic, tinted styling, so `>` written manually now looks like a proper quote as well. Nothing you received earlier changes: the old `»…«` form is still recognised and still displayed exactly as before.
---