diff --git a/package-lock.json b/package-lock.json index 864663c50..940875653 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18296,7 +18296,6 @@ }, "@converse/skeletor": { "version": "git+ssh://git@github.com/conversejs/skeletor.git#c7e76b023337a8ac201c74507f7a1209de1c6d18", - "integrity": "sha512-2g+6XxFUorhlHncfkBWB8+26+8Izl2kJYf+1uk/Umb53/ltvCgtCJcQuAECmKXC/y99yCjNWot+qhA+tQK9sWQ==", "from": "@converse/skeletor@conversejs/skeletor#c7e76b023337a8ac201c74507f7a1209de1c6d18", "requires": { "lit-html": "^2.0.0-rc.2", @@ -25061,7 +25060,6 @@ }, "localforage-getitems": { "version": "git+ssh://git@github.com/conversejs/localForage-getItems.git#de039970de16a9d3b54cdaa816aed5adaefb80c9", - "integrity": "sha512-fPxYV2vJFx2onqHfL+En0bTesjawTmn1v/peYf/0gaYL7uhx5nP9czVHNUYAXoKL9kKplVH8lZo4LRrE2MK23w==", "from": "localforage-getitems@conversejs/localForage-getItems#de039970de16a9d3b54cdaa816aed5adaefb80c9", "requires": { "localforage": ">=1.4.0" diff --git a/src/plugins/muc-views/tests/unfurls.js b/src/plugins/muc-views/tests/unfurls.js index b2974b6cc..cf8630a6d 100644 --- a/src/plugins/muc-views/tests/unfurls.js +++ b/src/plugins/muc-views/tests/unfurls.js @@ -10,6 +10,9 @@ describe("A Groupchat Message", function () { await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); + const unfurl_image_src = "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg"; + const unfurl_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; + const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ @@ -26,9 +29,9 @@ describe("A Groupchat Message", function () { - + - + @@ -43,7 +46,8 @@ describe("A Groupchat Message", function () { _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); - expect(unfurl.querySelector('.card-img-top').getAttribute('text')).toBe('https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg'); + expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe(unfurl_image_src); + expect(unfurl.querySelector('.card-img-top').getAttribute('href')).toBe(unfurl_url); })); it("will render an unfurl with limited OGP data", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { @@ -78,10 +82,49 @@ describe("A Groupchat Message", function () { _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); - expect(unfurl.querySelector('.card-img-top').getAttribute('text')).toBe('https://conversejs.org/dist/images/custom_emojis/converse.png'); + expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe('https://conversejs.org/dist/images/custom_emojis/converse.png'); expect(unfurl.querySelector('.card-body')).toBe(null); })); + it("will render an unfurl containing a GIF", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { + const nick = 'romeo'; + const muc_jid = 'lounge@montague.lit'; + await mock.openAndEnterChatRoom(_converse, muc_jid, nick); + const view = _converse.chatboxviews.get(muc_jid); + const unfurl_url = "https://giphy.com/gifs/giphyqa-4YY4DnqeUDBXNTcYMu"; + const gif_url = "https://media4.giphy.com/media/4YY4DnqeUDBXNTcYMu/giphy.gif?foo=bar"; + + const message_stanza = u.toStanza(` + + ${unfurl_url} + + + + + `); + _converse.connection._dataRecv(mock.createRequest(message_stanza)); + const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); + expect(el.textContent).toBe(unfurl_url); + + + const metadata_stanza = u.toStanza(` + + + + + + + + + + + `); + _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); + + const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); + expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe(gif_url); + })); + it("will render multiple unfurls based on OGP data", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; diff --git a/src/plugins/omemo/utils.js b/src/plugins/omemo/utils.js index 5fb764c4d..261cf9a60 100644 --- a/src/plugins/omemo/utils.js +++ b/src/plugins/omemo/utils.js @@ -202,7 +202,7 @@ function getTemplateForObjectURL (uri, obj_url, richtext) { } if (isImageURL(file_url)) { return tpl_image({ - 'url': obj_url, + 'src': obj_url, 'onClick': richtext.onImgClick, 'onLoad': richtext.onImgLoad }); diff --git a/src/shared/chat/templates/unfurl.js b/src/shared/chat/templates/unfurl.js index 4a88a4ef3..1f3b47385 100644 --- a/src/shared/chat/templates/unfurl.js +++ b/src/shared/chat/templates/unfurl.js @@ -17,7 +17,7 @@ const tpl_url_wrapper = (o, wrapped_template) => : wrapped_template(o); const tpl_image = o => - html``; + html``; export default o => { const show_image = isValidImage(o.image); diff --git a/src/shared/components/image.js b/src/shared/components/image.js index dd049e9c5..55df28e40 100644 --- a/src/shared/components/image.js +++ b/src/shared/components/image.js @@ -2,27 +2,27 @@ import tpl_gif from 'templates/gif.js'; import tpl_image from 'templates/image.js'; import { CustomElement } from './element.js'; import { api } from "@converse/headless/core"; -import { filterQueryParamsFromURL, isGIFURL } from '@converse/headless/utils/url.js'; +import { filterQueryParamsFromURL, isGIFURL, shouldRenderMediaFromURL } from '@converse/headless/utils/url.js'; export default class Image extends CustomElement { static get properties () { return { - 'href': { type: String }, + 'src': { type: String }, 'onImgLoad': { type: Function }, - 'text': { type: String }, + // If specified, image is wrapped in a hyperlink that points to this URL. + 'href': { type: String }, } } render () { - const filtered_url = filterQueryParamsFromURL(this.href); - if (isGIFURL(this.text) && this.shouldRenderMedia(this.text, 'image')) { - return tpl_gif(filtered_url); + if (isGIFURL(this.src) && shouldRenderMediaFromURL(this.src, 'image')) { + return tpl_gif(filterQueryParamsFromURL(this.src), true); } else { return tpl_image({ - 'url': this.text, - 'href': filtered_url, + 'src': filterQueryParamsFromURL(this.src), + 'href': this.href, 'onClick': this.onImgClick, 'onLoad': this.onImgLoad }); diff --git a/src/shared/rich-text.js b/src/shared/rich-text.js index 2af9e5631..7293835ae 100644 --- a/src/shared/rich-text.js +++ b/src/shared/rich-text.js @@ -134,7 +134,7 @@ export class RichText extends String { template = tpl_gif(filtered_url, this.hide_media_urls); } else if (isImageURL(url_text) && this.shouldRenderMedia(url_text, 'image')) { template = tpl_image({ - 'url': filtered_url, + 'src': filtered_url, // XXX: bit of an abuse of `hide_media_urls`, might want a dedicated option here 'href': this.hide_media_urls ? null : filtered_url, 'onClick': this.onImgClick, diff --git a/src/templates/image.js b/src/templates/image.js index 3eb5d933a..069b34ea5 100644 --- a/src/templates/image.js +++ b/src/templates/image.js @@ -1,4 +1,4 @@ import { html } from "lit"; import { renderImage } from "shared/directives/image.js"; -export default (o) => html`${renderImage(o.url, o.href, o.onLoad, o.onClick)}`; +export default (o) => html`${renderImage(o.src || o.url, o.href, o.onLoad, o.onClick)}`;