audio: Present audio player in wrapped element.

This commit is contained in:
Karl Stolley
2025-08-20 14:55:12 -05:00
committed by Tim Abbott
parent 3787fb3b02
commit cacd73fd8b
6 changed files with 61 additions and 15 deletions

View File

@@ -198,15 +198,6 @@ export function postprocess_content(html: string): string {
}
}
for (const audio of template.content.querySelectorAll("audio")) {
const audio_wrapper = inertDocument.createElement("span");
audio_wrapper.classList.add("media-audio-wrapper");
// We want a class to refer to audio elements
audio.classList.add("media-audio-element");
audio_wrapper.append(audio.cloneNode());
audio.replaceWith(audio_wrapper);
}
for (const ol of template.content.querySelectorAll("ol")) {
const list_start = Number(ol.getAttribute("start") ?? 1);
// We don't count the first item in the list, as it

View File

@@ -5,6 +5,7 @@ import assert from "minimalistic-assert";
import render_channel_message_link from "../templates/channel_message_link.hbs";
import code_buttons_container from "../templates/code_buttons_container.hbs";
import render_markdown_audio from "../templates/markdown_audio.hbs";
import render_markdown_timestamp from "../templates/markdown_timestamp.hbs";
import render_mention_content_wrapper from "../templates/mention_content_wrapper.hbs";
import render_topic_link from "../templates/topic_link.hbs";
@@ -369,6 +370,20 @@ export const update_elements = ($content: JQuery): void => {
$codehilite.addClass("zulip-code-block");
});
$content.find("audio").each(function (): void {
// We grab the audio source and title for
// inserting into the template
const audio_src = $(this).attr("src");
const audio_title = $(this).attr("title");
const rendered_audio = render_markdown_audio({
audio_src,
audio_title,
});
$(this).replaceWith($(rendered_audio));
});
// Display emoji (including realm emoji) as text if
// user_settings.emojiset is 'text'.
if (user_settings.emojiset === "text") {

View File

@@ -673,11 +673,18 @@
display: grid;
}
.media-audio-element {
.media-audio-wrapper {
vertical-align: middle;
display: inline-flex;
align-items: center;
max-width: 100%;
}
.media-audio-element {
flex: 0 1 auto;
/* Allow browser-native media players
to resize in narrow viewports. */
max-width: 100%;
max-width: calc(100% - 30px);
}
.message_embed {

View File

@@ -0,0 +1,5 @@
{{~!-- --~}}
<span class="media-audio-wrapper">
<audio controls="" preload="metadata" src="{{audio_src}}" title="{{audio_title}}" class="media-audio-element"></audio>
</span>
{{~!-- --~}}

View File

@@ -43,8 +43,7 @@ run_test("postprocess_content", () => {
"</div>" +
'<div class="message_embed_description">All about us.</div>' +
"</div>" +
"</div>" +
'<p><audio controls preload="metadata" src="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp3" title="inline.mp3"></audio></p>',
"</div>",
),
'<a href="http://example.com" target="_blank" rel="noopener noreferrer" title="http://example.com/">good</a> ' +
'<a href="http://zulip.zulipdev.com/user_uploads/w/ha/tever/file.png" target="_blank" rel="noopener noreferrer" title="translated: Download file.png">upload</a> ' +
@@ -75,8 +74,7 @@ run_test("postprocess_content", () => {
"</div>" +
'<div class="message_embed_description">All about us.</div>' +
"</div>" +
"</div>" +
'<p><span class="media-audio-wrapper"><audio controls="" preload="metadata" src="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp3" title="inline.mp3" class="media-audio-element"></audio></span></p>',
"</div>",
);
});

View File

@@ -151,6 +151,7 @@ const get_content_element = () => {
$content.set_find_results("div.spoiler-header", $array([]));
$content.set_find_results("div.codehilite", $array([]));
$content.set_find_results(".message_inline_video video", $array([]));
$content.set_find_results("audio", $array([]));
set_message_for_message_content($content, undefined);
@@ -538,6 +539,35 @@ run_test("timestamp without time", () => {
assert.equal($timestamp.text(), "never-been-set");
});
run_test("audio", ({mock_template}) => {
const audio_src = "http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp3";
const audio_title = "inline.mp3";
const $content = get_content_element();
const $audio = $.create("audio");
$audio.replaceWith = noop;
$audio.attr("src", audio_src);
$audio.attr("title", audio_title);
$content.set_find_results("audio", $array([$audio]));
let audio_html;
mock_template("markdown_audio.hbs", true, (data, html) => {
assert.deepEqual(data, {audio_src, audio_title});
audio_html = html;
return html;
});
rm.update_elements($content);
assert.equal(
audio_html,
'<span class="media-audio-wrapper">\n' +
' <audio controls="" preload="metadata" src="http://zulip.zulipdev.com/user_uploads/w/ha/tever/inline.mp3" title="inline.mp3" class="media-audio-element"></audio>\n' +
"</span>",
);
});
run_test("timestamp", ({mock_template}) => {
mock_template("markdown_timestamp.hbs", true, (data, html) => {
assert.deepEqual(data, {text: "Thu, Jan 1, 1970, 12:00 AM"});