mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-04 05:53:21 +00:00 
			
		
		
		
	preference: Encapsulate in a custom element.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
		@@ -1,7 +1,6 @@
 | 
			
		||||
html,
 | 
			
		||||
body {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
:host {
 | 
			
		||||
  contain: strict;
 | 
			
		||||
  display: flow-root;
 | 
			
		||||
  cursor: default;
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  font-family: menu, "Helvetica Neue", sans-serif;
 | 
			
		||||
@@ -74,7 +73,7 @@ td:nth-child(odd) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#content {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  display: flex !important;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  font-family: "Montserrat", sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import type {DNDSettings} from "../../../../common/dnd-util";
 | 
			
		||||
import {html} from "../../../../common/html";
 | 
			
		||||
import type {NavItem} from "../../../../common/types";
 | 
			
		||||
import {ipcRenderer} from "../../typed-ipc-renderer";
 | 
			
		||||
 | 
			
		||||
@@ -9,51 +10,89 @@ import {initNetworkSection} from "./network-section";
 | 
			
		||||
import {initServersSection} from "./servers-section";
 | 
			
		||||
import {initShortcutsSection} from "./shortcuts-section";
 | 
			
		||||
 | 
			
		||||
export function initPreferenceView(): void {
 | 
			
		||||
  const $sidebarContainer = document.querySelector("#sidebar")!;
 | 
			
		||||
  const $settingsContainer = document.querySelector("#settings-container")!;
 | 
			
		||||
export class PreferenceView {
 | 
			
		||||
  readonly $view: HTMLElement;
 | 
			
		||||
  private readonly $shadow: ShadowRoot;
 | 
			
		||||
  private readonly $settingsContainer: Element;
 | 
			
		||||
  private readonly nav: Nav;
 | 
			
		||||
 | 
			
		||||
  const nav = new Nav({
 | 
			
		||||
    $root: $sidebarContainer,
 | 
			
		||||
    onItemSelected: handleNavigation,
 | 
			
		||||
  });
 | 
			
		||||
  constructor() {
 | 
			
		||||
    this.$view = document.createElement("div");
 | 
			
		||||
    this.$shadow = this.$view.attachShadow({mode: "open"});
 | 
			
		||||
    this.$shadow.innerHTML = html`
 | 
			
		||||
      <link
 | 
			
		||||
        rel="stylesheet"
 | 
			
		||||
        href="${require.resolve("../../../css/fonts.css")}"
 | 
			
		||||
      />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="stylesheet"
 | 
			
		||||
        href="${require.resolve("../../../css/preference.css")}"
 | 
			
		||||
      />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="stylesheet"
 | 
			
		||||
        href="${require.resolve("@yaireo/tagify/dist/tagify.css")}"
 | 
			
		||||
      />
 | 
			
		||||
      <!-- Initially hidden to prevent FOUC -->
 | 
			
		||||
      <div id="content" hidden>
 | 
			
		||||
        <div id="sidebar"></div>
 | 
			
		||||
        <div id="settings-container"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
    `.html;
 | 
			
		||||
 | 
			
		||||
  const navItem =
 | 
			
		||||
    nav.navItems.find((navItem) => window.location.hash === `#${navItem}`) ??
 | 
			
		||||
    "General";
 | 
			
		||||
    const $sidebarContainer = this.$shadow.querySelector("#sidebar")!;
 | 
			
		||||
    this.$settingsContainer = this.$shadow.querySelector(
 | 
			
		||||
      "#settings-container",
 | 
			
		||||
    )!;
 | 
			
		||||
 | 
			
		||||
  handleNavigation(navItem);
 | 
			
		||||
    this.nav = new Nav({
 | 
			
		||||
      $root: $sidebarContainer,
 | 
			
		||||
      onItemSelected: this.handleNavigation,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  function handleNavigation(navItem: NavItem): void {
 | 
			
		||||
    nav.select(navItem);
 | 
			
		||||
    const navItem =
 | 
			
		||||
      this.nav.navItems.find(
 | 
			
		||||
        (navItem) => window.location.hash === `#${navItem}`,
 | 
			
		||||
      ) ?? "General";
 | 
			
		||||
 | 
			
		||||
    this.handleNavigation(navItem);
 | 
			
		||||
 | 
			
		||||
    ipcRenderer.on("switch-settings-nav", this.handleSwitchSettingsNav);
 | 
			
		||||
    ipcRenderer.on("toggle-sidebar-setting", this.handleToggleSidebar);
 | 
			
		||||
    ipcRenderer.on("toggle-menubar-setting", this.handleToggleMenubar);
 | 
			
		||||
    ipcRenderer.on("toggle-tray", this.handleToggleTray);
 | 
			
		||||
    ipcRenderer.on("toggle-dnd", this.handleToggleDnd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleNavigation = (navItem: NavItem): void => {
 | 
			
		||||
    this.nav.select(navItem);
 | 
			
		||||
    switch (navItem) {
 | 
			
		||||
      case "AddServer":
 | 
			
		||||
        initServersSection({
 | 
			
		||||
          $root: $settingsContainer,
 | 
			
		||||
          $root: this.$settingsContainer,
 | 
			
		||||
        });
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case "General":
 | 
			
		||||
        initGeneralSection({
 | 
			
		||||
          $root: $settingsContainer,
 | 
			
		||||
          $root: this.$settingsContainer,
 | 
			
		||||
        });
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case "Organizations":
 | 
			
		||||
        initConnectedOrgSection({
 | 
			
		||||
          $root: $settingsContainer,
 | 
			
		||||
          $root: this.$settingsContainer,
 | 
			
		||||
        });
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case "Network":
 | 
			
		||||
        initNetworkSection({
 | 
			
		||||
          $root: $settingsContainer,
 | 
			
		||||
          $root: this.$settingsContainer,
 | 
			
		||||
        });
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case "Shortcuts": {
 | 
			
		||||
        initShortcutsSection({
 | 
			
		||||
          $root: $settingsContainer,
 | 
			
		||||
          $root: this.$settingsContainer,
 | 
			
		||||
        });
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
@@ -63,44 +102,57 @@ export function initPreferenceView(): void {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    window.location.hash = `#${navItem}`;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  destroy(): void {
 | 
			
		||||
    ipcRenderer.off("switch-settings-nav", this.handleSwitchSettingsNav);
 | 
			
		||||
    ipcRenderer.off("toggle-sidebar-setting", this.handleToggleSidebar);
 | 
			
		||||
    ipcRenderer.off("toggle-menubar-setting", this.handleToggleMenubar);
 | 
			
		||||
    ipcRenderer.off("toggle-tray", this.handleToggleTray);
 | 
			
		||||
    ipcRenderer.off("toggle-dnd", this.handleToggleDnd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Handle toggling and reflect changes in preference page
 | 
			
		||||
  function handleToggle(elementName: string, state = false): void {
 | 
			
		||||
  private handleToggle(elementName: string, state = false): void {
 | 
			
		||||
    const inputSelector = `#${elementName} .action .switch input`;
 | 
			
		||||
    const input: HTMLInputElement = document.querySelector(inputSelector)!;
 | 
			
		||||
    const input: HTMLInputElement = this.$shadow.querySelector(inputSelector)!;
 | 
			
		||||
    if (input) {
 | 
			
		||||
      input.checked = state;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ipcRenderer.on("switch-settings-nav", (_event: Event, navItem: NavItem) => {
 | 
			
		||||
    handleNavigation(navItem);
 | 
			
		||||
  });
 | 
			
		||||
  private readonly handleSwitchSettingsNav = (
 | 
			
		||||
    _event: Event,
 | 
			
		||||
    navItem: NavItem,
 | 
			
		||||
  ) => {
 | 
			
		||||
    this.handleNavigation(navItem);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ipcRenderer.on("toggle-sidebar-setting", (_event: Event, state: boolean) => {
 | 
			
		||||
    handleToggle("sidebar-option", state);
 | 
			
		||||
  });
 | 
			
		||||
  private readonly handleToggleSidebar = (_event: Event, state: boolean) => {
 | 
			
		||||
    this.handleToggle("sidebar-option", state);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ipcRenderer.on("toggle-menubar-setting", (_event: Event, state: boolean) => {
 | 
			
		||||
    handleToggle("menubar-option", state);
 | 
			
		||||
  });
 | 
			
		||||
  private readonly handleToggleMenubar = (_event: Event, state: boolean) => {
 | 
			
		||||
    this.handleToggle("menubar-option", state);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ipcRenderer.on("toggle-tray", (_event: Event, state: boolean) => {
 | 
			
		||||
    handleToggle("tray-option", state);
 | 
			
		||||
  });
 | 
			
		||||
  private readonly handleToggleTray = (_event: Event, state: boolean) => {
 | 
			
		||||
    this.handleToggle("tray-option", state);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ipcRenderer.on(
 | 
			
		||||
    "toggle-dnd",
 | 
			
		||||
    (_event: Event, _state: boolean, newSettings: Partial<DNDSettings>) => {
 | 
			
		||||
      handleToggle("show-notification-option", newSettings.showNotification);
 | 
			
		||||
      handleToggle("silent-option", newSettings.silent);
 | 
			
		||||
  private readonly handleToggleDnd = (
 | 
			
		||||
    _event: Event,
 | 
			
		||||
    _state: boolean,
 | 
			
		||||
    newSettings: Partial<DNDSettings>,
 | 
			
		||||
  ) => {
 | 
			
		||||
    this.handleToggle("show-notification-option", newSettings.showNotification);
 | 
			
		||||
    this.handleToggle("silent-option", newSettings.silent);
 | 
			
		||||
 | 
			
		||||
      if (process.platform === "win32") {
 | 
			
		||||
        handleToggle("flash-taskbar-option", newSettings.flashTaskbarOnMessage);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
    if (process.platform === "win32") {
 | 
			
		||||
      this.handleToggle(
 | 
			
		||||
        "flash-taskbar-option",
 | 
			
		||||
        newSettings.flashTaskbarOnMessage,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.addEventListener("load", initPreferenceView);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,10 @@ export const ipcRenderer: {
 | 
			
		||||
    channel: Channel,
 | 
			
		||||
    listener: RendererListener<Channel>,
 | 
			
		||||
  ): void;
 | 
			
		||||
  off<Channel extends keyof RendererMessage>(
 | 
			
		||||
    channel: Channel,
 | 
			
		||||
    listener: RendererListener<Channel>,
 | 
			
		||||
  ): void;
 | 
			
		||||
  removeListener<Channel extends keyof RendererMessage>(
 | 
			
		||||
    channel: Channel,
 | 
			
		||||
    listener: RendererListener<Channel>,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,24 +5,20 @@
 | 
			
		||||
    <meta name="viewport" content="width=device-width" />
 | 
			
		||||
    <title>Zulip - Settings</title>
 | 
			
		||||
    <link rel="stylesheet" href="css/fonts.css" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="css/preference.css"
 | 
			
		||||
      type="text/css"
 | 
			
		||||
      media="screen"
 | 
			
		||||
    />
 | 
			
		||||
    <link id="tagify-css" rel="stylesheet" href="data:text/css," />
 | 
			
		||||
    <style>
 | 
			
		||||
      html,
 | 
			
		||||
      body,
 | 
			
		||||
      body > div {
 | 
			
		||||
        margin: 0;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="content">
 | 
			
		||||
      <div id="sidebar"></div>
 | 
			
		||||
      <div id="settings-container"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <zd-preference-view></zd-preference-view>
 | 
			
		||||
    <script>
 | 
			
		||||
      const {PreferenceView} = require("./js/pages/preference/preference.js");
 | 
			
		||||
      document.body.append(new PreferenceView().$view);
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
  <script>
 | 
			
		||||
    document.querySelector("#tagify-css").href = require.resolve(
 | 
			
		||||
      "@yaireo/tagify/dist/tagify.css",
 | 
			
		||||
    );
 | 
			
		||||
    require("./js/pages/preference/preference.js");
 | 
			
		||||
  </script>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user