mirror of
https://github.com/zulip/zulip.git
synced 2025-11-16 11:52:01 +00:00
Add overlay lightbox for displaying inline image previews.
This adds an event listener (by way of delegation) to the .message_inline_image elements that pops up the overlay and hides it when the overlay exit is clicked. Fixes #654.
This commit is contained in:
committed by
Tim Abbott
parent
2ea7d2341e
commit
87afe61860
@@ -368,6 +368,25 @@ $(function () {
|
|||||||
.text("Bringing you to your latest messages…"));
|
.text("Bringing you to your latest messages…"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
$("#main_div").on("click", ".message_inline_image a", function (e) {
|
||||||
|
var img = e.target,
|
||||||
|
row = rows.id($(img).closest(".message_row")),
|
||||||
|
user = current_msg_list.get(row).sender_full_name;
|
||||||
|
|
||||||
|
// prevent the link from opening in a new page.
|
||||||
|
e.preventDefault();
|
||||||
|
// prevent the message compose dialog from happening.
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
ui.lightbox_photo(img, user);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#overlay .exit").click(function (e) {
|
||||||
|
ui.exit_lightbox_photo();
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
// MAIN CLICK HANDLER
|
// MAIN CLICK HANDLER
|
||||||
|
|
||||||
$(document).on('click', function (e) {
|
$(document).on('click', function (e) {
|
||||||
|
|||||||
@@ -246,6 +246,10 @@ function process_hotkey(e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event_name === "escape" && $("#overlay").hasClass("show")) {
|
||||||
|
ui.exit_lightbox_photo();
|
||||||
|
}
|
||||||
|
|
||||||
// If we're on a button or a link and have pressed enter, let the
|
// If we're on a button or a link and have pressed enter, let the
|
||||||
// browser handle the keypress
|
// browser handle the keypress
|
||||||
//
|
//
|
||||||
@@ -361,7 +365,8 @@ function process_hotkey(e) {
|
|||||||
|
|
||||||
$(document).keydown(function (e) {
|
$(document).keydown(function (e) {
|
||||||
// Restrict to non-alphanumeric keys
|
// Restrict to non-alphanumeric keys
|
||||||
if (48 > e.which || 90 < e.which) {
|
// check if 27 (esc) because it doesn't register under .keypress()
|
||||||
|
if (48 > e.which || 90 < e.which || e.which === 27) {
|
||||||
if (process_hotkey(e)) {
|
if (process_hotkey(e)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,6 +281,29 @@ exports.small_avatar_url = function (message) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.lightbox_photo = function (image, user) {
|
||||||
|
// image should be an Image Object in JavaScript.
|
||||||
|
var url = $(image).attr("src"),
|
||||||
|
title = $(image).parent().attr("title");
|
||||||
|
|
||||||
|
$("#overlay .image-preview")
|
||||||
|
.css("background-image", "url(" + url + ")");
|
||||||
|
|
||||||
|
$("#overlay").addClass("show");
|
||||||
|
|
||||||
|
$(".right-sidebar, .column-middle-inner, .left-sidebar").addClass("visual-blur");
|
||||||
|
|
||||||
|
$(".title").text(title || "N/A");
|
||||||
|
$(".user").text(user);
|
||||||
|
|
||||||
|
$(".image-actions .open, .image-actions .download").attr("href", url);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.exit_lightbox_photo = function (image) {
|
||||||
|
$("#overlay").removeClass("show");
|
||||||
|
$(".right-sidebar, .column-middle-inner, .left-sidebar").removeClass("visual-blur");
|
||||||
|
};
|
||||||
|
|
||||||
var loading_more_messages_indicator_showing = false;
|
var loading_more_messages_indicator_showing = false;
|
||||||
exports.show_loading_more_messages_indicator = function () {
|
exports.show_loading_more_messages_indicator = function () {
|
||||||
if (! loading_more_messages_indicator_showing) {
|
if (! loading_more_messages_indicator_showing) {
|
||||||
|
|||||||
116
static/styles/overlay.css
Normal file
116
static/styles/overlay.css
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
background-color: rgba(255,255,255,0.4);
|
||||||
|
box-shadow: 0 0 20px rgba(0,0,0,0.2);
|
||||||
|
z-index: 101;
|
||||||
|
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay.show {
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-preview {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 80px);
|
||||||
|
|
||||||
|
background-color: #19203a;
|
||||||
|
box-shadow: 0 0 20px rgba(0,0,0,0.2);
|
||||||
|
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-preview .exit {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
|
||||||
|
color: rgba(255,255,255,0.8);
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 200;
|
||||||
|
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-preview:hover .exit {
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-description,
|
||||||
|
#overlay .image-actions {
|
||||||
|
float: left;
|
||||||
|
margin: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-actions {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-actions .icon {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-actions .icon .text {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-actions span:nth-of-type(2) {
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-actions .open span:nth-of-type(2) {
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-description {
|
||||||
|
/* approx width of screen minus action buttons on the side. */
|
||||||
|
width: calc(100% - 290px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-description .title {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: normal;
|
||||||
|
max-width: calc(100%);
|
||||||
|
|
||||||
|
/* Required for text-overflow */
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay .image-description .user {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-actions a.button {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button .download {
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
@@ -26,6 +26,12 @@ body,
|
|||||||
transition: background-color 200ms linear;
|
transition: background-color 200ms linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.visual-blur {
|
||||||
|
filter: blur(15px);
|
||||||
|
-moz-filter: blur(15px);
|
||||||
|
-webkit-filter: blur(15px);
|
||||||
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
button,
|
button,
|
||||||
select,
|
select,
|
||||||
|
|||||||
17
templates/zerver/image-overlay.html
Normal file
17
templates/zerver/image-overlay.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<div id="overlay">
|
||||||
|
<div class="image-preview">
|
||||||
|
<div class="exit">x</div>
|
||||||
|
</div>
|
||||||
|
<div class="image-description">
|
||||||
|
<div class="title"></div>
|
||||||
|
<div class="user"></div>
|
||||||
|
</div>
|
||||||
|
<div class="image-actions">
|
||||||
|
<a class="button sea-green small-flex open icon" target="_blank">
|
||||||
|
<span class="text">Open</span> <span class="icon-vector-external-link"></span>
|
||||||
|
</a>
|
||||||
|
<a class="button sea-green small-flex download icon" download>
|
||||||
|
<span class="text">Download</span> <span class="icon-vector-download"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -119,6 +119,7 @@ var page_params = {{ page_params }};
|
|||||||
<div class="column-right">
|
<div class="column-right">
|
||||||
{% include "zerver/right-sidebar.html" %}
|
{% include "zerver/right-sidebar.html" %}
|
||||||
</div><!--/right sidebar-->
|
</div><!--/right sidebar-->
|
||||||
|
{% include "zerver/image-overlay.html" %}
|
||||||
</div><!--/row-->
|
</div><!--/row-->
|
||||||
{% include "zerver/keyboard_shortcuts.html" %}
|
{% include "zerver/keyboard_shortcuts.html" %}
|
||||||
{% include "zerver/search_operators.html" %}
|
{% include "zerver/search_operators.html" %}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ GENERIC_KEYWORDS = [
|
|||||||
'error',
|
'error',
|
||||||
'expanded',
|
'expanded',
|
||||||
'hide',
|
'hide',
|
||||||
|
'show',
|
||||||
'notdisplayed',
|
'notdisplayed',
|
||||||
'popover',
|
'popover',
|
||||||
'success',
|
'success',
|
||||||
|
|||||||
@@ -650,6 +650,7 @@ PIPELINE = {
|
|||||||
'styles/zulip.css',
|
'styles/zulip.css',
|
||||||
'styles/media.css',
|
'styles/media.css',
|
||||||
'styles/settings.css',
|
'styles/settings.css',
|
||||||
|
'styles/overlay.css',
|
||||||
'styles/pygments.css',
|
'styles/pygments.css',
|
||||||
'styles/thirdparty-fonts.css',
|
'styles/thirdparty-fonts.css',
|
||||||
# We don't want fonts.css on QtWebKit, so its omitted here
|
# We don't want fonts.css on QtWebKit, so its omitted here
|
||||||
@@ -665,6 +666,7 @@ PIPELINE = {
|
|||||||
'styles/zulip.css',
|
'styles/zulip.css',
|
||||||
'styles/media.css',
|
'styles/media.css',
|
||||||
'styles/settings.css',
|
'styles/settings.css',
|
||||||
|
'styles/overlay.css',
|
||||||
'styles/pygments.css',
|
'styles/pygments.css',
|
||||||
'styles/thirdparty-fonts.css',
|
'styles/thirdparty-fonts.css',
|
||||||
'styles/fonts.css',
|
'styles/fonts.css',
|
||||||
|
|||||||
Reference in New Issue
Block a user