2
0
Эх сурвалжийг харах

Use the `converse-texture` component to render the OOB URL

JC Brand 4 сар өмнө
parent
commit
f4c628e545

+ 1 - 1
src/headless/types/shared/model-with-messages.d.ts

@@ -282,7 +282,7 @@ export default function ModelWithMessages<T extends import("./types").ModelExten
         _listeningTo: {};
         _listenId: any;
         off(name: string, callback: (event: any, model: Model, collection: import("@converse/skeletor").Collection, options: Record<string, any>) => any, context?: any): any;
-        stopListening(obj?: any, name?: string, callback?: (event: any, model: Model, collection: import("@converse/skeletor" /** @param {...any} args */).Collection, options: Record<string, any>) => any): any;
+        stopListening(obj?: any, name?: string, callback?: (event: any, model: Model, collection: import("@converse/skeletor").Collection, options: Record<string, any>) => any): any;
         once(name: string, callback: (event: any, model: Model, collection: import("@converse/skeletor").Collection, options: Record<string, any>) => any, context: any): any;
         listenToOnce(obj: any, name: string, callback?: (event: any, model: Model, collection: import("@converse/skeletor").Collection, options: Record<string, any>) => any): any;
         trigger(name: string, ...args: any[]): any;

+ 15 - 10
src/plugins/chatview/tests/oob.js

@@ -1,5 +1,4 @@
 /*global mock, converse */
-
 const { Strophe, Promise, u } = converse.env;
 
 describe("A Chat Message", function () {
@@ -97,6 +96,9 @@ describe("A Chat Message", function () {
             msg = view.querySelector('converse-chat-message .chat-msg__text');
             expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('Have you seen this funny video?');
             expect(view.querySelector('converse-chat-message:last-child .chat-msg__media')).toBe(null);
+            expect(media.firstElementChild.nodeName).toBe('CONVERSE-TEXTURE');
+            await u.waitUntil(() => media.firstElementChild.querySelector('video'));
+            expect(media.firstElementChild.querySelector('video').getAttribute('src')).toBe(url);
         }));
 
         it("will render download links for files from oob URLs",
@@ -109,12 +111,13 @@ describe("A Chat Message", function () {
             await mock.openChatBoxFor(_converse, contact_jid);
             const view = _converse.chatboxviews.get(contact_jid);
             spyOn(view.model, 'sendMessage').and.callThrough();
+            const url = 'https://montague.lit/funny.pdf';
             const stanza = u.toStanza(`
                 <message from="${contact_jid}"
                          type="chat"
                          to="romeo@montague.lit/orchard">
                     <body>Have you downloaded this funny file?</body>
-                    <x xmlns="jabber:x:oob"><url>https://montague.lit/funny.pdf</url></x>
+                    <x xmlns="jabber:x:oob"><url>${url}</url></x>
                 </message>`);
             _converse.api.connection.get()._dataRecv(mock.createRequest(stanza));
             await new Promise(resolve => view.model.messages.once('rendered', resolve));
@@ -123,8 +126,9 @@ describe("A Chat Message", function () {
             expect(u.hasClass('chat-msg__text', msg)).toBe(true);
             expect(msg.textContent).toEqual('Have you downloaded this funny file?');
             const media = view.querySelector('.chat-msg .chat-msg__media');
-            expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "").replace(/<!-.*?->/g, '')).toEqual(
-                `<a target="_blank" rel="noopener" href="https://montague.lit/funny.pdf">Download file "funny.pdf"</a>`);
+            expect(media.firstElementChild.nodeName).toBe('CONVERSE-TEXTURE');
+            await u.waitUntil(() => media.firstElementChild.querySelector('a'));
+            expect(media.firstElementChild.querySelector('a').getAttribute('href')).toBe(url);
         }));
 
         it("will render images from oob URLs",
@@ -141,9 +145,10 @@ describe("A Chat Message", function () {
             const url = base_url+"/logo/conversejs-filled.svg";
 
             const stanza = u.toStanza(`
-                <message from="${contact_jid}"
-                         type="chat"
-                         to="romeo@montague.lit/orchard">
+                <message xmlns="jabber:client"
+                        from="${contact_jid}"
+                        type="chat"
+                        to="romeo@montague.lit/orchard">
                     <body>Have you seen this funny image?</body>
                     <x xmlns="jabber:x:oob"><url>${url}</url></x>
                 </message>`);
@@ -155,9 +160,9 @@ describe("A Chat Message", function () {
             expect(u.hasClass('chat-msg__text', msg)).toBe(true);
             expect(msg.textContent).toEqual('Have you seen this funny image?');
             const media = view.querySelector('.chat-msg .chat-msg__media');
-            expect(media.innerHTML.replace(/<!-.*?->/g, '').replace(/(\r\n|\n|\r)/gm, "")).toEqual(
-                `<a target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
-                `Download file "conversejs-filled.svg"</a>`);
+            expect(media.firstElementChild.nodeName).toBe('CONVERSE-TEXTURE');
+            await u.waitUntil(() => media.firstElementChild.querySelector('img'));
+            expect(media.firstElementChild.querySelector('img').getAttribute('src')).toBe(url);
         }));
     });
 });

+ 10 - 10
src/shared/chat/message-body.js

@@ -35,26 +35,26 @@ export default class MessageBody extends CustomElement {
         this.listenTo(settings, 'change:render_media', () => this.requestUpdate());
     }
 
-    onImgClick (ev) { // eslint-disable-line class-methods-use-this
+    onImgClick (ev) {
         ev.preventDefault();
-        api.modal.show('converse-image-modal', {'src': ev.target.src}, ev);
+        api.modal.show('converse-image-modal', { src: ev.target.src }, ev);
     }
 
     onImgLoad () {
-        this.dispatchEvent(new CustomEvent('imageLoaded', { detail: this, 'bubbles': true }));
+        this.dispatchEvent(new CustomEvent('imageLoaded', { detail: this, bubbles: true }));
     }
 
     render () {
         const callback = () => this.model.collection?.trigger('rendered', this.model);
         const offset = 0;
         const options = {
-            'media_urls': this.model.get('media_urls'),
-            'mentions': this.model.get('references'),
-            'nick': this.model.chatbox.get('nick'),
-            'onImgClick': (ev) => this.onImgClick(ev),
-            'onImgLoad': () => this.onImgLoad(),
-            'render_styling': !this.model.get('is_unstyled') && api.settings.get('allow_message_styling'),
-            'show_me_message': true,
+            media_urls: this.model.get('media_urls'),
+            mentions: this.model.get('references'),
+            nick: this.model.chatbox.get('nick'),
+            onImgClick: (ev) => this.onImgClick(ev),
+            onImgLoad: () => this.onImgLoad(),
+            render_styling: !this.model.get('is_unstyled') && api.settings.get('allow_message_styling'),
+            show_me_message: true,
         }
         if (this.hide_url_previews === "false") {
             options.embed_audio = true;

+ 5 - 0
src/shared/chat/message.js

@@ -112,6 +112,11 @@ export default class Message extends ObservableElement {
             ['chat', 'groupchat', 'normal'].includes(this.model.get('type'));
     }
 
+    onImgClick (ev) {
+        ev.preventDefault();
+        api.modal.show('converse-image-modal', { src: ev.target.src }, ev);
+    }
+
     onUnfurlAnimationEnd () {
         if (this.model.get('url_preview_transition') === 'fade-out') {
             this.model.save({

+ 12 - 3
src/shared/chat/templates/message-text.js

@@ -1,12 +1,12 @@
+import { api } from "@converse/headless";
 import { __ } from 'i18n/index.js';
-import { getOOBURLMarkup } from 'utils/html.js';
 import { html } from 'lit';
 
 /**
  * @param {import('../message').default} el
  */
 function tplEditedIcon(el) {
-    const i18n_edited = __('This message has been edited');
+    const i18n_edited = __('el message has been edited');
     return html`<converse-icon
         title="${i18n_edited}"
         class="fa fa-edit chat-msg__edit-modal"
@@ -52,6 +52,7 @@ export default (el) => {
         : '';
     const text = el.model.getMessageText();
     const show_oob = el.model.get('oob_url') && text !== el.model.get('oob_url');
+    const render_media = api.settings.get('render_media');
 
     return html`
         ${el.model.get('is_spoiler') ? tplSpoilerHint : ''}
@@ -69,7 +70,15 @@ export default (el) => {
             ${el.model.get('received') && !el.model.isMeCommand() && !is_groupchat_message ? tplCheckmark() : ''}
             ${el.model.get('edited') ? tplEditedIcon(el) : ''}
         </span>
-        ${show_oob ? html`<div class="chat-msg__media">${getOOBURLMarkup(el.model.get('oob_url'))}</div>` : ''}
+        ${show_oob ? html`<div class="chat-msg__media">
+            <converse-texture
+                text="${el.model.get('oob_url')}"
+                .onImgClick="${(ev) => el.onImgClick(ev)}"
+                ?embed_audio="${render_media}"
+                ?embed_videos="${render_media}"
+                ?show_images="${render_media}"
+                />
+            </div>` : ''}
         ${error_text ? html`<div class="chat-msg__error">${i18n_error}</div>` : ''}
     `;
 };

+ 1 - 0
src/types/shared/chat/message.d.ts

@@ -23,6 +23,7 @@ export default class Message extends ObservableElement {
     renderFileProgress(): import("lit").TemplateResult<1> | "";
     renderChatMessage(): import("lit").TemplateResult<1>;
     shouldShowAvatar(): boolean;
+    onImgClick(ev: any): void;
     onUnfurlAnimationEnd(): void;
     onRetryClicked(): Promise<void>;
     show_spinner: boolean;

+ 0 - 8
src/types/utils/html.d.ts

@@ -7,14 +7,6 @@ export function getNameAndValue(field: HTMLInputElement | HTMLSelectElement): {
     [key: string]: string | number | string[];
 } | null;
 export function getFileName(url: any): any;
-/**
- * Returns the markup for a URL that points to a downloadable asset
- * (such as a video, image or audio file).
- * @method u#getOOBURLMarkup
- * @param {string} url
- * @returns {TemplateResult|string}
- */
-export function getOOBURLMarkup(url: string): TemplateResult | string;
 /**
  * Has an element a class?
  * @method u#hasClass

+ 1 - 28
src/utils/html.js

@@ -7,8 +7,6 @@
 import { render } from 'lit';
 import { Builder, Stanza } from 'strophe.js';
 import { api, converse, log, u } from '@converse/headless';
-import tplAudio from 'templates/audio.js';
-import tplFile from 'templates/file.js';
 import tplDateInput from 'templates/form_date.js';
 import tplFormCaptcha from '../templates/form_captcha.js';
 import tplFormCheckbox from '../templates/form_checkbox.js';
@@ -19,10 +17,9 @@ import tplFormTextarea from '../templates/form_textarea.js';
 import tplFormUrl from '../templates/form_url.js';
 import tplFormUsername from '../templates/form_username.js';
 import tplHyperlink from 'templates/hyperlink.js';
-import tplVideo from 'templates/video.js';
 
 const { sizzle, Strophe, dayjs } = converse.env;
-const { getURI, isAudioURL, isImageURL, isVideoURL, isValidURL } = u;
+const { getURI, isValidURL } = u;
 
 const APPROVED_URL_PROTOCOLS = ['http', 'https', 'xmpp', 'mailto'];
 
@@ -146,29 +143,6 @@ export function getFileName (url) {
     }
 }
 
-/**
- * Returns the markup for a URL that points to a downloadable asset
- * (such as a video, image or audio file).
- * @method u#getOOBURLMarkup
- * @param {string} url
- * @returns {TemplateResult|string}
- */
-export function getOOBURLMarkup (url) {
-    const uri = getURI(url);
-    if (uri === null) {
-        return url;
-    }
-    if (isVideoURL(uri)) {
-        return tplVideo(url);
-    } else if (isAudioURL(uri)) {
-        return tplAudio(url);
-    } else if (isImageURL(uri)) {
-        return tplFile(uri.toString(), getFileName(uri));
-    } else {
-        return tplFile(uri.toString(), getFileName(uri));
-    }
-}
-
 /**
  * Return the height of the passed in DOM element,
  * based on the heights of its children.
@@ -560,7 +534,6 @@ Object.assign(u, {
     escapeHTML,
     getElementFromTemplateResult,
     getNextElement,
-    getOOBURLMarkup,
     getOuterWidth,
     getRootElement,
     hasClass,