diff --git a/static/js/muting_ui.js b/static/js/muting_ui.js index 9975eeb039..276e904849 100644 --- a/static/js/muting_ui.js +++ b/static/js/muting_ui.js @@ -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 diff --git a/static/js/popovers.js b/static/js/popovers.js index 9fe96c8e47..64e5529775 100644 --- a/static/js/popovers.js +++ b/static/js/popovers.js @@ -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(); }); diff --git a/static/styles/zulip.css b/static/styles/zulip.css index 99d43275ef..3605702fee 100644 --- a/static/styles/zulip.css +++ b/static/styles/zulip.css @@ -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; } diff --git a/templates/zerver/index.html b/templates/zerver/index.html index c8ffb0afbc..2ae4e6b936 100644 --- a/templates/zerver/index.html +++ b/templates/zerver/index.html @@ -44,6 +44,8 @@ var page_params = {{ page_params }}; {{ minified_js('app_debug')|safe }} {% endif %} +{% include "zerver/topic_is_muted.html" %} + {% endblock %} {% block content %}
You have muted the topic under the stream.
+