mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			219 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import {addDays} from "date-fns";
 | |
| import $ from "jquery";
 | |
| 
 | |
| import render_bankruptcy_alert_content from "../templates/navbar_alerts/bankruptcy.hbs";
 | |
| import render_configure_email_alert_content from "../templates/navbar_alerts/configure_outgoing_email.hbs";
 | |
| import render_desktop_notifications_alert_content from "../templates/navbar_alerts/desktop_notifications.hbs";
 | |
| import render_insecure_desktop_app_alert_content from "../templates/navbar_alerts/insecure_desktop_app.hbs";
 | |
| import render_navbar_alert_wrapper from "../templates/navbar_alerts/navbar_alert_wrapper.hbs";
 | |
| import render_profile_incomplete_alert_content from "../templates/navbar_alerts/profile_incomplete.hbs";
 | |
| import render_server_needs_upgrade_alert_content from "../templates/navbar_alerts/server_needs_upgrade.hbs";
 | |
| 
 | |
| import {localstorage} from "./localstorage";
 | |
| import * as notifications from "./notifications";
 | |
| import {page_params} from "./page_params";
 | |
| import * as unread_ops from "./unread_ops";
 | |
| import * as unread_ui from "./unread_ui";
 | |
| import * as util from "./util";
 | |
| 
 | |
| /* This is called by resize.js, and thus indirectly when we trigger
 | |
|  * resize events in the logic below. */
 | |
| export function resize_app() {
 | |
|     const navbar_alerts_wrapper_height = $("#navbar_alerts_wrapper").height();
 | |
|     $("body > .app").height("calc(100% - " + navbar_alerts_wrapper_height + "px)");
 | |
| 
 | |
|     // the floating recipient bar is usually positioned right below
 | |
|     // the `.header` element (including padding).
 | |
|     const frb_top =
 | |
|         navbar_alerts_wrapper_height +
 | |
|         $(".header").height() +
 | |
|         Number.parseInt($(".header").css("paddingBottom"), 10);
 | |
|     $("#floating_recipient_bar").css("top", frb_top + "px");
 | |
| }
 | |
| 
 | |
| const show_step = function ($process, step) {
 | |
|     $process
 | |
|         .find("[data-step]")
 | |
|         .hide()
 | |
|         .filter("[data-step=" + step + "]")
 | |
|         .show();
 | |
| };
 | |
| 
 | |
| const get_step = function ($process) {
 | |
|     return $process.find("[data-step]:visible").data("step");
 | |
| };
 | |
| 
 | |
| export function should_show_notifications(ls) {
 | |
|     // if the user said to never show banner on this computer again, it will
 | |
|     // be stored as `true` so we want to negate that.
 | |
|     if (localstorage.supported() && ls.get("dontAskForNotifications") === true) {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     return (
 | |
|         // Spectators cannot receive desktop notifications, so never
 | |
|         // request permissions to send them.
 | |
|         !page_params.is_spectator &&
 | |
|         // notifications *basically* don't work on any mobile platforms, so don't
 | |
|         // event show the banners. This prevents trying to access things that
 | |
|         // don't exist like `Notification.permission`.
 | |
|         !util.is_mobile() &&
 | |
|         // if permission has not been granted yet.
 | |
|         !notifications.granted_desktop_notifications_permission() &&
 | |
|         // if permission is allowed to be requested (e.g. not in "denied" state).
 | |
|         notifications.permission_state() !== "denied"
 | |
|     );
 | |
| }
 | |
| 
 | |
| export function should_show_server_upgrade_notification(ls) {
 | |
|     // We do not show the server upgrade nag for a week after the user
 | |
|     // clicked "dismiss".
 | |
|     if (!localstorage.supported() || ls.get("lastUpgradeNagDismissalTime") === undefined) {
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     const last_notification_dismissal_time = ls.get("lastUpgradeNagDismissalTime");
 | |
| 
 | |
|     const upgrade_nag_dismissal_duration = addDays(new Date(last_notification_dismissal_time), 7);
 | |
| 
 | |
|     // show the notification only if the time duration is completed.
 | |
|     return Date.now() > upgrade_nag_dismissal_duration;
 | |
| }
 | |
| 
 | |
| export function dismiss_upgrade_nag(ls) {
 | |
|     $(".alert[data-process='server-needs-upgrade'").hide();
 | |
|     if (localstorage.supported()) {
 | |
|         ls.set("lastUpgradeNagDismissalTime", Date.now());
 | |
|     }
 | |
| }
 | |
| 
 | |
| export function check_profile_incomplete() {
 | |
|     if (!page_params.is_admin) {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     // Eventually, we might also check page_params.realm_icon_source,
 | |
|     // but it feels too aggressive to ask users to do change that
 | |
|     // since their organization might not have a logo yet.
 | |
|     if (
 | |
|         page_params.realm_description === "" ||
 | |
|         /^Organization imported from [A-Za-z]+[!.]$/.test(page_params.realm_description)
 | |
|     ) {
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| export function show_profile_incomplete(is_profile_incomplete) {
 | |
|     if (is_profile_incomplete) {
 | |
|         // Note that this will be a noop unless we'd already displayed
 | |
|         // the notice in this session.  This seems OK, given that
 | |
|         // this is meant to be a one-time task for administrators.
 | |
|         $("[data-process='profile-incomplete']").show();
 | |
|     } else {
 | |
|         $("[data-process='profile-incomplete']").hide();
 | |
|     }
 | |
| }
 | |
| 
 | |
| export function initialize() {
 | |
|     const ls = localstorage();
 | |
|     if (page_params.insecure_desktop_app) {
 | |
|         open({
 | |
|             data_process: "insecure-desktop-app",
 | |
|             custom_class: "red",
 | |
|             rendered_alert_content_html: render_insecure_desktop_app_alert_content(),
 | |
|         });
 | |
|     } else if (page_params.server_needs_upgrade) {
 | |
|         if (should_show_server_upgrade_notification(ls)) {
 | |
|             open({
 | |
|                 data_process: "server-needs-upgrade",
 | |
|                 custom_class: "red",
 | |
|                 rendered_alert_content_html: render_server_needs_upgrade_alert_content(),
 | |
|             });
 | |
|         }
 | |
|     } else if (page_params.warn_no_email === true && page_params.is_admin) {
 | |
|         // if email has not been set up and the user is the admin,
 | |
|         // display a warning to tell them to set up an email server.
 | |
|         open({
 | |
|             data_process: "email-server",
 | |
|             custom_class: "red",
 | |
|             rendered_alert_content_html: render_configure_email_alert_content(),
 | |
|         });
 | |
|     } else if (should_show_notifications(ls)) {
 | |
|         open({
 | |
|             data_process: "notifications",
 | |
|             rendered_alert_content_html: render_desktop_notifications_alert_content(),
 | |
|         });
 | |
|     } else if (unread_ui.should_display_bankruptcy_banner()) {
 | |
|         const unread_msgs_count = page_params.unread_msgs.count;
 | |
|         open({
 | |
|             data_process: "bankruptcy",
 | |
|             custom_class: "bankruptcy",
 | |
|             rendered_alert_content_html: render_bankruptcy_alert_content({unread_msgs_count}),
 | |
|         });
 | |
|     } else if (check_profile_incomplete()) {
 | |
|         open({
 | |
|             data_process: "profile-incomplete",
 | |
|             rendered_alert_content_html: render_profile_incomplete_alert_content(),
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     // Configure click handlers.
 | |
|     $(".request-desktop-notifications").on("click", function (e) {
 | |
|         e.preventDefault();
 | |
|         $(this).closest(".alert").hide();
 | |
|         notifications.request_desktop_notifications_permission();
 | |
|         $(window).trigger("resize");
 | |
|     });
 | |
| 
 | |
|     $(".reject-notifications").on("click", function () {
 | |
|         $(this).closest(".alert").hide();
 | |
|         ls.set("dontAskForNotifications", true);
 | |
|         $(window).trigger("resize");
 | |
|     });
 | |
| 
 | |
|     $(".accept-bankruptcy").on("click", function (e) {
 | |
|         e.preventDefault();
 | |
|         const $process = $(this).closest("[data-process]");
 | |
|         show_step($process, 2);
 | |
|         setTimeout(unread_ops.mark_all_as_read, 1000);
 | |
|         $(window).trigger("resize");
 | |
|     });
 | |
| 
 | |
|     $(".dismiss-upgrade-nag").on("click", (e) => {
 | |
|         e.preventDefault();
 | |
|         e.stopPropagation();
 | |
|         dismiss_upgrade_nag(ls);
 | |
|     });
 | |
| 
 | |
|     $("#navbar_alerts_wrapper").on("click", ".alert .close, .alert .exit", function (e) {
 | |
|         e.stopPropagation();
 | |
|         const $process = $(e.target).closest("[data-process]");
 | |
|         if (get_step($process) === 1 && $process.data("process") === "notifications") {
 | |
|             show_step($process, 2);
 | |
|         } else {
 | |
|             $(this).closest(".alert").hide();
 | |
|         }
 | |
|         $(window).trigger("resize");
 | |
|     });
 | |
| 
 | |
|     // Treat Enter with links in the navbar alerts UI focused like a click.,
 | |
|     $("#navbar_alerts_wrapper").on("keyup", ".alert-link[role=button]", function (e) {
 | |
|         e.stopPropagation();
 | |
|         if (e.key === "Enter") {
 | |
|             $(this).trigger("click");
 | |
|         }
 | |
|     });
 | |
| }
 | |
| 
 | |
| export function open(args) {
 | |
|     const rendered_alert_wrapper_html = render_navbar_alert_wrapper(args);
 | |
| 
 | |
|     // Note: We only support one alert being rendered at a time; as a
 | |
|     // result, we just replace the alert area in the DOM with the
 | |
|     // indicated alert. We do this to avoid bad UX, as it'd look weird
 | |
|     // to have more than one alert visible at a time.
 | |
|     $("#navbar_alerts_wrapper").html(rendered_alert_wrapper_html);
 | |
|     $(window).trigger("resize");
 | |
| }
 |