eleven / messenger Public

web: re-instate large bubble-less rendering for short all-emoji messages (#45)

A message whose entire content is up to 3 emoji again renders large with no
surrounding bubble (à la Messages). The pure `emojiOnlyCount` helper in
format.js and its tests survived the multi-thread rebuild, but the render
wiring in fillContent (and the `.jumbo-emoji` CSS, later swept up in the
dead-CSS cleanup) had been dropped. This re-wires both:

- chat.js: import `emojiOnlyCount`; apply `jumbo-emoji` to a text-only message
  (no attachments) of 1–3 emoji, so a photo-with-emoji caption keeps its bubble.
- style.css: restore the `.bubble.jumbo-emoji` rule (44px, no background/padding).


Claude-Session: https://claude.ai/code/session_01QqaTw3kgGRRwSqxHLi9Ram
Co-authored-by: Claude <noreply@anthropic.com>
James Adam b8d207b1c54e79c9c51e066081e75ced2c5ba78a parent c4a41d4
2 files changed, +10 −2
  • web/static/chat.js +7 −2
  • web/static/style.css +3 −0
diff --git a/web/static/chat.js b/web/static/chat.js
index 8d76cc7..c2140f5 100644
--- a/web/static/chat.js
+++ b/web/static/chat.js
@@ -29,7 +29,7 @@ import {
colorScheme,
composerToken,
} from "/static/ui.js";
-import { richTokens, typingSummary, replySnippet, formatBytes, autoGroupTitle } from "/static/format.js";
+import { richTokens, typingSummary, replySnippet, formatBytes, autoGroupTitle, emojiOnlyCount } from "/static/format.js";
import { emojify, emojiMatches } from "/static/emoji.js";
import { MESSAGE_TYPE_TYPING } from "/static/message.js";
import { qrCanvas } from "/static/qrcode.js";
@@ -1293,7 +1293,12 @@ async function appendMessage(threadId, m, scroll = true) {
}
if (data.text) {
const bubble = document.createElement("div");
- bubble.className = "bubble";
+ // A message that's nothing but a few emoji renders large and bubble-less
+ // (à la Messages). Anything alongside it — an attachment — makes it a
+ // normal captioned message, so it keeps its bubble.
+ const hasAttachments = Array.isArray(data.attachments) && data.attachments.length > 0;
+ const jumbo = !hasAttachments && emojiOnlyCount(data.text) > 0;
+ bubble.className = jumbo ? "bubble jumbo-emoji" : "bubble";
renderText(bubble, data.text);
content.appendChild(bubble);
const link = (richTokens(data.text).find((t) => t.href) || {}).href;
diff --git a/web/static/style.css b/web/static/style.css
index dcf3b17..27e0abd 100644
--- a/web/static/style.css
+++ b/web/static/style.css
@@ -339,6 +339,9 @@ input:focus, textarea:focus { outline: 2px solid var(--accent); border-color: tr
.msg.me .bubble { background: var(--bubble-me); color: var(--bubble-me-ink); border-bottom-right-radius: 6px; }
.msg.them .bubble { border-bottom-left-radius: 6px; }
.msg .bubble a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
+/* a message of just a few emoji: large and bubble-less, no background or padding (see fillContent) */
+.msg .bubble.jumbo-emoji,
+.msg.me .bubble.jumbo-emoji { background: none; color: inherit; padding: 2px 0; font-size: 44px; line-height: 1.15; }
/* centered time separator that opens a burst (replaces per-message timestamps) */
.time-sep {