mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			139 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import $ from "jquery";
 | 
						|
 | 
						|
import render_feedback_container from "../templates/feedback_container.hbs";
 | 
						|
 | 
						|
/*
 | 
						|
 | 
						|
This code lets you show something like this:
 | 
						|
 | 
						|
    +-----
 | 
						|
    | TOPIC MUTES [undo] [x]
 | 
						|
    |
 | 
						|
    | You muted stream Foo, topic Bar.
 | 
						|
    +-----
 | 
						|
 | 
						|
And then you configure the undo behavior, and
 | 
						|
everything else is controlled by the widget.
 | 
						|
 | 
						|
Codewise it's a singleton widget that controls the DOM inside
 | 
						|
#feedback_container, which gets served up by server.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
const meta = {
 | 
						|
    hide_me_time: null,
 | 
						|
    alert_hover_state: false,
 | 
						|
    $container: null,
 | 
						|
    opened: false,
 | 
						|
};
 | 
						|
 | 
						|
const animate = {
 | 
						|
    maybe_close() {
 | 
						|
        if (!meta.opened) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        if (meta.hide_me_time < Date.now() && !meta.alert_hover_state) {
 | 
						|
            animate.fadeOut();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        setTimeout(animate.maybe_close, 100);
 | 
						|
    },
 | 
						|
    fadeOut() {
 | 
						|
        if (!meta.opened) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        if (meta.$container) {
 | 
						|
            meta.$container.fadeOut(500).removeClass("show");
 | 
						|
            meta.opened = false;
 | 
						|
            meta.alert_hover_state = false;
 | 
						|
        }
 | 
						|
    },
 | 
						|
    fadeIn() {
 | 
						|
        if (meta.opened) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        if (meta.$container) {
 | 
						|
            meta.$container.fadeIn(500).addClass("show");
 | 
						|
            meta.opened = true;
 | 
						|
            setTimeout(animate.maybe_close, 100);
 | 
						|
        }
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
function set_up_handlers() {
 | 
						|
    if (meta.handlers_set) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    meta.handlers_set = true;
 | 
						|
 | 
						|
    // if the user mouses over the notification, don't hide it.
 | 
						|
    meta.$container.on("mouseenter", () => {
 | 
						|
        if (!meta.opened) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        meta.alert_hover_state = true;
 | 
						|
    });
 | 
						|
 | 
						|
    // once the user's mouse leaves the notification, restart the countdown.
 | 
						|
    meta.$container.on("mouseleave", () => {
 | 
						|
        if (!meta.opened) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        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, Date.now() + 2000);
 | 
						|
    });
 | 
						|
 | 
						|
    meta.$container.on("click", ".exit-me", () => {
 | 
						|
        animate.fadeOut();
 | 
						|
    });
 | 
						|
 | 
						|
    meta.$container.on("click", ".feedback_undo", () => {
 | 
						|
        if (meta.undo) {
 | 
						|
            meta.undo();
 | 
						|
        }
 | 
						|
        animate.fadeOut();
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
export function is_open() {
 | 
						|
    return meta.opened;
 | 
						|
}
 | 
						|
 | 
						|
export function dismiss() {
 | 
						|
    animate.fadeOut();
 | 
						|
}
 | 
						|
 | 
						|
export function show(opts) {
 | 
						|
    if (!opts.populate) {
 | 
						|
        blueslip.error("programmer needs to supply populate callback.");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    meta.$container = $("#feedback_container");
 | 
						|
 | 
						|
    const html = render_feedback_container();
 | 
						|
    meta.$container.html(html);
 | 
						|
 | 
						|
    set_up_handlers();
 | 
						|
 | 
						|
    meta.undo = opts.on_undo;
 | 
						|
 | 
						|
    // add a four second delay before closing up.
 | 
						|
    meta.hide_me_time = Date.now() + 4000;
 | 
						|
 | 
						|
    meta.$container.find(".feedback_title").text(opts.title_text);
 | 
						|
    meta.$container.find(".feedback_undo").text(opts.undo_button_text);
 | 
						|
    opts.populate(meta.$container.find(".feedback_content"));
 | 
						|
 | 
						|
    animate.fadeIn();
 | 
						|
}
 |