Merge pull request #2821 from Raqbit/show-link-filesize

Add file size to link preview
This commit is contained in:
Pavel Djundik 2019-11-08 16:53:56 +02:00 committed by GitHub
commit 61f86b1557
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 32 deletions

View file

@ -0,0 +1,34 @@
<template>
<span class="preview-size">({{ previewSize }})</span>
</template>
<script>
const constants = require("../js/constants");
export default {
name: "LinkPreviewFileSize",
props: {
size: Number,
},
computed: {
previewSize() {
let size = this.size;
// Threshold for SI units
const thresh = 1024;
let u = 0;
do {
size /= thresh;
++u;
} while (size >= thresh && u < constants.sizeUnits.length - 1);
const displaySize = size.toFixed(1);
const unit = constants.sizeUnits[u];
return `${displaySize} ${unit}`;
},
},
};
</script>

View file

@ -1475,6 +1475,11 @@ background on hover (unless active) */
border-left: 1px solid var(--highlight-bg-color);
}
#chat .preview-size {
margin-left: 5px;
user-select: none;
}
#chat .toggle-content.opened .more-caret, /* Expand/Collapse link previews */
#chat .toggle-button.opened, /* Thumbnail toggle */
#chat .msg.condensed:not(.closed) .toggle-button { /* Expanded status message toggle */

View file

@ -27,10 +27,13 @@ const timeFormats = {
msgWithSeconds: "HH:mm:ss",
};
const sizeUnits = ["B", "KiB", "MiB", "GiB", "TiB"];
module.exports = {
colorCodeMap,
commands: [],
condensedTypes,
condensedTypesQuery,
timeFormats,
sizeUnits,
};

View file

@ -9,6 +9,7 @@ const merge = require("./ircmessageparser/merge");
const colorClass = require("./colorClass");
const emojiMap = require("../fullnamemap.json");
const LinkPreviewToggle = require("../../../components/LinkPreviewToggle.vue").default;
const LinkPreviewFileSize = require("../../../components/LinkPreviewFileSize.vue").default;
const emojiModifiersRegex = /[\u{1f3fb}-\u{1f3ff}]/gu;
// Create an HTML `span` with styling information for a given fragment
@ -96,12 +97,16 @@ module.exports = function parse(createElement, text, message = undefined, networ
// Wrap these potentially styled fragments with links and channel buttons
if (textPart.link) {
const preview = message && message.previews.find((p) => p.link === textPart.link);
const preview =
message &&
message.previews &&
message.previews.find((p) => p.link === textPart.link);
const link = createElement(
"a",
{
attrs: {
href: textPart.link,
dir: preview ? null : "auto",
target: "_blank",
rel: "noopener",
},
@ -113,6 +118,28 @@ module.exports = function parse(createElement, text, message = undefined, networ
return link;
}
const linkEls = [link];
if (preview.size > 0) {
linkEls.push(
createElement(LinkPreviewFileSize, {
props: {
size: preview.size,
},
})
);
}
linkEls.push(
createElement(LinkPreviewToggle, {
props: {
link: preview,
},
})
);
// We wrap the link, size, and the toggle button into <span dir="auto">
// to correctly keep the left-to-right order of these elements
return createElement(
"span",
{
@ -120,19 +147,7 @@ module.exports = function parse(createElement, text, message = undefined, networ
dir: "auto",
},
},
[
link,
createElement(
LinkPreviewToggle,
{
class: ["toggle-button", "toggle-preview"],
props: {
link: preview,
},
},
fragments
),
]
linkEls
);
} else if (textPart.channel) {
return createElement(

View file

@ -43,6 +43,7 @@ module.exports = function(client, chan, msg) {
head: "",
body: "",
thumb: "",
size: -1,
link: link.link, // Send original matched link to the client
shown: true,
};
@ -181,8 +182,11 @@ function parseHtmlMedia($, preview, client) {
function parse(msg, chan, preview, res, client) {
let promise;
preview.size = res.size;
switch (res.type) {
case "text/html":
preview.size = -1;
promise = parseHtml(preview, res, client);
break;

View file

@ -25,7 +25,7 @@ describe("parse Handlebars helper", () => {
{
input: "<img onerror='location.href=\"//youtube.com\"'>",
expected:
'&lt;img onerror=\'location.href=&quot;<a href="http://youtube.com" target="_blank" rel="noopener">//youtube.com</a>&quot;\'&gt;',
'&lt;img onerror=\'location.href=&quot;<a href="http://youtube.com" dir="auto" target="_blank" rel="noopener">//youtube.com</a>&quot;\'&gt;',
},
{
input: '#&">bug',
@ -61,14 +61,14 @@ describe("parse Handlebars helper", () => {
{
input: "irc://freenode.net/thelounge",
expected:
'<a href="irc://freenode.net/thelounge" target="_blank" rel="noopener">' +
'<a href="irc://freenode.net/thelounge" dir="auto" target="_blank" rel="noopener">' +
"irc://freenode.net/thelounge" +
"</a>",
},
{
input: "www.nooooooooooooooo.com",
expected:
'<a href="http://www.nooooooooooooooo.com" target="_blank" rel="noopener">' +
'<a href="http://www.nooooooooooooooo.com" dir="auto" target="_blank" rel="noopener">' +
"www.nooooooooooooooo.com" +
"</a>",
},
@ -76,7 +76,7 @@ describe("parse Handlebars helper", () => {
input: "look at https://thelounge.chat/ for more information",
expected:
"look at " +
'<a href="https://thelounge.chat/" target="_blank" rel="noopener">' +
'<a href="https://thelounge.chat/" dir="auto" target="_blank" rel="noopener">' +
"https://thelounge.chat/" +
"</a>" +
" for more information",
@ -85,7 +85,7 @@ describe("parse Handlebars helper", () => {
input: "use www.duckduckgo.com for privacy reasons",
expected:
"use " +
'<a href="http://www.duckduckgo.com" target="_blank" rel="noopener">' +
'<a href="http://www.duckduckgo.com" dir="auto" target="_blank" rel="noopener">' +
"www.duckduckgo.com" +
"</a>" +
" for privacy reasons",
@ -93,7 +93,7 @@ describe("parse Handlebars helper", () => {
{
input: "svn+ssh://example.org",
expected:
'<a href="svn+ssh://example.org" target="_blank" rel="noopener">' +
'<a href="svn+ssh://example.org" dir="auto" target="_blank" rel="noopener">' +
"svn+ssh://example.org" +
"</a>",
},
@ -110,7 +110,7 @@ describe("parse Handlebars helper", () => {
"bonuspunkt: your URL parser misparses this URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx";
const correctResult =
"bonuspunkt: your URL parser misparses this URL: " +
'<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" target="_blank" rel="noopener">' +
'<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" dir="auto" target="_blank" rel="noopener">' +
"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" +
"</a>";
@ -125,7 +125,7 @@ describe("parse Handlebars helper", () => {
input: "<https://theos.kyriasis.com/~kyrias/stats/archlinux.html>",
expected:
"&lt;" +
'<a href="https://theos.kyriasis.com/~kyrias/stats/archlinux.html" target="_blank" rel="noopener">' +
'<a href="https://theos.kyriasis.com/~kyrias/stats/archlinux.html" dir="auto" target="_blank" rel="noopener">' +
"https://theos.kyriasis.com/~kyrias/stats/archlinux.html" +
"</a>" +
"&gt;",
@ -134,7 +134,7 @@ describe("parse Handlebars helper", () => {
input: "abc (www.example.com)",
expected:
"abc (" +
'<a href="http://www.example.com" target="_blank" rel="noopener">' +
'<a href="http://www.example.com" dir="auto" target="_blank" rel="noopener">' +
"www.example.com" +
"</a>" +
")",
@ -142,14 +142,14 @@ describe("parse Handlebars helper", () => {
{
input: "http://example.com/Test_(Page)",
expected:
'<a href="http://example.com/Test_(Page)" target="_blank" rel="noopener">' +
'<a href="http://example.com/Test_(Page)" dir="auto" target="_blank" rel="noopener">' +
"http://example.com/Test_(Page)" +
"</a>",
},
{
input: "www.example.com/Test_(Page)",
expected:
'<a href="http://www.example.com/Test_(Page)" target="_blank" rel="noopener">' +
'<a href="http://www.example.com/Test_(Page)" dir="auto" target="_blank" rel="noopener">' +
"www.example.com/Test_(Page)" +
"</a>",
},
@ -386,7 +386,7 @@ describe("parse Handlebars helper", () => {
users: ["MaxLeiter, test"],
input: "https://www.MaxLeiter.com/test",
expected:
'<a href="https://www.MaxLeiter.com/test" target="_blank" rel="noopener">' +
'<a href="https://www.MaxLeiter.com/test" dir="auto" target="_blank" rel="noopener">' +
"https://www.MaxLeiter.com/test" +
"</a>",
},
@ -403,7 +403,7 @@ describe("parse Handlebars helper", () => {
{
input: "\x02irc\x0f://\x1dfreenode.net\x0f/\x034,8thelounge",
expected:
'<a href="irc://freenode.net/thelounge" target="_blank" rel="noopener">' +
'<a href="irc://freenode.net/thelounge" dir="auto" target="_blank" rel="noopener">' +
'<span class="irc-bold">irc</span>' +
"://" +
'<span class="irc-italic">freenode.net</span>' +
@ -470,7 +470,7 @@ describe("parse Handlebars helper", () => {
input: "https://i.❤️.thelounge.chat",
// FIXME: Emoji in text should be `<span class="emoji">❤️</span>`. See https://github.com/thelounge/thelounge/issues/1784
expected:
'<a href="https://i.❤️.thelounge.chat" target="_blank" rel="noopener">https://i.❤️.thelounge.chat</a>',
'<a href="https://i.❤️.thelounge.chat" dir="auto" target="_blank" rel="noopener">https://i.❤️.thelounge.chat</a>',
},
{
name: "wrapped in channels",
@ -511,7 +511,7 @@ describe("parse Handlebars helper", () => {
input: "like..http://example.com",
expected:
"like.." +
'<a href="http://example.com" target="_blank" rel="noopener">' +
'<a href="http://example.com" dir="auto" target="_blank" rel="noopener">' +
"http://example.com" +
"</a>",
},
@ -519,7 +519,7 @@ describe("parse Handlebars helper", () => {
input: "like..HTTP://example.com",
expected:
"like.." +
'<a href="HTTP://example.com" target="_blank" rel="noopener">' +
'<a href="HTTP://example.com" dir="auto" target="_blank" rel="noopener">' +
"HTTP://example.com" +
"</a>",
},
@ -536,7 +536,7 @@ describe("parse Handlebars helper", () => {
{
input: "http://example.com/#hash",
expected:
'<a href="http://example.com/#hash" target="_blank" rel="noopener">' +
'<a href="http://example.com/#hash" dir="auto" target="_blank" rel="noopener">' +
"http://example.com/#hash" +
"</a>",
},
@ -553,7 +553,7 @@ describe("parse Handlebars helper", () => {
const actual = getParsedMessageContents(input);
expect(actual).to.equal(
'Url: <a href="http://example.com/path" target="_blank" rel="noopener">http://example.com/path</a> ' +
'Url: <a href="http://example.com/path" dir="auto" target="_blank" rel="noopener">http://example.com/path</a> ' +
'Channel: <span role="button" dir="auto" tabindex="0" data-chan="##channel" class="inline-channel">##channel</span>'
);
});

View file

@ -45,6 +45,7 @@ describe("Link plugin", function() {
head: "",
link: url,
thumb: "",
size: -1,
type: "loading",
shown: true,
},
@ -278,6 +279,7 @@ describe("Link plugin", function() {
expect(data.preview.thumb).to.equal(
"http://localhost:" + port + "/real-test-image.png"
);
expect(data.preview.size).to.equal(960);
done();
});
});
@ -296,6 +298,7 @@ describe("Link plugin", function() {
head: "",
link: "http://localhost:" + port + "/one",
thumb: "",
size: -1,
type: "loading",
shown: true,
},
@ -304,6 +307,7 @@ describe("Link plugin", function() {
head: "",
link: "http://localhost:" + port + "/two",
thumb: "",
size: -1,
type: "loading",
shown: true,
},
@ -496,6 +500,7 @@ describe("Link plugin", function() {
head: "",
body: "",
thumb: "",
size: -1,
link: "http://localhost:" + port + "",
shown: true,
},