From 185f5480fa76d2b1fe171f17f782553f19e45f52 Mon Sep 17 00:00:00 2001 From: CrescentLeaf Date: Fri, 5 Dec 2025 21:27:05 +0800 Subject: [PATCH] feat: BlockQoute display in client --- client/index.ts | 1 + client/ui/chat/ChatFragment.tsx | 4 +++ client/ui/chat/Message.tsx | 1 + client/ui/custom-elements/chat-quote.ts | 45 +++++++++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 client/ui/custom-elements/chat-quote.ts diff --git a/client/index.ts b/client/index.ts index f77bf4d..02af9d2 100644 --- a/client/index.ts +++ b/client/index.ts @@ -11,6 +11,7 @@ import './ui/custom-elements/chat-file.ts' import './ui/custom-elements/chat-text.ts' import './ui/custom-elements/chat-mention.ts' import './ui/custom-elements/chat-text-container.ts' +import './ui/custom-elements/chat-quote.ts' import App from './ui/App.tsx' import AppMobile from './ui/AppMobile.tsx' diff --git a/client/ui/chat/ChatFragment.tsx b/client/ui/chat/ChatFragment.tsx index f22ee99..d8b65dc 100644 --- a/client/ui/chat/ChatFragment.tsx +++ b/client/ui/chat/ChatFragment.tsx @@ -49,6 +49,7 @@ const sanitizeConfig = { 'chat-text', "chat-link", 'chat-mention', + 'chat-quote', ], ALLOWED_ATTR: [ 'underline', @@ -64,6 +65,9 @@ const sanitizeConfig = { const markedInstance = new marked.Marked({ renderer: { + blockquote({ text }) { + return `${escapeHTML(text)}` + }, text({ text }) { return `${escapeHTML(text)}` }, diff --git a/client/ui/chat/Message.tsx b/client/ui/chat/Message.tsx index 6a2e09f..7a27c45 100644 --- a/client/ui/chat/Message.tsx +++ b/client/ui/chat/Message.tsx @@ -25,6 +25,7 @@ function prettyFlatParsedMessage(html: string) { const textElementTags = [ 'chat-text', 'chat-mention', + 'chat-quote', ] function checkContinuousElement(tagName: string) { /* console.log('shangyige ', lastElementType) diff --git a/client/ui/custom-elements/chat-quote.ts b/client/ui/custom-elements/chat-quote.ts new file mode 100644 index 0000000..7426127 --- /dev/null +++ b/client/ui/custom-elements/chat-quote.ts @@ -0,0 +1,45 @@ +import { $ } from 'mdui/jq' + +customElements.define('chat-quote', class extends HTMLElement { + declare container: HTMLAnchorElement + declare span: HTMLSpanElement + declare ellipsis: boolean + constructor() { + super() + this.attachShadow({ mode: 'open' }) + } + update() { + if (this.container == null) return + + this.span.textContent = this.textContent + + this.updateStyle() + } + updateStyle() { + this.span.style.whiteSpace = this.ellipsis ? 'nowrap' : 'pre-wrap' + this.span.style.overflow = this.ellipsis ? 'hidden' : '' + this.span.style.textOverflow = this.ellipsis ? 'ellipsis' : '' + } + attributeChangedCallback(_name: string, _oldValue: unknown, _newValue: unknown) { + this.update() + } + connectedCallback() { + this.container = new DOMParser().parseFromString(` + + + `, 'text/html').body.firstChild as HTMLAnchorElement + this.span = $(this.container).find('span').get(0) + this.container.style.textDecoration = 'none' + this.span.style.fontSynthesis = 'style weight' + this.container.onclick = (e) => { + this.ellipsis = !this.ellipsis + this.updateStyle() + e.stopPropagation() + } + this.ellipsis = true + + this.shadowRoot!.appendChild(this.container) + + this.update() + } +})