FEATURE: Use upload:// short URL for videos and audio in composer (#8760)

For consistency this PR introduces using custom markdown and short upload:// URLs for video and audio uploads, rather than just treating them as links and relying on the oneboxer. The markdown syntax for videos is ![file text|video](upload://123456.mp4) and for audio it is ![file text|audio](upload://123456.mp3).

This is achieved in discourse-markdown-it by modifying the rules for images in mardown-it via md.renderer.rules.image. We return HTML instead of the token when we encounter audio or video after | and the preview renders that HTML. Also when uploading an audio or video file we insert the relevant markdown into the composer.
This commit is contained in:
Martin Brennan
2020-01-23 09:41:39 +10:00
committed by GitHub
parent 4646a38ae6
commit 65481858c2
9 changed files with 190 additions and 76 deletions

View File

@@ -973,6 +973,28 @@ QUnit.test("images", assert => {
);
});
QUnit.test("video", assert => {
assert.cooked(
"![baby shark|video](upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp4)",
`<p><video width="100%" height="100%" controls>
<source src="/404" data-orig-src="upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp4">
<a href="/404">/404</a>
</video></p>`,
"It returns the correct video player HTML"
);
});
QUnit.test("audio", assert => {
assert.cooked(
"![young americans|audio](upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp3)",
`<p><audio controls>
<source src="/404" data-orig-src="upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp3">
<a href="/404">/404</a>
</audio></p>`,
"It returns the correct audio player HTML"
);
});
QUnit.test("censoring", assert => {
assert.cookedOptions(
"Pleased to meet you, but pleeeease call me later, xyz123",

View File

@@ -33,9 +33,22 @@ QUnit.module("lib:pretty-text/upload-short-url", {
}
];
const otherMediaSrcs = [
{
short_url: "upload://d.mp4",
url: "/uploads/default/original/3X/c/b/4.mp4",
short_path: "/uploads/short-url/d.mp4"
},
{
short_url: "upload://e.mp3",
url: "/uploads/default/original/3X/c/b/5.mp3",
short_path: "/uploads/short-url/e.mp3"
}
];
// prettier-ignore
server.post("/uploads/lookup-urls", () => { //eslint-disable-line
return response(imageSrcs.concat(attachmentSrcs));
return response(imageSrcs.concat(attachmentSrcs.concat(otherMediaSrcs)));
});
fixture().html(
@@ -79,4 +92,16 @@ QUnit.test("resolveAllShortUrls", async assert => {
url: "/uploads/default/original/3X/c/b/3.pdf",
short_path: "/uploads/short-url/c.pdf"
});
lookup = lookupCachedUploadUrl("upload://d.mp4");
assert.deepEqual(lookup, {
url: "/uploads/default/original/3X/c/b/4.mp4",
short_path: "/uploads/short-url/d.mp4"
});
lookup = lookupCachedUploadUrl("upload://e.mp3");
assert.deepEqual(lookup, {
url: "/uploads/default/original/3X/c/b/5.mp3",
short_path: "/uploads/short-url/e.mp3"
});
});

View File

@@ -1,7 +1,7 @@
import {
validateUploadedFiles,
authorizedExtensions,
isAnImage,
isImage,
allowsImages,
allowsAttachments,
getUploadMarkdown
@@ -122,18 +122,18 @@ QUnit.test("allows valid uploads to go through", assert => {
assert.not(bootbox.alert.calledOnce);
});
QUnit.test("isAnImage", assert => {
QUnit.test("isImage", assert => {
["png", "jpg", "jpeg", "gif", "ico"].forEach(extension => {
var image = "image." + extension;
assert.ok(isAnImage(image), image + " is recognized as an image");
assert.ok(isImage(image), image + " is recognized as an image");
assert.ok(
isAnImage("http://foo.bar/path/to/" + image),
isImage("http://foo.bar/path/to/" + image),
image + " is recognized as an image"
);
});
assert.not(isAnImage("file.txt"));
assert.not(isAnImage("http://foo.bar/path/to/file.txt"));
assert.not(isAnImage(""));
assert.not(isImage("file.txt"));
assert.not(isImage("http://foo.bar/path/to/file.txt"));
assert.not(isImage(""));
});
QUnit.test("allowsImages", assert => {