zulip/web/src/settings_panel_menu.js
Anders Kaseorg c1675913a2 web: Move web app to ‘web’ directory.
Ever since we started bundling the app with webpack, there’s been less
and less overlap between our ‘static’ directory (files belonging to
the frontend app) and Django’s interpretation of the ‘static’
directory (files served directly to the web).

Split the app out to its own ‘web’ directory outside of ‘static’, and
remove all the custom collectstatic --ignore rules.  This makes it
much clearer what’s actually being served to the web, and what’s being
bundled by webpack.  It also shrinks the release tarball by 3%.

Signed-off-by: Anders Kaseorg <[email protected]>
2023-02-23 16:04:17 -08:00

183 lines
5.6 KiB
JavaScript

import $ from "jquery";
import * as browser_history from "./browser_history";
import * as keydown_util from "./keydown_util";
import * as popovers from "./popovers";
import * as settings from "./settings";
import * as settings_sections from "./settings_sections";
import * as ui from "./ui";
export let normal_settings;
export let org_settings;
export function mobile_deactivate_section() {
const $settings_overlay_container = $("#settings_overlay_container");
$settings_overlay_container.find(".right").removeClass("show");
$settings_overlay_container.find(".settings-header.mobile").removeClass("slide-left");
}
function two_column_mode() {
return $("#settings_overlay_container").css("--single-column") === undefined;
}
export class SettingsPanelMenu {
constructor(opts) {
this.$main_elem = opts.$main_elem;
this.hash_prefix = opts.hash_prefix;
this.$curr_li = this.$main_elem.children("li").eq(0);
this.$main_elem.on("click", "li[data-section]", (e) => {
const section = $(e.currentTarget).attr("data-section");
this.activate_section_or_default(section);
// You generally want to add logic to activate_section,
// not to this click handler.
e.stopPropagation();
});
}
show() {
this.$main_elem.show();
const section = this.current_tab();
if (two_column_mode()) {
// In one column mode want to show the settings list, not the first settings section.
this.activate_section_or_default(section);
}
this.$curr_li.trigger("focus");
}
hide() {
this.$main_elem.hide();
}
current_tab() {
return this.$curr_li.data("section");
}
li_for_section(section) {
const $li = $(`#settings_overlay_container li[data-section='${CSS.escape(section)}']`);
return $li;
}
set_key_handlers(toggler) {
const {vim_left, vim_right, vim_up, vim_down} = keydown_util;
keydown_util.handle({
$elem: this.$main_elem,
handlers: {
ArrowLeft: toggler.maybe_go_left,
ArrowRight: toggler.maybe_go_right,
Enter: () => this.enter_panel(),
ArrowUp: () => this.prev(),
ArrowDown: () => this.next(),
// Binding vim keys as well
[vim_left]: toggler.maybe_go_left,
[vim_right]: toggler.maybe_go_right,
[vim_up]: () => this.prev(),
[vim_down]: () => this.next(),
},
});
}
prev() {
this.$curr_li.prevAll(":visible").first().trigger("focus").trigger("click");
return true;
}
next() {
this.$curr_li.nextAll(":visible").first().trigger("focus").trigger("click");
return true;
}
enter_panel() {
const $panel = this.get_panel();
const $panel_elem = $panel.find("input:visible,button:visible,select:visible").first();
$panel_elem.trigger("focus");
return true;
}
activate_section_or_default(section) {
popovers.hide_all();
if (!section) {
// No section is given so we display the default.
if (two_column_mode()) {
// In two column mode we resume to the last active section.
section = this.current_tab();
} else {
// In single column mode we close the active section
// so that you always start at the settings list.
mobile_deactivate_section();
return;
}
}
const $li_for_section = this.li_for_section(section);
if ($li_for_section.length === 0) {
// This happens when there is no such section or the user does not have
// permission to view that section.
section = this.current_tab();
} else {
this.$curr_li = $li_for_section;
}
this.$main_elem.children("li").removeClass("active");
this.$curr_li.addClass("active");
const settings_section_hash = "#" + this.hash_prefix + section;
// It could be that the hash has already been set.
browser_history.update_hash_internally_if_required(settings_section_hash);
$(".settings-section").removeClass("show");
settings_sections.load_settings_section(section);
this.get_panel().addClass("show");
ui.reset_scrollbar($("#settings_content"));
const $settings_overlay_container = $("#settings_overlay_container");
$settings_overlay_container.find(".right").addClass("show");
$settings_overlay_container.find(".settings-header.mobile").addClass("slide-left");
settings.set_settings_header(section);
}
get_panel() {
const section = this.$curr_li.data("section");
const sel = `[data-name='${CSS.escape(section)}']`;
const $panel = $(".settings-section" + sel);
return $panel;
}
}
export function initialize() {
normal_settings = new SettingsPanelMenu({
$main_elem: $(".normal-settings-list"),
hash_prefix: "settings/",
});
org_settings = new SettingsPanelMenu({
$main_elem: $(".org-settings-list"),
hash_prefix: "organization/",
});
}
export function show_normal_settings() {
org_settings.hide();
normal_settings.show();
}
export function show_org_settings() {
normal_settings.hide();
org_settings.show();
}
export function set_key_handlers(toggler) {
normal_settings.set_key_handlers(toggler);
org_settings.set_key_handlers(toggler);
}