diff --git a/app/renderer/css/preference.css b/app/renderer/css/preference.css
index c1299d3d..71fb1b43 100644
--- a/app/renderer/css/preference.css
+++ b/app/renderer/css/preference.css
@@ -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;
}
diff --git a/app/renderer/js/pages/preference/preference.ts b/app/renderer/js/pages/preference/preference.ts
index 955e6e7d..0eb8777c 100644
--- a/app/renderer/js/pages/preference/preference.ts
+++ b/app/renderer/js/pages/preference/preference.ts
@@ -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`
+
+
+
+
+
+ `.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) => {
- handleToggle("show-notification-option", newSettings.showNotification);
- handleToggle("silent-option", newSettings.silent);
+ private readonly handleToggleDnd = (
+ _event: Event,
+ _state: boolean,
+ newSettings: Partial,
+ ) => {
+ 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);
diff --git a/app/renderer/js/typed-ipc-renderer.ts b/app/renderer/js/typed-ipc-renderer.ts
index 48ba1c27..95f55180 100644
--- a/app/renderer/js/typed-ipc-renderer.ts
+++ b/app/renderer/js/typed-ipc-renderer.ts
@@ -23,6 +23,10 @@ export const ipcRenderer: {
channel: Channel,
listener: RendererListener,
): void;
+ off(
+ channel: Channel,
+ listener: RendererListener,
+ ): void;
removeListener(
channel: Channel,
listener: RendererListener,
diff --git a/app/renderer/preference.html b/app/renderer/preference.html
index 4685add3..c1ff11f4 100644
--- a/app/renderer/preference.html
+++ b/app/renderer/preference.html
@@ -5,24 +5,20 @@
Zulip - Settings
-
-
+
-
+
+
-