From 28200830ed3bad73bdddc3f6df31ef65ee3e468d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Astori?= Date: Thu, 6 Jul 2017 03:35:54 -0400 Subject: [PATCH] Move preview toggle buttons next to their respective URLs and switch from ellipsis to caret --- client/css/style.css | 28 ++++++++++++++------ client/js/libs/handlebars/parse.js | 2 +- client/js/renderPreview.js | 10 ++++++-- client/views/index.js | 1 + client/views/msg_preview.tpl | 3 --- client/views/msg_preview_toggle.tpl | 10 ++++++++ test/client/js/libs/handlebars/parse.js | 34 ++++++++++++------------- 7 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 client/views/msg_preview_toggle.tpl diff --git a/client/css/style.css b/client/css/style.css index 4082cff3..f100305e 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -205,6 +205,7 @@ kbd { #chat .whois .from:before, #chat .nick .from:before, #chat .action .from:before, +#chat .toggle-button:after, .context-menu-item:before, #nick button:before { font: normal normal normal 14px/1 FontAwesome; @@ -293,6 +294,16 @@ kbd { content: "\f005"; /* http://fontawesome.io/icon/star/ */ } +#chat .toggle-button { + /* These 2 directives are loosely taken from .fa-fw */ + width: 1.35em; + text-align: center; +} + +#chat .toggle-button:after { + content: "\f0da"; /* http://fontawesome.io/icon/caret-right/ */ +} + #chat .count:before { color: #cfcfcf; content: "\f002"; /* http://fontawesome.io/icon/search/ */ @@ -1097,17 +1108,18 @@ kbd { } #chat .toggle-button { - background: #f5f5f5; - border-radius: 2px; display: inline-block; color: #666; - height: 1em; - line-height: 0; - padding: 0 6px; + transition: color .2s, transform .2s; } -#chat .toggle-button:after { - content: "ยทยทยท"; +#chat .toggle-button.opened { + transform: rotate(90deg); +} + +#chat .toggle-button:hover { + /* transform and opacity together glitch, so need to use RGBA transition */ + color: rgba(102, 102, 102, .8); /* #666 x .8 opacity */ } #chat .toggle-content { @@ -1118,7 +1130,7 @@ kbd { font-size: 12px; max-width: 100%; padding: 6px; - margin-top: 2px; + margin: 2px 0; overflow: hidden; } diff --git a/client/js/libs/handlebars/parse.js b/client/js/libs/handlebars/parse.js index 2d65c69e..1a581904 100644 --- a/client/js/libs/handlebars/parse.js +++ b/client/js/libs/handlebars/parse.js @@ -83,6 +83,6 @@ module.exports = function parse(text) { return fragments; }).join("") + linkParts.map((part) => { const escapedLink = Handlebars.Utils.escapeExpression(part.link); - return `
`; + return `
`; }).join(""); }; diff --git a/client/js/renderPreview.js b/client/js/renderPreview.js index a1f1ce54..86fb58c0 100644 --- a/client/js/renderPreview.js +++ b/client/js/renderPreview.js @@ -16,7 +16,11 @@ function renderPreview(preview, msg) { bottom = container.isScrollBottom(); } - msg.find(`[data-url="${preview.link}"]`) + msg.find(`.text a[href="${preview.link}"]`) + .first() + .after(templates.msg_preview_toggle({preview: preview})); + + msg.find(`.preview[data-url="${preview.link}"]`) .first() .append(templates.msg_preview({preview: preview})); @@ -30,13 +34,15 @@ function renderPreview(preview, msg) { $("#chat").on("click", ".toggle-button", function() { const self = $(this); const container = self.closest(".chat"); - const content = self.parent().next(".toggle-content"); + const content = self.closest(".text") + .find(`.preview[data-url="${self.data("url")}"] .toggle-content`); const bottom = container.isScrollBottom(); if (bottom && !content.hasClass("show")) { handleImageInPreview(content, container); } + self.toggleClass("opened"); content.toggleClass("show"); // If scrollbar was at the bottom before toggling the preview, keep it at the bottom diff --git a/client/views/index.js b/client/views/index.js index 9de19307..ca571bec 100644 --- a/client/views/index.js +++ b/client/views/index.js @@ -26,6 +26,7 @@ module.exports = { msg: require("./msg.tpl"), msg_action: require("./msg_action.tpl"), msg_preview: require("./msg_preview.tpl"), + msg_preview_toggle: require("./msg_preview_toggle.tpl"), msg_unhandled: require("./msg_unhandled.tpl"), network: require("./network.tpl"), unread_marker: require("./unread_marker.tpl"), diff --git a/client/views/msg_preview.tpl b/client/views/msg_preview.tpl index 2ebaa023..5f56529c 100644 --- a/client/views/msg_preview.tpl +++ b/client/views/msg_preview.tpl @@ -1,7 +1,4 @@ {{#preview}} -
- -
{{#equal type "image"}} diff --git a/client/views/msg_preview_toggle.tpl b/client/views/msg_preview_toggle.tpl new file mode 100644 index 00000000..386282cc --- /dev/null +++ b/client/views/msg_preview_toggle.tpl @@ -0,0 +1,10 @@ +{{#preview}} + +{{/preview}} diff --git a/test/client/js/libs/handlebars/parse.js b/test/client/js/libs/handlebars/parse.js index 5a011e77..aa0e5050 100644 --- a/test/client/js/libs/handlebars/parse.js +++ b/test/client/js/libs/handlebars/parse.js @@ -38,14 +38,14 @@ describe("parse Handlebars helper", () => { "" + "irc://freenode.net/thelounge" + "" + - "
" + "
" }, { input: "www.nooooooooooooooo.com", expected: "" + "www.nooooooooooooooo.com" + "" + - "
" + "
" }, { input: "look at https://thelounge.github.io/ for more information", expected: @@ -54,7 +54,7 @@ describe("parse Handlebars helper", () => { "https://thelounge.github.io/" + "" + " for more information" + - "
" + "
" }, { input: "use www.duckduckgo.com for privacy reasons", expected: @@ -63,14 +63,14 @@ describe("parse Handlebars helper", () => { "www.duckduckgo.com" + "" + " for privacy reasons" + - "
" + "
" }, { input: "svn+ssh://example.org", expected: "" + "svn+ssh://example.org" + "" + - "
" + "
" }, { input: "https://example.com https://example.org", expected: @@ -80,8 +80,8 @@ describe("parse Handlebars helper", () => { "" + "https://example.org" + "" + - "
" + - "
" + "
" + + "
" }]; const actual = testCases.map((testCase) => parse(testCase.input)); @@ -98,7 +98,7 @@ describe("parse Handlebars helper", () => { "" + "https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" + "" + - "
"; + "
"; const actual = parse(input); @@ -114,7 +114,7 @@ describe("parse Handlebars helper", () => { "https://theos.kyriasis.com/~kyrias/stats/archlinux.html" + "" + ">" + - "
" + "
" }, { input: "abc (www.example.com)", expected: @@ -123,21 +123,21 @@ describe("parse Handlebars helper", () => { "www.example.com" + "" + ")" + - "
" + "
" }, { input: "http://example.com/Test_(Page)", expected: "" + "http://example.com/Test_(Page)" + "" + - "
" + "
" }, { input: "www.example.com/Test_(Page)", expected: "" + "www.example.com/Test_(Page)" + "" + - "
" + "
" }]; const actual = testCases.map((testCase) => parse(testCase.input)); @@ -275,7 +275,7 @@ describe("parse Handlebars helper", () => { "/" + "thelounge" + "" + - "
" + "
" }, { input: "\x02#\x038,9thelounge", expected: @@ -315,7 +315,7 @@ describe("parse Handlebars helper", () => { "" + "http://example.com" + "" + - "
" + "
" }, { input: "like..HTTP://example.com", expected: @@ -323,7 +323,7 @@ describe("parse Handlebars helper", () => { "" + "HTTP://example.com" + "" + - "
" + "
" }]; const actual = testCases.map((testCase) => parse(testCase.input)); @@ -340,7 +340,7 @@ describe("parse Handlebars helper", () => { "" + "http://example.com/#hash" + "" + - "
" + "
" }]; const actual = testCases.map((testCase) => parse(testCase.input)); @@ -356,7 +356,7 @@ describe("parse Handlebars helper", () => { expect(actual).to.equal( "Url: http://example.com/path " + "Channel: ##channel" + - "
" + "
" ); }); });