mirror of
https://github.com/zulip/zulip.git
synced 2025-11-15 11:22:04 +00:00
Add notification for muting with unmute option.
This adds a support a notification at the top of the screen that alerts a user they’ve muted a stream and gives them the option to unmute if it was an accident. The notification disappears automatically after 4s, but if a user moves their mouse over the notification, the timer resets to 2s after the user moves their mouse off the notification, to make it easy for users to read the full message and decide what to do.
This commit is contained in:
committed by
Tim Abbott
parent
3a4fff837f
commit
c833265fae
@@ -16,6 +16,76 @@ exports.rerender = function () {
|
||||
}
|
||||
};
|
||||
|
||||
exports.notify_with_undo_option = (function () {
|
||||
var event_added = false;
|
||||
var meta = {
|
||||
stream: null,
|
||||
topic: null,
|
||||
hide_me_time: null,
|
||||
alert_hover_state: false,
|
||||
$mute: null
|
||||
};
|
||||
var animate = {
|
||||
fadeOut: function ($mute) {
|
||||
if (meta.$mute) {
|
||||
meta.$mute.fadeOut(500).removeClass("show");
|
||||
}
|
||||
},
|
||||
fadeIn: function ($mute) {
|
||||
if (meta.$mute) {
|
||||
meta.$mute.fadeIn(500).addClass("show");
|
||||
}
|
||||
}
|
||||
};
|
||||
var interval = setInterval(function () {
|
||||
if (meta.hide_me_time < new Date().getTime() && !meta.alert_hover_state) {
|
||||
animate.fadeOut();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
return function (stream, topic) {
|
||||
var $exit = $("#unmute_muted_topic_notification .exit-me");
|
||||
|
||||
if (!meta.$mute) {
|
||||
meta.$mute = $("#unmute_muted_topic_notification");
|
||||
|
||||
$exit.click(function () {
|
||||
animate.fadeOut();
|
||||
});
|
||||
|
||||
meta.$mute.find("#unmute").click(function () {
|
||||
// it should reference the meta variable and not get stuck with
|
||||
// a pass-by-value of stream, topic.
|
||||
popovers.topic_ops.unmute(meta.stream, meta.topic);
|
||||
animate.fadeOut();
|
||||
});
|
||||
}
|
||||
|
||||
meta.stream = stream;
|
||||
meta.topic = topic;
|
||||
// add a four second delay before closing up.
|
||||
meta.hide_me_time = new Date().getTime() + 4000;
|
||||
|
||||
meta.$mute.find(".topic").html(topic);
|
||||
meta.$mute.find(".stream").html(stream);
|
||||
|
||||
animate.fadeIn();
|
||||
|
||||
// if the user mouses over the notification, don't hide it.
|
||||
meta.$mute.mouseenter(function () {
|
||||
meta.alert_hover_state = true;
|
||||
});
|
||||
|
||||
// once the user's mouse leaves the notification, restart the countdown.
|
||||
meta.$mute.mouseleave(function () {
|
||||
meta.alert_hover_state = false;
|
||||
// add at least 2000ms but if more than that exists just keep the
|
||||
// current amount.
|
||||
meta.hide_me_time = Math.max(meta.hide_me_time, new Date().getTime() + 2000);
|
||||
});
|
||||
};
|
||||
}());
|
||||
|
||||
exports.persist_and_rerender = function () {
|
||||
// Optimistically rerender our new muting preferences. The back
|
||||
// end should eventually save it, and if it doesn't, it's a recoverable
|
||||
|
||||
@@ -136,6 +136,23 @@ exports.hide_actions_popover = function () {
|
||||
}
|
||||
};
|
||||
|
||||
exports.topic_ops = {
|
||||
mute: function (stream, topic) {
|
||||
popovers.hide_topic_sidebar_popover();
|
||||
muting.mute_topic(stream, topic);
|
||||
muting_ui.persist_and_rerender();
|
||||
muting_ui.notify_with_undo_option(stream, topic);
|
||||
},
|
||||
// we don't run a unmute_notif function because it isn't an issue as much
|
||||
// if someone accidentally unmutes a stream rather than if they mute it
|
||||
// and miss out on info.
|
||||
unmute: function (stream, topic) {
|
||||
popovers.hide_topic_sidebar_popover();
|
||||
muting.unmute_topic(stream, topic);
|
||||
muting_ui.persist_and_rerender();
|
||||
}
|
||||
};
|
||||
|
||||
function message_info_popped() {
|
||||
return current_message_info_popover_elem !== undefined;
|
||||
}
|
||||
@@ -364,9 +381,7 @@ exports.register_click_handlers = function () {
|
||||
$('body').on('click', '.sidebar-popover-mute-topic', function (e) {
|
||||
var stream = $(e.currentTarget).attr('data-stream-name');
|
||||
var topic = $(e.currentTarget).attr('data-topic-name');
|
||||
popovers.hide_topic_sidebar_popover();
|
||||
muting.mute_topic(stream, topic);
|
||||
muting_ui.persist_and_rerender();
|
||||
exports.topic_ops.mute(stream, topic);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
@@ -374,9 +389,7 @@ exports.register_click_handlers = function () {
|
||||
$('body').on('click', '.sidebar-popover-unmute-topic', function (e) {
|
||||
var stream = $(e.currentTarget).attr('data-stream-name');
|
||||
var topic = $(e.currentTarget).attr('data-topic-name');
|
||||
popovers.hide_topic_sidebar_popover();
|
||||
muting.unmute_topic(stream, topic);
|
||||
muting_ui.persist_and_rerender();
|
||||
exports.topic_ops.unmute(stream, topic);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
@@ -514,9 +527,7 @@ exports.register_click_handlers = function () {
|
||||
$('body').on('click', '.popover_mute_topic', function (e) {
|
||||
var stream = $(e.currentTarget).data('msg-stream');
|
||||
var topic = $(e.currentTarget).data('msg-topic');
|
||||
popovers.hide_actions_popover();
|
||||
muting.mute_topic(stream, topic);
|
||||
muting_ui.persist_and_rerender();
|
||||
exports.topic_ops.mute(stream, topic);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
@@ -42,6 +42,99 @@ a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p.n-margin {
|
||||
margin: 10px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.small-line-height {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.float-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.float-clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.light {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.border-radius {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#unmute_muted_topic_notification {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
top: 0px;
|
||||
left: calc(50vw - 220px);
|
||||
padding: 15px;
|
||||
|
||||
background-color: #FAFAFA;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 0px 30px rgba(0,0,0,0.25);
|
||||
z-index: 101;
|
||||
|
||||
animation-name: pulse;
|
||||
animation-iteration-count: infinite;
|
||||
animation-duration: 2s;
|
||||
|
||||
transition-property: top, bottom;
|
||||
transition-duration: 0.5s;
|
||||
}
|
||||
|
||||
#unmute_muted_topic_notification.show {
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
#unmute_muted_topic_notification h3 {
|
||||
font-size: 16pt;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0px 0px 30px rgba(0,0,0,0.35);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0px 0px 30px rgba(0,0,0,0.15);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0px 0px 30px rgba(0,0,0,0.35);
|
||||
}
|
||||
}
|
||||
|
||||
#unmute_muted_topic_notification .btn {
|
||||
background-color: transparent;
|
||||
border: 1px solid #444;
|
||||
outline: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
#unmute_muted_topic_notification .btn:hover {
|
||||
background-color: #444;
|
||||
color: #FAFAFA;
|
||||
}
|
||||
|
||||
#unmute_muted_topic_notification .exit-me {
|
||||
font-size: 30pt;
|
||||
font-weight: 200;
|
||||
margin: 5px 0px 0px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ztable_comp_col1 {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ var page_params = {{ page_params }};
|
||||
{{ minified_js('app_debug')|safe }}
|
||||
{% endif %}
|
||||
|
||||
{% include "zerver/topic_is_muted.html" %}
|
||||
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div id="css-loading">
|
||||
|
||||
9
templates/zerver/topic_is_muted.html
Normal file
9
templates/zerver/topic_is_muted.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<div id="unmute_muted_topic_notification">
|
||||
<div class="float-header">
|
||||
<h3 class="light no-margin small-line-height float-left">Topic Muted</h3>
|
||||
<div class="exit-me float-right">×</div>
|
||||
<button class="btn border-radius float-right" id="unmute" type="button" name="button">Unmute</button>
|
||||
<div class="float-clear"></div>
|
||||
</div>
|
||||
<p class="n-margin">You have muted the topic <span class="topic"></span> under the <span class="stream"></span> stream.</p>
|
||||
</div>
|
||||
Reference in New Issue
Block a user