diff --git a/client/components/LinkPreviewFileSize.vue b/client/components/LinkPreviewFileSize.vue
new file mode 100644
index 00000000..3e2b0179
--- /dev/null
+++ b/client/components/LinkPreviewFileSize.vue
@@ -0,0 +1,34 @@
+
+ ({{ previewSize }})
+
+
+
diff --git a/client/css/style.css b/client/css/style.css
index 2edf282a..96ed5c79 100644
--- a/client/css/style.css
+++ b/client/css/style.css
@@ -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 */
diff --git a/client/js/constants.js b/client/js/constants.js
index 0b91ca23..40677f70 100644
--- a/client/js/constants.js
+++ b/client/js/constants.js
@@ -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,
};
diff --git a/client/js/libs/handlebars/parse.js b/client/js/libs/handlebars/parse.js
index e7b3048c..9488c020 100644
--- a/client/js/libs/handlebars/parse.js
+++ b/client/js/libs/handlebars/parse.js
@@ -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
+ // 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(
diff --git a/src/plugins/irc-events/link.js b/src/plugins/irc-events/link.js
index 90122945..b1e3c050 100644
--- a/src/plugins/irc-events/link.js
+++ b/src/plugins/irc-events/link.js
@@ -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;
diff --git a/test/client/js/libs/handlebars/parse.js b/test/client/js/libs/handlebars/parse.js
index 08160801..b8bde3c9 100644
--- a/test/client/js/libs/handlebars/parse.js
+++ b/test/client/js/libs/handlebars/parse.js
@@ -25,7 +25,7 @@ describe("parse Handlebars helper", () => {
{
input: "",
expected:
- '<img onerror=\'location.href="//youtube.com"\'>',
+ '<img onerror=\'location.href="//youtube.com"\'>',
},
{
input: '#&">bug',
@@ -61,14 +61,14 @@ describe("parse Handlebars helper", () => {
{
input: "irc://freenode.net/thelounge",
expected:
- '' +
+ '' +
"irc://freenode.net/thelounge" +
"",
},
{
input: "www.nooooooooooooooo.com",
expected:
- '' +
+ '' +
"www.nooooooooooooooo.com" +
"",
},
@@ -76,7 +76,7 @@ describe("parse Handlebars helper", () => {
input: "look at https://thelounge.chat/ for more information",
expected:
"look at " +
- '' +
+ '' +
"https://thelounge.chat/" +
"" +
" for more information",
@@ -85,7 +85,7 @@ describe("parse Handlebars helper", () => {
input: "use www.duckduckgo.com for privacy reasons",
expected:
"use " +
- '' +
+ '' +
"www.duckduckgo.com" +
"" +
" for privacy reasons",
@@ -93,7 +93,7 @@ describe("parse Handlebars helper", () => {
{
input: "svn+ssh://example.org",
expected:
- '' +
+ '' +
"svn+ssh://example.org" +
"",
},
@@ -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: " +
- '' +
+ '' +
"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" +
"";
@@ -125,7 +125,7 @@ describe("parse Handlebars helper", () => {
input: "",
expected:
"<" +
- '' +
+ '' +
"https://theos.kyriasis.com/~kyrias/stats/archlinux.html" +
"" +
">",
@@ -134,7 +134,7 @@ describe("parse Handlebars helper", () => {
input: "abc (www.example.com)",
expected:
"abc (" +
- '' +
+ '' +
"www.example.com" +
"" +
")",
@@ -142,14 +142,14 @@ describe("parse Handlebars helper", () => {
{
input: "http://example.com/Test_(Page)",
expected:
- '' +
+ '' +
"http://example.com/Test_(Page)" +
"",
},
{
input: "www.example.com/Test_(Page)",
expected:
- '' +
+ '' +
"www.example.com/Test_(Page)" +
"",
},
@@ -386,7 +386,7 @@ describe("parse Handlebars helper", () => {
users: ["MaxLeiter, test"],
input: "https://www.MaxLeiter.com/test",
expected:
- '' +
+ '' +
"https://www.MaxLeiter.com/test" +
"",
},
@@ -403,7 +403,7 @@ describe("parse Handlebars helper", () => {
{
input: "\x02irc\x0f://\x1dfreenode.net\x0f/\x034,8thelounge",
expected:
- '' +
+ '' +
'irc' +
"://" +
'freenode.net' +
@@ -470,7 +470,7 @@ describe("parse Handlebars helper", () => {
input: "https://i.❤️.thelounge.chat",
// FIXME: Emoji in text should be `❤️`. See https://github.com/thelounge/thelounge/issues/1784
expected:
- 'https://i.❤️.thelounge.chat',
+ 'https://i.❤️.thelounge.chat',
},
{
name: "wrapped in channels",
@@ -511,7 +511,7 @@ describe("parse Handlebars helper", () => {
input: "like..http://example.com",
expected:
"like.." +
- '' +
+ '' +
"http://example.com" +
"",
},
@@ -519,7 +519,7 @@ describe("parse Handlebars helper", () => {
input: "like..HTTP://example.com",
expected:
"like.." +
- '' +
+ '' +
"HTTP://example.com" +
"",
},
@@ -536,7 +536,7 @@ describe("parse Handlebars helper", () => {
{
input: "http://example.com/#hash",
expected:
- '' +
+ '' +
"http://example.com/#hash" +
"",
},
@@ -553,7 +553,7 @@ describe("parse Handlebars helper", () => {
const actual = getParsedMessageContents(input);
expect(actual).to.equal(
- 'Url: http://example.com/path ' +
+ 'Url: http://example.com/path ' +
'Channel: ##channel'
);
});
diff --git a/test/plugins/link.js b/test/plugins/link.js
index a7aa04b0..ae0bbfaf 100644
--- a/test/plugins/link.js
+++ b/test/plugins/link.js
@@ -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,
},