diff --git a/client/ui/custom-elements/chat-file.ts b/client/ui/custom-elements/chat-file.ts index 7929789..6807b18 100644 --- a/client/ui/custom-elements/chat-file.ts +++ b/client/ui/custom-elements/chat-file.ts @@ -7,7 +7,7 @@ customElements.define('chat-file', class extends HTMLElement { connectedCallback() { const e = new DOMParser().parseFromString(` - + diff --git a/client/ui/custom-elements/chat-image.ts b/client/ui/custom-elements/chat-image.ts index c3078a1..b1e6aa2 100644 --- a/client/ui/custom-elements/chat-image.ts +++ b/client/ui/custom-elements/chat-image.ts @@ -1,39 +1,59 @@ import openImageViewer from "../openImageViewer.ts" -import { snackbar } from "../snackbar.ts" import { $ } from 'mdui/jq' customElements.define('chat-image', class extends HTMLElement { + static observedAttributes = ['src', 'show-error'] + declare img: HTMLImageElement + declare error: HTMLElement constructor() { super() + + this.attachShadow({ mode: 'open' }) + } + update() { + if (this.img == null) return + + this.img.src = $(this).attr('src') as string + + const error = $(this).attr('show-error') == 'true' + this.img.style.display = error ? 'none' : 'block' + this.error.style.display = error ? '' : 'none' + } + attributeChangedCallback(_name: string, _oldValue: unknown, _newValue: unknown) { + this.update() } connectedCallback() { - this.style.display = 'block' - const e = new Image() - e.style.maxWidth = "400px" - e.style.maxHeight = "300px" - e.style.marginTop = '5px' - e.style.marginBottom = '5px' - e.style.borderRadius = "var(--mdui-shape-corner-medium)" - e.alt = $(this).attr('alt') || "" - e.onerror = () => { - const src = $(this).attr('src') - $(this).html(``) - $(this).attr('alt', '无法加载: ' + $(this).attr('alt')) - $(this).on('click', () => { - snackbar({ - message: `图片 (${src}) 无法加载!`, - placement: 'top' - }) - }) - } - e.src = $(this).attr('src') as string - e.onclick = (event) => { + this.img = new Image() + this.img.style.width = '100%' + this.img.style.maxHeight = "300px" + this.img.style.objectFit = 'cover' + // this.img.style.borderRadius = "var(--mdui-shape-corner-medium)" + this.shadowRoot!.appendChild(this.img) + + this.error = new DOMParser().parseFromString(``, 'text/html').body.firstChild as HTMLElement + this.shadowRoot!.appendChild(this.error) + + this.img.addEventListener('error', () => { + $(this).attr('show-error', 'true') + }) + this.error.addEventListener('click', (event) => { + event.stopPropagation() + const img = this.img + this.img = new Image() + this.img.style.width = '100%' + this.img.style.maxHeight = "300px" + this.img.style.objectFit = 'cover' + this.shadowRoot!.replaceChild(img, this.img) + $(this).attr('show-error', undefined) + }) + this.img.addEventListener('click', (event) => { event.stopPropagation() openImageViewer($(this).attr('src') as string) - } - this.appendChild(e) + }) + + this.update() } }) diff --git a/client/ui/custom-elements/chat-video.ts b/client/ui/custom-elements/chat-video.ts index 2710d49..be2a808 100644 --- a/client/ui/custom-elements/chat-video.ts +++ b/client/ui/custom-elements/chat-video.ts @@ -1,19 +1,31 @@ import { $ } from 'mdui/jq' customElements.define('chat-video', class extends HTMLElement { + static observedAttributes = ['src'] + declare video: HTMLVideoElement constructor() { super() + + this.attachShadow({ mode: 'open' }) + } + update() { + if (this.video == null) return + + this.video.src = $(this).attr('src') as string + } + attributeChangedCallback(_name: string, _oldValue: unknown, _newValue: unknown) { + this.update() } connectedCallback() { - this.style.display = 'block' - const e = new DOMParser().parseFromString(``, 'text/html').body.firstChild as HTMLVideoElement - e.style.maxWidth = "400px" - e.style.maxHeight = "300px" - e.style.width = "100%" - e.style.height = "100%" - e.style.borderRadius = "var(--mdui-shape-corner-medium)" - e.src = $(this).attr('src') as string - e.onclick = (e) => e.stopPropagation() - this.appendChild(e) + this.video = new DOMParser().parseFromString(``, 'text/html').body.firstChild as HTMLVideoElement + this.video.style.maxWidth = "400px" + this.video.style.maxHeight = "300px" + this.video.style.width = "100%" + this.video.style.height = "100%" + this.video.style.display = 'block' + // e.style.borderRadius = "var(--mdui-shape-corner-medium)" + + this.video.onclick = (e) => e.stopPropagation() + this.shadowRoot!.appendChild(this.video) } })