zulip/web/src/gear_menu.js

212 lines
6.7 KiB
JavaScript
Raw Normal View History

import $ from "jquery";
2023-10-13 12:51:35 +02:00
import WinChan from "winchan";
2023-10-13 12:51:35 +02:00
import render_gear_menu_popover from "../templates/gear_menu_popover.hbs";
2023-10-13 12:51:35 +02:00
import * as blueslip from "./blueslip";
import * as channel from "./channel";
import * as dark_theme from "./dark_theme";
import * as message_lists from "./message_lists";
import * as popover_menus from "./popover_menus";
import * as popover_menus_data from "./popover_menus_data";
2023-10-13 12:51:35 +02:00
import * as popovers from "./popovers";
import * as settings_preferences from "./settings_preferences";
2023-10-13 12:51:35 +02:00
import {parse_html} from "./ui_util";
2018-08-29 19:50:12 +02:00
/*
For various historical reasons there isn't one
single chunk of code that really makes our gear
menu function. In this comment I try to help
you know where to look for relevant code.
The module that you're reading now doesn't
actually do much of the work.
2018-08-29 19:50:12 +02:00
Our gear menu has these choices:
=================
hash: Stream settings
2018-08-29 19:50:12 +02:00
hash: Settings
hash: Organization settings
link: Usage statistics
2018-08-29 19:50:12 +02:00
---
link: Help center
info: Keyboard shortcuts
info: Message formatting
info: Search filters
hash: About Zulip
2018-08-29 19:50:12 +02:00
---
link: Desktop & mobile apps
link: Integrations
link: API documentation
link: Sponsor Zulip
link: Plans and pricing
2018-08-29 19:50:12 +02:00
---
hash: Invite users
---
misc: Logout
=================
Depending on settings, there may also be choices
like "Feedback" or "Debug".
The menu items get built in a handlebars template
called gear_menu_popover.hbs.
2018-08-29 19:50:12 +02:00
The menu itself has the selector
"settings-dropdown".
The items with the prefix of "hash:" are in-page
links:
#streams
#settings
#organization
#about-zulip
2018-08-29 19:50:12 +02:00
#invite
When you click on the links there is a function
called hashchanged() in web/src/hashchange.js
that gets invoked. (We register this as a listener
for the hashchange event.) This function then
2018-08-29 19:50:12 +02:00
launches the appropriate modal for each menu item.
Look for things like subs.launch(...) or
invite.launch() in that code.
Some items above are prefixed with "link:". Those
items, when clicked, just use the normal browser
mechanism to link to external pages, and they
have a target of "_blank".
The "info:" items use our info overlay system
in web/src/info_overlay.js. They are dispatched
using a click handler in web/src/click_handlers.js.
2018-08-29 19:50:12 +02:00
The click handler uses "[data-overlay-trigger]" as
the selector and then calls browser_history.go_to_location.
2018-08-29 19:50:12 +02:00
*/
2023-10-13 12:51:35 +02:00
function render(instance) {
const rendered_gear_menu = render_gear_menu_popover(
popover_menus_data.get_gear_menu_content_context(),
);
instance.setContent(parse_html(rendered_gear_menu));
}
2023-10-13 12:51:35 +02:00
export function initialize() {
popover_menus.register_popover_menu("#gear-menu", {
theme: "navbar-dropdown-menu",
2023-10-13 12:51:35 +02:00
placement: "bottom",
offset: [-50, 0],
popperOptions: {
strategy: "fixed",
modifiers: [
{
name: "eventListeners",
options: {
scroll: false,
},
},
],
},
onMount(instance) {
const $popper = $(instance.popper);
popover_menus.popover_instances.gear_menu = instance;
$popper.on("click", ".webathena_login", (e) => {
$("#zephyr-mirror-error").removeClass("show");
const principal = ["zephyr", "zephyr"];
WinChan.open(
{
url: "https://webathena.mit.edu/#!request_ticket_v1",
relay_url: "https://webathena.mit.edu/relay.html",
params: {
realm: "ATHENA.MIT.EDU",
principal,
},
},
(err, r) => {
if (err) {
blueslip.warn(err);
return;
}
if (r.status !== "OK") {
blueslip.warn(r);
return;
}
channel.post({
url: "/accounts/webathena_kerberos_login/",
data: {cred: JSON.stringify(r.session)},
success() {
$("#zephyr-mirror-error").removeClass("show");
},
error() {
$("#zephyr-mirror-error").addClass("show");
},
});
},
);
instance.hide();
e.preventDefault();
e.stopPropagation();
});
$popper.on("click", ".change-language-spectator", (e) => {
instance.hide();
e.preventDefault();
e.stopPropagation();
settings_preferences.launch_default_language_setting_modal();
2023-10-13 12:51:35 +02:00
});
// We cannot update recipient bar color using dark_theme.enable/disable due to
// it being called before message lists are initialized and the order cannot be changed.
// Also, since these buttons are only visible for spectators which doesn't have events,
// if theme is changed in a different tab, the theme of this tab remains the same.
$popper.on("click", "#gear-menu-dropdown .gear-menu-select-dark-theme", (e) => {
2023-10-13 12:51:35 +02:00
instance.hide();
e.preventDefault();
e.stopPropagation();
requestAnimationFrame(() => {
dark_theme.enable();
message_lists.update_recipient_bar_background_color();
});
});
$popper.on("click", "#gear-menu-dropdown .gear-menu-select-light-theme", (e) => {
2023-10-13 12:51:35 +02:00
instance.hide();
e.preventDefault();
e.stopPropagation();
requestAnimationFrame(() => {
dark_theme.disable();
message_lists.update_recipient_bar_background_color();
});
});
},
onShow: render,
onHidden(instance) {
instance.destroy();
popover_menus.popover_instances.gear_menu = undefined;
},
});
}
2023-10-13 12:51:35 +02:00
export function toggle() {
if (popover_menus.is_gear_menu_popover_displayed()) {
popovers.hide_all();
return;
}
// Since this can be called via hotkey, we need to
// hide any other popovers that may be open before.
if (popovers.any_active()) {
popovers.hide_all();
}
$("#gear-menu").trigger("click");
}
2023-10-13 12:51:35 +02:00
export function rerender() {
if (popover_menus.is_gear_menu_popover_displayed()) {
render(popover_menus.get_gear_menu_instance());
}
}