Move preview toggle buttons next to their respective URLs and switch from ellipsis to caret
This commit is contained in:
parent
64ebe0f437
commit
28200830ed
@ -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;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,6 @@ module.exports = function parse(text) {
|
||||
return fragments;
|
||||
}).join("") + linkParts.map((part) => {
|
||||
const escapedLink = Handlebars.Utils.escapeExpression(part.link);
|
||||
return `<div data-url="${escapedLink}"></div>`;
|
||||
return `<div class="preview" data-url="${escapedLink}"></div>`;
|
||||
}).join("");
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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"),
|
||||
|
@ -1,7 +1,4 @@
|
||||
{{#preview}}
|
||||
<div>
|
||||
<button class="toggle-button" aria-label="Toggle prefetched media"></button>
|
||||
</div>
|
||||
<a href="{{link}}" target="_blank" rel="noopener" class="toggle-content toggle-type-{{type}}{{#if shown}} show{{/if}}">
|
||||
{{#equal type "image"}}
|
||||
<img src="{{link}}">
|
||||
|
10
client/views/msg_preview_toggle.tpl
Normal file
10
client/views/msg_preview_toggle.tpl
Normal file
@ -0,0 +1,10 @@
|
||||
{{#preview}}
|
||||
<button class="toggle-button {{#if shown}} opened{{/if}}"
|
||||
data-url="{{link}}"
|
||||
{{#equal type "image"}}
|
||||
aria-label="Toggle image preview"
|
||||
{{else}}
|
||||
aria-label="Toggle website preview"
|
||||
{{/equal}}
|
||||
></button>
|
||||
{{/preview}}
|
@ -38,14 +38,14 @@ describe("parse Handlebars helper", () => {
|
||||
"<a href=\"irc://freenode.net/thelounge\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"irc://freenode.net/thelounge" +
|
||||
"</a>" +
|
||||
"<div data-url=\"irc://freenode.net/thelounge\"></div>"
|
||||
"<div class=\"preview\" data-url=\"irc://freenode.net/thelounge\"></div>"
|
||||
}, {
|
||||
input: "www.nooooooooooooooo.com",
|
||||
expected:
|
||||
"<a href=\"http://www.nooooooooooooooo.com\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"www.nooooooooooooooo.com" +
|
||||
"</a>" +
|
||||
"<div data-url=\"http://www.nooooooooooooooo.com\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://www.nooooooooooooooo.com\"></div>"
|
||||
}, {
|
||||
input: "look at https://thelounge.github.io/ for more information",
|
||||
expected:
|
||||
@ -54,7 +54,7 @@ describe("parse Handlebars helper", () => {
|
||||
"https://thelounge.github.io/" +
|
||||
"</a>" +
|
||||
" for more information" +
|
||||
"<div data-url=\"https://thelounge.github.io/\"></div>"
|
||||
"<div class=\"preview\" data-url=\"https://thelounge.github.io/\"></div>"
|
||||
}, {
|
||||
input: "use www.duckduckgo.com for privacy reasons",
|
||||
expected:
|
||||
@ -63,14 +63,14 @@ describe("parse Handlebars helper", () => {
|
||||
"www.duckduckgo.com" +
|
||||
"</a>" +
|
||||
" for privacy reasons" +
|
||||
"<div data-url=\"http://www.duckduckgo.com\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://www.duckduckgo.com\"></div>"
|
||||
}, {
|
||||
input: "svn+ssh://example.org",
|
||||
expected:
|
||||
"<a href=\"svn+ssh://example.org\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"svn+ssh://example.org" +
|
||||
"</a>" +
|
||||
"<div data-url=\"svn+ssh://example.org\"></div>"
|
||||
"<div class=\"preview\" data-url=\"svn+ssh://example.org\"></div>"
|
||||
}, {
|
||||
input: "https://example.com https://example.org",
|
||||
expected:
|
||||
@ -80,8 +80,8 @@ describe("parse Handlebars helper", () => {
|
||||
"<a href=\"https://example.org\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"https://example.org" +
|
||||
"</a>" +
|
||||
"<div data-url=\"https://example.com\"></div>" +
|
||||
"<div data-url=\"https://example.org\"></div>"
|
||||
"<div class=\"preview\" data-url=\"https://example.com\"></div>" +
|
||||
"<div class=\"preview\" data-url=\"https://example.org\"></div>"
|
||||
}];
|
||||
|
||||
const actual = testCases.map((testCase) => parse(testCase.input));
|
||||
@ -98,7 +98,7 @@ describe("parse Handlebars helper", () => {
|
||||
"<a href=\"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" +
|
||||
"</a>" +
|
||||
"<div data-url=\"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx\"></div>";
|
||||
"<div class=\"preview\" data-url=\"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx\"></div>";
|
||||
|
||||
const actual = parse(input);
|
||||
|
||||
@ -114,7 +114,7 @@ describe("parse Handlebars helper", () => {
|
||||
"https://theos.kyriasis.com/~kyrias/stats/archlinux.html" +
|
||||
"</a>" +
|
||||
">" +
|
||||
"<div data-url=\"https://theos.kyriasis.com/~kyrias/stats/archlinux.html\"></div>"
|
||||
"<div class=\"preview\" data-url=\"https://theos.kyriasis.com/~kyrias/stats/archlinux.html\"></div>"
|
||||
}, {
|
||||
input: "abc (www.example.com)",
|
||||
expected:
|
||||
@ -123,21 +123,21 @@ describe("parse Handlebars helper", () => {
|
||||
"www.example.com" +
|
||||
"</a>" +
|
||||
")" +
|
||||
"<div data-url=\"http://www.example.com\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://www.example.com\"></div>"
|
||||
}, {
|
||||
input: "http://example.com/Test_(Page)",
|
||||
expected:
|
||||
"<a href=\"http://example.com/Test_(Page)\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"http://example.com/Test_(Page)" +
|
||||
"</a>" +
|
||||
"<div data-url=\"http://example.com/Test_(Page)\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://example.com/Test_(Page)\"></div>"
|
||||
}, {
|
||||
input: "www.example.com/Test_(Page)",
|
||||
expected:
|
||||
"<a href=\"http://www.example.com/Test_(Page)\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"www.example.com/Test_(Page)" +
|
||||
"</a>" +
|
||||
"<div data-url=\"http://www.example.com/Test_(Page)\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://www.example.com/Test_(Page)\"></div>"
|
||||
}];
|
||||
|
||||
const actual = testCases.map((testCase) => parse(testCase.input));
|
||||
@ -275,7 +275,7 @@ describe("parse Handlebars helper", () => {
|
||||
"/" +
|
||||
"<span class=\"irc-fg4 irc-bg8\">thelounge</span>" +
|
||||
"</a>" +
|
||||
"<div data-url=\"irc://freenode.net/thelounge\"></div>"
|
||||
"<div class=\"preview\" data-url=\"irc://freenode.net/thelounge\"></div>"
|
||||
}, {
|
||||
input: "\x02#\x038,9thelounge",
|
||||
expected:
|
||||
@ -315,7 +315,7 @@ describe("parse Handlebars helper", () => {
|
||||
"<a href=\"http://example.com\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"http://example.com" +
|
||||
"</a>" +
|
||||
"<div data-url=\"http://example.com\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://example.com\"></div>"
|
||||
}, {
|
||||
input: "like..HTTP://example.com",
|
||||
expected:
|
||||
@ -323,7 +323,7 @@ describe("parse Handlebars helper", () => {
|
||||
"<a href=\"HTTP://example.com\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"HTTP://example.com" +
|
||||
"</a>" +
|
||||
"<div data-url=\"HTTP://example.com\"></div>"
|
||||
"<div class=\"preview\" data-url=\"HTTP://example.com\"></div>"
|
||||
}];
|
||||
|
||||
const actual = testCases.map((testCase) => parse(testCase.input));
|
||||
@ -340,7 +340,7 @@ describe("parse Handlebars helper", () => {
|
||||
"<a href=\"http://example.com/#hash\" target=\"_blank\" rel=\"noopener\">" +
|
||||
"http://example.com/#hash" +
|
||||
"</a>" +
|
||||
"<div data-url=\"http://example.com/#hash\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://example.com/#hash\"></div>"
|
||||
}];
|
||||
|
||||
const actual = testCases.map((testCase) => parse(testCase.input));
|
||||
@ -356,7 +356,7 @@ describe("parse Handlebars helper", () => {
|
||||
expect(actual).to.equal(
|
||||
"Url: <a href=\"http://example.com/path\" target=\"_blank\" rel=\"noopener\">http://example.com/path</a> " +
|
||||
"Channel: <span class=\"inline-channel\" role=\"button\" tabindex=\"0\" data-chan=\"##channel\">##channel</span>" +
|
||||
"<div data-url=\"http://example.com/path\"></div>"
|
||||
"<div class=\"preview\" data-url=\"http://example.com/path\"></div>"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user