This commit is contained in:
Stanko K.R.
2026-07-20 15:35:13 +02:00
parent 797efa54fd
commit a3d2939569
5 changed files with 65 additions and 19 deletions
@@ -8,7 +8,6 @@ const OPENGRAPH_EMBED_CONTENT_TYPE = "application/vnd.actiontext.opengraph-embed
const UNFURLED_TWITTER_AVATAR_CSS_CLASS = "cf-twitter-avatar"
const TWITTER_AVATAR_URL_PREFIX = "https://pbs.twimg.com/profile_images"
// Unfurls URLs pasted into the rich text editor into OpenGraph preview attachments
export default class extends Controller {
#abortController
@@ -44,14 +43,14 @@ export default class extends Controller {
if (title && href) return { title, href, image, description }
}
} catch {
// Ignore aborted or failed requests, like the previous implementation did
// Ignore aborted and failed requests
}
return null
}
#opengraphEmbedHTML({ title, href, image, description }) {
return `<actiontext-opengraph-embed class="${this.#isTwitterAvatar(image) ? UNFURLED_TWITTER_AVATAR_CSS_CLASS : ""}">
return `<actiontext-opengraph-embed class="${this.#embedClass(image)}">
<div class="og-embed gap">
<div class="og-embed__content">
<div class="og-embed__title">
@@ -59,12 +58,28 @@ export default class extends Controller {
</div>
<div class="og-embed__description">${escapeHTML(truncateString(description, 560))}</div>
</div>
${image ? `<div class="og-embed__image"><img src="${escapeHTML(image)}" class="image center" alt="" /></div>` : ""}
${this.#imageHTML(image)}
</div>
</actiontext-opengraph-embed>`
}
#embedClass(image) {
if (this.#isTwitterAvatar(image)) {
return UNFURLED_TWITTER_AVATAR_CSS_CLASS
} else {
return ""
}
}
#isTwitterAvatar(image) {
return !!image?.startsWith(TWITTER_AVATAR_URL_PREFIX)
return Boolean(image) && image.startsWith(TWITTER_AVATAR_URL_PREFIX)
}
#imageHTML(image) {
if (image) {
return `<div class="og-embed__image"><img src="${escapeHTML(image)}" class="image center" alt="" /></div>`
} else {
return ""
}
}
}
+14 -2
View File
@@ -18,7 +18,7 @@ export default class ClientMessage {
body,
messageTimestamp: Math.floor(now.getTime()),
messageDatetime: now.toISOString(),
messageClasses: this.#containsOnlyEmoji(this.#plainTextFromNode(node)) ? "message--emoji" : "",
messageClasses: this.#messageClassesFromNode(node),
})
}
@@ -52,6 +52,14 @@ export default class ClientMessage {
}
}
#messageClassesFromNode(node) {
if (this.#containsOnlyEmoji(this.#plainTextFromNode(node))) {
return "message--emoji"
} else {
return ""
}
}
#isPlayCommand(node) {
return this.#matchPlayCommand(node)
@@ -62,7 +70,11 @@ export default class ClientMessage {
}
#plainTextFromNode(node) {
return this.#isRichText(node) ? node.toString()?.trim() : node
if (this.#isRichText(node)) {
return node.toString().trim()
} else {
return node
}
}
#isRichText(node) {
+7 -6
View File
@@ -77,14 +77,15 @@ export default class MessageFormatter {
#highlightCodeBlock(block) {
this.#normalizeLineBreaks(block)
if (!this.#isPlainText(block)) return
const language = block.dataset.language
if (language && window.hljs.getLanguage(language)) {
block.classList.add(`language-${language}`)
if (this.#isPlainText(block)) {
const language = block.dataset.language
if (language && window.hljs.getLanguage(language)) {
block.classList.add(`language-${language}`)
}
window.hljs.highlightElement(block)
}
window.hljs.highlightElement(block)
}
// Lexxy breaks code block lines with <br>, Trix-era blocks used newlines