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()
+ }
+})