diff --git a/client/css/style.css b/client/css/style.css
index 0c6f9947..c5e8baff 100644
--- a/client/css/style.css
+++ b/client/css/style.css
@@ -238,6 +238,7 @@ kbd {
#chat .nick .from::before,
#chat .action .from::before,
#chat .toggle-button::after,
+#chat .toggle-content .more-caret::before,
#version-checker::before,
.context-menu-item::before,
#help .website-link::before,
@@ -1332,75 +1333,112 @@ kbd {
color: #f00;
}
+#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 */
transform: rotate(90deg);
}
#chat .toggle-content {
- background: #f5f5f5;
- border-radius: 2px;
+ background: #f6f6f6;
+ border-radius: 5px;
display: none;
- color: #222;
max-width: 100%;
margin: 0;
margin-top: 6px;
overflow: hidden;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
+ contain: content; /* This fixes a display bug where border-radius stopped working on image link hover */
}
-#chat .toggle-type-error {
- background: transparent;
-}
-
+/* This applies to images of preview-type-image and thumbnails of preview-type-link */
#chat .toggle-content img {
max-width: 100%;
max-height: 128px;
display: block;
+ cursor: zoom-in;
}
-#chat .prefetch-error {
+#chat .toggle-content pre.prefetch-error {
+ padding: 0;
+ margin: 0;
+ color: inherit;
+ background-color: transparent;
+}
+
+#chat .toggle-content .prefetch-error {
display: none;
}
+#chat .toggle-content.opened .prefetch-error {
+ display: inline;
+}
+
+/* This applies to thumbnails of preview-type-link only */
#chat .toggle-content .thumb {
- max-width: 48px;
- max-height: 38px;
+ max-height: 54px;
+ max-width: 96px;
}
-#chat .toggle-thumbnail {
- padding: 6px;
+#chat .toggle-type-error,
+#chat .toggle-content .toggle-text {
+ padding: 8px 10px;
}
-#chat .toggle-text {
- padding: 6px;
- min-width: 0;
- display: flex;
- flex-direction: column;
+#chat .toggle-content .toggle-text {
white-space: nowrap;
- color: inherit;
-}
-
-#chat .toggle-text:not(:first-child) {
- padding-left: 0;
-}
-
-#chat .toggle-content .head,
-#chat .toggle-content .body {
- text-overflow: ellipsis;
overflow: hidden;
- color: inherit;
+}
+
+#chat .toggle-content.opened .toggle-text {
+ white-space: normal;
}
#chat .toggle-content .head {
+ display: flex;
+ align-items: flex-start;
font-weight: bold;
+ color: #222;
}
-#chat .toggle-content .body {
- color: #999;
+#chat .toggle-type-error,
+#chat .toggle-text .body {
+ color: #717171;
+}
+
+#chat .toggle-text a {
+ color: inherit;
+}
+
+#chat .toggle-text .overflowable {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ flex-grow: 1;
+}
+
+#chat .toggle-content .more {
+ color: #50a656;
+ font-weight: normal;
+ margin-left: 10px;
+ flex-shrink: 0;
+}
+
+#chat .toggle-content .more::after {
+ content: attr(aria-label);
+}
+
+#chat .toggle-content .more-caret {
+ display: inline-block;
+ transition: transform 0.2s;
+}
+
+#chat .toggle-content .more-caret::before {
+ content: "\f0da"; /* https://fontawesome.com/icons/caret-right?style=solid */
}
#chat .toggle-content.show {
display: inline-flex !important;
+ align-items: flex-start;
}
#chat audio {
@@ -2322,6 +2360,11 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
#chat .header .title {
padding-left: 6px;
}
+
+ #chat .toggle-content .thumb {
+ max-height: 58px;
+ max-width: 104px;
+ }
}
@media (max-width: 479px) {
diff --git a/client/js/lounge.js b/client/js/lounge.js
index 106ca1e2..be9d6fc9 100644
--- a/client/js/lounge.js
+++ b/client/js/lounge.js
@@ -49,6 +49,7 @@ $(function() {
slideoutMenu.toggle(isOpen);
storeSidebarVisibility("thelounge.state.sidebar", isOpen);
+ utils.togglePreviewMoreButtonsIfNeeded();
});
viewport.on("click", ".rt", function() {
@@ -57,6 +58,7 @@ $(function() {
viewport.toggleClass("rt", isOpen);
chat.find(".chan.active .chat").trigger("keepToBottom");
storeSidebarVisibility("thelounge.state.userlist", isOpen);
+ utils.togglePreviewMoreButtonsIfNeeded();
return false;
});
@@ -252,6 +254,8 @@ $(function() {
if (!keepSidebarOpen && $(window).outerWidth() < utils.mobileViewportPixels) {
slideoutMenu.toggle(false);
}
+
+ utils.togglePreviewMoreButtonsIfNeeded();
}
const lastActive = $("#windows > .active");
diff --git a/client/js/renderPreview.js b/client/js/renderPreview.js
index 99fb0f53..8530d053 100644
--- a/client/js/renderPreview.js
+++ b/client/js/renderPreview.js
@@ -66,6 +66,26 @@ function appendPreview(preview, msg, template) {
previewContainer.append(template);
+ const moreBtn = previewContainer.find(".more");
+ const previewContent = previewContainer.find(".toggle-content")[0];
+
+ const showMoreIfNeeded = () => {
+ if (preview.type === "link") {
+ const isVisible = moreBtn.is(":visible");
+ const shouldShow = previewContent.offsetWidth >= previewContainer[0].offsetWidth;
+
+ if (!isVisible && shouldShow) {
+ moreBtn.show();
+ } else if (isVisible && !shouldShow) {
+ togglePreviewMore(moreBtn, false);
+ moreBtn.hide();
+ }
+ }
+ };
+
+ $(window).on("resize", showMoreIfNeeded);
+ window.requestAnimationFrame(showMoreIfNeeded);
+
if (activeChannelId === channelId) {
container.trigger("keepToBottom");
}
@@ -97,6 +117,24 @@ $("#chat").on("click", ".text .toggle-button", function() {
}
});
+$("#chat").on("click", ".toggle-content .more", function() {
+ togglePreviewMore($(this));
+ return false;
+});
+
+function togglePreviewMore(moreBtn, state = undefined) {
+ moreBtn.closest(".toggle-content").toggleClass("opened", state);
+ const isExpanded = moreBtn.closest(".toggle-content").hasClass("opened");
+
+ moreBtn.attr("aria-expanded", isExpanded);
+
+ if (isExpanded) {
+ moreBtn.attr("aria-label", moreBtn.data("opened-text"));
+ } else {
+ moreBtn.attr("aria-label", moreBtn.data("closed-text"));
+ }
+}
+
/* Image viewer */
const imageViewer = $("#image-viewer");
diff --git a/client/js/utils.js b/client/js/utils.js
index e9f73090..a7660d8f 100644
--- a/client/js/utils.js
+++ b/client/js/utils.js
@@ -23,6 +23,7 @@ module.exports = {
toggleNickEditor,
toggleNotificationMarkers,
requestIdleCallback,
+ togglePreviewMoreButtonsIfNeeded,
};
function findCurrentNetworkChan(name) {
@@ -141,3 +142,8 @@ function requestIdleCallback(callback, timeout) {
callback();
}
}
+
+// Force handling preview display
+function togglePreviewMoreButtonsIfNeeded() {
+ window.requestAnimationFrame(() => $(window).trigger("resize"));
+}
diff --git a/client/views/msg_preview.tpl b/client/views/msg_preview.tpl
index 1e1cb916..5186e133 100644
--- a/client/views/msg_preview.tpl
+++ b/client/views/msg_preview.tpl
@@ -23,10 +23,31 @@
{{/if}}
-
-