mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	* Show an empty overlay of recent topics. * Register click event to open recent topics. * Launch recent topics on "t" keypress. This is based on the draft overlay.
		
			
				
	
	
		
			246 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| let active_overlay;
 | |
| let close_handler;
 | |
| let open_overlay_name;
 | |
| 
 | |
| function reset_state() {
 | |
|     active_overlay = undefined;
 | |
|     close_handler = undefined;
 | |
|     open_overlay_name = undefined;
 | |
| }
 | |
| 
 | |
| exports.is_active = function () {
 | |
|     return !!open_overlay_name;
 | |
| };
 | |
| 
 | |
| exports.is_modal_open = function () {
 | |
|     return $(".modal").hasClass("in");
 | |
| };
 | |
| 
 | |
| exports.info_overlay_open = function () {
 | |
|     return open_overlay_name === 'informationalOverlays';
 | |
| };
 | |
| 
 | |
| exports.settings_open = function () {
 | |
|     return open_overlay_name === 'settings';
 | |
| };
 | |
| 
 | |
| exports.streams_open = function () {
 | |
|     return open_overlay_name === 'subscriptions';
 | |
| };
 | |
| 
 | |
| exports.lightbox_open = function () {
 | |
|     return open_overlay_name === 'lightbox';
 | |
| };
 | |
| 
 | |
| exports.drafts_open = function () {
 | |
|     return open_overlay_name === 'drafts';
 | |
| };
 | |
| 
 | |
| exports.recent_topics_open = function () {
 | |
|     return open_overlay_name === 'recent_topics';
 | |
| };
 | |
| 
 | |
| // To address bugs where mouse might apply to the streams/settings
 | |
| // overlays underneath an open modal within those settings UI, we add
 | |
| // this inline style to '.overlay.show', overriding the
 | |
| // "pointer-events: all" style in app_components.scss.
 | |
| //
 | |
| // This is kinda hacky; it only works for modals within overlays, and
 | |
| // we need to make sure it gets re-enabled when the modal closes.
 | |
| exports.disable_background_mouse_events = function () {
 | |
|     $('.overlay.show').attr("style", "pointer-events: none");
 | |
| };
 | |
| 
 | |
| // This removes only the inline-style of the element that
 | |
| // was added in disable_background_mouse_events and
 | |
| // enables the background mouse events.
 | |
| exports.enable_background_mouse_events = function () {
 | |
|     $('.overlay.show').attr("style", null);
 | |
| };
 | |
| 
 | |
| exports.active_modal = function () {
 | |
|     if (!exports.is_modal_open()) {
 | |
|         blueslip.error("Programming error — Called active_modal when there is no modal open");
 | |
|         return;
 | |
|     }
 | |
|     return '#' + $(".modal.in").attr("id");
 | |
| };
 | |
| 
 | |
| exports.open_overlay = function (opts) {
 | |
|     popovers.hide_all();
 | |
| 
 | |
|     if (!opts.name || !opts.overlay || !opts.on_close) {
 | |
|         blueslip.error('Programming error in open_overlay');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (active_overlay || open_overlay_name || close_handler) {
 | |
|         blueslip.error('Programming error — trying to open ' + opts.name +
 | |
|             ' before closing ' + open_overlay_name);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     blueslip.debug('open overlay: ' + opts.name);
 | |
| 
 | |
|     // Our overlays are kind of crufty...we have an HTML id
 | |
|     // attribute for them and then a data-overlay attribute for
 | |
|     // them.  Make sure they match.
 | |
|     if (opts.overlay.attr('data-overlay') !== opts.name) {
 | |
|         blueslip.error('Bad overlay setup for ' + opts.name);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     open_overlay_name = opts.name;
 | |
|     active_overlay = opts.overlay;
 | |
|     opts.overlay.addClass('show');
 | |
| 
 | |
|     opts.overlay.attr("aria-hidden", "false");
 | |
|     $('.app').attr("aria-hidden", "true");
 | |
|     $('.fixed-app').attr("aria-hidden", "true");
 | |
|     $('.header').attr("aria-hidden", "true");
 | |
| 
 | |
|     close_handler = function () {
 | |
|         opts.on_close();
 | |
|         reset_state();
 | |
|     };
 | |
| };
 | |
| 
 | |
| exports.open_modal = function (selector) {
 | |
|     if (selector === undefined) {
 | |
|         blueslip.error('Undefined selector was passed into open_modal');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (selector[0] !== '#') {
 | |
|         blueslip.error('Non-id-based selector passed in to open_modal: ' + selector);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (exports.is_modal_open()) {
 | |
|         blueslip.error('open_modal() was called while ' + exports.active_modal() +
 | |
|             ' modal was open.');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     blueslip.debug('open modal: ' + selector);
 | |
| 
 | |
|     const elem = $(selector).expectOne();
 | |
|     elem.modal("show").attr("aria-hidden", false);
 | |
|     // Disable background mouse events when modal is active
 | |
|     exports.disable_background_mouse_events();
 | |
|     // Remove previous alert messages from modal, if exists.
 | |
|     elem.find(".alert").hide();
 | |
|     elem.find(".alert-notification").html("");
 | |
| };
 | |
| 
 | |
| exports.close_overlay = function (name) {
 | |
|     if (name !== open_overlay_name) {
 | |
|         blueslip.error("Trying to close " + name + " when " + open_overlay_name + " is open.");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (name === undefined) {
 | |
|         blueslip.error('Undefined name was passed into close_overlay');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     blueslip.debug('close overlay: ' + name);
 | |
| 
 | |
|     active_overlay.removeClass("show");
 | |
| 
 | |
|     active_overlay.attr("aria-hidden", "true");
 | |
|     $('.app').attr("aria-hidden", "false");
 | |
|     $('.fixed-app').attr("aria-hidden", "false");
 | |
|     $('.header').attr("aria-hidden", "false");
 | |
| 
 | |
|     if (!close_handler) {
 | |
|         blueslip.error("Overlay close handler for " + name + " not properly setup.");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     close_handler();
 | |
| };
 | |
| 
 | |
| exports.close_active = function () {
 | |
|     if (!open_overlay_name) {
 | |
|         blueslip.warn('close_active() called without checking is_active()');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     exports.close_overlay(open_overlay_name);
 | |
| };
 | |
| 
 | |
| exports.close_modal = function (selector) {
 | |
|     if (selector === undefined) {
 | |
|         blueslip.error('Undefined selector was passed into close_modal');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (!exports.is_modal_open()) {
 | |
|         blueslip.warn('close_active_modal() called without checking is_modal_open()');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (exports.active_modal() !== selector) {
 | |
|         blueslip.error("Trying to close " + selector +
 | |
|             " modal when " + exports.active_modal() + " is open.");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     blueslip.debug('close modal: ' + selector);
 | |
| 
 | |
|     const elem = $(selector).expectOne();
 | |
|     elem.modal("hide").attr("aria-hidden", true);
 | |
|     // Enable mouse events for the background as the modal closes.
 | |
|     exports.enable_background_mouse_events();
 | |
| 
 | |
| };
 | |
| 
 | |
| exports.close_active_modal = function () {
 | |
|     if (!exports.is_modal_open()) {
 | |
|         blueslip.warn('close_active_modal() called without checking is_modal_open()');
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     $(".modal.in").modal("hide").attr("aria-hidden", true);
 | |
| };
 | |
| 
 | |
| exports.close_for_hash_change = function () {
 | |
|     $(".overlay.show").removeClass("show");
 | |
|     reset_state();
 | |
| };
 | |
| 
 | |
| exports.open_settings = function () {
 | |
|     exports.open_overlay({
 | |
|         name: 'settings',
 | |
|         overlay: $("#settings_overlay_container"),
 | |
|         on_close: function () {
 | |
|             hashchange.exit_overlay();
 | |
|         },
 | |
|     });
 | |
| };
 | |
| 
 | |
| exports.initialize = function () {
 | |
|     $("body").on("click", ".overlay, .overlay .exit", function (e) {
 | |
|         let $target = $(e.target);
 | |
| 
 | |
|         // if the target is not the .overlay element, search up the node tree
 | |
|         // until it is found.
 | |
|         if ($target.is(".exit, .exit-sign, .overlay-content, .exit span")) {
 | |
|             $target = $target.closest("[data-overlay]");
 | |
|         } else if (!$target.is(".overlay")) {
 | |
|             // not a valid click target then.
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         const target_name = $target.attr("data-overlay");
 | |
| 
 | |
|         exports.close_overlay(target_name);
 | |
| 
 | |
|         e.preventDefault();
 | |
|         e.stopPropagation();
 | |
|     });
 | |
| };
 | |
| 
 | |
| window.overlays = exports;
 |