Skip to content

Commit

Permalink
Various changes.
Browse files Browse the repository at this point in the history
- Add docstrings.
- Render only hostname below video element
- Handle no headers being returned
  • Loading branch information
jcbrand committed Jan 12, 2025
1 parent e40c389 commit c6ef8ae
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 31 deletions.
12 changes: 3 additions & 9 deletions src/plugins/chatview/tests/message-videos.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,13 @@ describe("A chat message containing video URLs", function () {
await mock.sendMessage(view, message);
await u.waitUntil(() => view.querySelectorAll('.chat-content video').length, 1000)
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<video controls="" preload="metadata" src="${message}"></video>`+
`<a target="_blank" rel="noopener" href="${message}">${message}</a>`);
expect(msg.querySelector('video').src).toEqual(message);

message += "?param1=val1&param2=val2";
await mock.sendMessage(view, message);
await u.waitUntil(() => view.querySelectorAll('.chat-content video').length === 2, 1000);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<video controls="" preload="metadata" src="${Strophe.xmlescape(message)}"></video>`+
`<a target="_blank" rel="noopener" href="${Strophe.xmlescape(message)}">${Strophe.xmlescape(message)}</a>`);
expect(msg.querySelector('video').src).toEqual(message);
}));

it("will not render videos if render_media is false",
Expand Down Expand Up @@ -64,9 +60,7 @@ describe("A chat message containing video URLs", function () {
await mock.sendMessage(view, message);
await u.waitUntil(() => view.querySelectorAll('.chat-content video').length, 1000)
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<video controls="" preload="metadata" src="${message}"></video>`+
`<a target="_blank" rel="noopener" href="${message}">${message}</a>`);
expect(msg.querySelector('video').src).toEqual(message);
}));

it("will allow the user to toggle visibility of rendered videos",
Expand Down
47 changes: 34 additions & 13 deletions src/shared/directives/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,46 @@ import { getHyperlinkTemplate } from 'utils/html.js';
const { URI } = converse.env;
const { isURLWithImageExtension } = u;


class ImageDirective extends AsyncDirective {

render (src, href, onLoad, onClick) {
return href ?
html`<a href="${href}" class="chat-image__link" target="_blank" rel="noopener">${ this.renderImage(src, href, onLoad, onClick) }</a>` :
this.renderImage(src, href, onLoad, onClick);
/**
* @param {string} src - The source URL of the image.
* @param {string} [href] - The optional hyperlink for the image.
* @param {Function} [onLoad] - Callback function to be called once the image has loaded.
* @param {Function} [onClick] - Callback function to be called once the image has been clicked.
* @returns {import('lit').TemplateResult}
*/
render(src, href, onLoad, onClick) {
return href
? html`<a href="${href}" class="chat-image__link" target="_blank" rel="noopener"
>${this.renderImage(src, href, onLoad, onClick)}</a
>`
: this.renderImage(src, href, onLoad, onClick);
}

renderImage (src, href, onLoad, onClick) {
/**
* @param {string} src - The source URL of the image.
* @param {string} [href] - The optional hyperlink for the image.
* @param {Function} [onLoad] - Callback function to be called once the image has loaded.
* @param {Function} [onClick] - Callback function to be called once the image has been clicked.
* @returns {import('lit').TemplateResult}
*/
renderImage(src, href, onLoad, onClick) {
return html`<img class="chat-image img-thumbnail"
loading="lazy"
src="${src}"
@click=${onClick}
@error=${() => this.onError(src, href, onLoad, onClick)}
@load="${onLoad}"/></a>`;
loading="lazy"
src="${src}"
@click=${onClick}
@error=${() => this.onError(src, href, onLoad, onClick)}
@load="${onLoad}"/></a>`;
}

onError (src, href, onLoad, onClick) {
/**
* Handles errors that occur during image loading.
* @param {string} src - The source URL of the image that failed to load.
* @param {string} [href] - The optional hyperlink for the image.
* @param {Function} [onLoad] - Callback function to be called once the image has loaded.
* @param {Function} [onClick] - Callback function to be called once the image has been clicked.
*/
onError(src, href, onLoad, onClick) {
if (isURLWithImageExtension(src)) {
href && this.setValue(getHyperlinkTemplate(href));
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/shared/texture/texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export class Texture extends String {
} else {
if (this.shouldRenderMedia(url_text, 'audio') && api.settings.get('fetch_url_headers')) {
const headers = await getHeaders(url_text);
if (headers.get('content-type')?.startsWith('audio')) {
if (headers?.get('content-type')?.startsWith('audio')) {
template = tplAudio(filtered_url, this.hide_media_urls, headers.get('Icy-Name'));
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/templates/video.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { html } from 'lit';
* @param {string} url
* @param {boolean} [hide_url]
*/
export default (url, hide_url) =>
html`<video controls preload="metadata" src="${url}"></video>${hide_url
? ''
: html`<a target="_blank" rel="noopener" href="${url}">${url}</a>`}`;
export default (url, hide_url) => {
const { hostname } = new URL(url);
return html`<figure>
<video controls preload="metadata" src="${url}"></video>
${hide_url ? '' : html`<a target="_blank" rel="noopener" title="${url}" href="${url}">${hostname}</a>`}
</figure>`;
}
29 changes: 25 additions & 4 deletions src/types/shared/directives/image.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,32 @@
* @param { Function } onLoad - A callback function to be called once the image has loaded.
* @param { Function } onClick - A callback function to be called once the image has been clicked.
*/
export const renderImage: (src?: any, href?: any, onLoad?: any, onClick?: any) => import("lit/async-directive.js").DirectiveResult<typeof ImageDirective>;
export const renderImage: (src: string, href?: string, onLoad?: Function, onClick?: Function) => import("lit/async-directive.js").DirectiveResult<typeof ImageDirective>;
declare class ImageDirective extends AsyncDirective {
render(src: any, href: any, onLoad: any, onClick: any): import("lit").TemplateResult<1>;
renderImage(src: any, href: any, onLoad: any, onClick: any): import("lit").TemplateResult<1>;
onError(src: any, href: any, onLoad: any, onClick: any): void;
/**
* @param {string} src - The source URL of the image.
* @param {string} [href] - The optional hyperlink for the image.
* @param {Function} [onLoad] - Callback function to be called once the image has loaded.
* @param {Function} [onClick] - Callback function to be called once the image has been clicked.
* @returns {import('lit').TemplateResult}
*/
render(src: string, href?: string, onLoad?: Function, onClick?: Function): import("lit").TemplateResult;
/**
* @param {string} src - The source URL of the image.
* @param {string} [href] - The optional hyperlink for the image.
* @param {Function} [onLoad] - Callback function to be called once the image has loaded.
* @param {Function} [onClick] - Callback function to be called once the image has been clicked.
* @returns {import('lit').TemplateResult}
*/
renderImage(src: string, href?: string, onLoad?: Function, onClick?: Function): import("lit").TemplateResult;
/**
* Handles errors that occur during image loading.
* @param {string} src - The source URL of the image that failed to load.
* @param {string} [href] - The optional hyperlink for the image.
* @param {Function} [onLoad] - Callback function to be called once the image has loaded.
* @param {Function} [onClick] - Callback function to be called once the image has been clicked.
*/
onError(src: string, href?: string, onLoad?: Function, onClick?: Function): void;
}
import { AsyncDirective } from 'lit/async-directive.js';
export {};
Expand Down

0 comments on commit c6ef8ae

Please sign in to comment.