typescript: Enable strictNullChecks.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2021-04-02 15:19:42 -07:00
parent 33c21d0153
commit 9a81ade1c8
13 changed files with 129 additions and 117 deletions

View File

@@ -292,7 +292,7 @@ function getHelpSubmenu(): Electron.MenuItemConstructorOptions[] {
function getWindowSubmenu(
tabs: TabData[],
activeTabIndex: number,
activeTabIndex?: number,
): Electron.MenuItemConstructorOptions[] {
const initialSubmenu: Electron.MenuItemConstructorOptions[] = [
{
@@ -342,7 +342,7 @@ function getWindowSubmenu(
if (focusedWindow) {
sendAction(
"switch-server-tab",
getNextServer(tabs, activeTabIndex),
getNextServer(tabs, activeTabIndex!),
);
}
},
@@ -355,7 +355,7 @@ function getWindowSubmenu(
if (focusedWindow) {
sendAction(
"switch-server-tab",
getPreviousServer(tabs, activeTabIndex),
getPreviousServer(tabs, activeTabIndex!),
);
}
},
@@ -367,7 +367,7 @@ function getWindowSubmenu(
}
function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
const {tabs, activeTabIndex, enableMenu} = props;
const {tabs, activeTabIndex, enableMenu = false} = props;
return [
{
@@ -533,7 +533,7 @@ function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
}
function getOtherTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
const {tabs, activeTabIndex, enableMenu} = props;
const {tabs, activeTabIndex, enableMenu = false} = props;
return [
{
label: t.__("File"),

View File

@@ -6,7 +6,8 @@ import type {TabProps} from "./tab";
import Tab from "./tab";
export default class FunctionalTab extends Tab {
$closeButton: Element;
$el: Element;
$closeButton?: Element;
constructor(props: TabProps) {
super(props);
@@ -14,7 +15,7 @@ export default class FunctionalTab extends Tab {
this.$el = generateNodeFromHTML(this.templateHTML());
if (this.props.name !== "Settings") {
this.props.$root.append(this.$el);
this.$closeButton = this.$el.querySelector(".server-tab-badge");
this.$closeButton = this.$el.querySelector(".server-tab-badge")!;
this.registerListeners();
}
}
@@ -36,15 +37,15 @@ export default class FunctionalTab extends Tab {
super.registerListeners();
this.$el.addEventListener("mouseover", () => {
this.$closeButton.classList.add("active");
this.$closeButton?.classList.add("active");
});
this.$el.addEventListener("mouseout", () => {
this.$closeButton.classList.remove("active");
this.$closeButton?.classList.remove("active");
});
this.$closeButton.addEventListener("click", (event: Event) => {
this.props.onDestroy();
this.$closeButton?.addEventListener("click", (event: Event) => {
this.props.onDestroy?.();
event.stopPropagation();
});
}

View File

@@ -59,7 +59,7 @@ export default function handleExternalLink(
body: "Download failed",
});
} else {
this.$el.downloadURL(url.href);
this.$el!.downloadURL(url.href);
}
}

View File

@@ -9,6 +9,7 @@ import type {TabProps} from "./tab";
import Tab from "./tab";
export default class ServerTab extends Tab {
$el: Element;
$badge: Element;
constructor(props: TabProps) {
@@ -17,7 +18,7 @@ export default class ServerTab extends Tab {
this.$el = generateNodeFromHTML(this.templateHTML());
this.props.$root.append(this.$el);
this.registerListeners();
this.$badge = this.$el.querySelector(".server-tab-badge");
this.$badge = this.$el.querySelector(".server-tab-badge")!;
}
templateHTML(): HTML {

View File

@@ -15,10 +15,11 @@ export interface TabProps {
onDestroy?: () => void;
}
export default class Tab {
export default abstract class Tab {
props: TabProps;
webview: WebView;
$el: Element;
abstract $el: Element;
constructor(props: TabProps) {
this.props = props;
this.webview = this.props.webview;
@@ -26,8 +27,14 @@ export default class Tab {
registerListeners(): void {
this.$el.addEventListener("click", this.props.onClick);
this.$el.addEventListener("mouseover", this.props.onHover);
this.$el.addEventListener("mouseout", this.props.onHoverOut);
if (this.props.onHover !== undefined) {
this.$el.addEventListener("mouseover", this.props.onHover);
}
if (this.props.onHoverOut !== undefined) {
this.$el.addEventListener("mouseout", this.props.onHoverOut);
}
}
showNetworkError(): void {
@@ -46,6 +53,6 @@ export default class Tab {
destroy(): void {
this.$el.remove();
this.webview.$el.remove();
this.webview.$el!.remove();
}
}

View File

@@ -35,9 +35,9 @@ export default class WebView {
zoomFactor: number;
badgeCount: number;
loading: boolean;
customCSS: string;
customCSS: string | null;
$webviewsContainer: DOMTokenList;
$el: Electron.WebviewTag;
$el?: Electron.WebviewTag;
domReady?: Promise<void>;
constructor(props: WebViewProps) {
@@ -48,7 +48,7 @@ export default class WebView {
this.customCSS = ConfigUtil.getConfigItem("customCSS");
this.$webviewsContainer = document.querySelector(
"#webviews-container",
).classList;
)!.classList;
}
templateHTML(): HTML {
@@ -74,7 +74,7 @@ export default class WebView {
init(): void {
this.$el = generateNodeFromHTML(this.templateHTML()) as Electron.WebviewTag;
this.domReady = new Promise((resolve) => {
this.$el.addEventListener(
this.$el!.addEventListener(
"dom-ready",
() => {
resolve();
@@ -88,23 +88,23 @@ export default class WebView {
}
registerListeners(): void {
this.$el.addEventListener("new-window", (event) => {
this.$el!.addEventListener("new-window", (event) => {
handleExternalLink.call(this, event);
});
if (shouldSilentWebview) {
this.$el.addEventListener("dom-ready", () => {
this.$el.setAudioMuted(true);
this.$el!.addEventListener("dom-ready", () => {
this.$el!.setAudioMuted(true);
});
}
this.$el.addEventListener("page-title-updated", (event) => {
this.$el!.addEventListener("page-title-updated", (event) => {
const {title} = event;
this.badgeCount = this.getBadgeCount(title);
this.props.onTitleChange();
});
this.$el.addEventListener("did-navigate-in-page", (event) => {
this.$el!.addEventListener("did-navigate-in-page", (event) => {
const isSettingPage = event.url.includes("renderer/preference.html");
if (isSettingPage) {
return;
@@ -113,11 +113,11 @@ export default class WebView {
this.canGoBackButton();
});
this.$el.addEventListener("did-navigate", () => {
this.$el!.addEventListener("did-navigate", () => {
this.canGoBackButton();
});
this.$el.addEventListener("page-favicon-updated", (event) => {
this.$el!.addEventListener("page-favicon-updated", (event) => {
const {favicons} = event;
// This returns a string of favicons URL. If there is a PM counts in unread messages then the URL would be like
@@ -135,16 +135,16 @@ export default class WebView {
}
});
this.$el.addEventListener("dom-ready", () => {
this.$el!.addEventListener("dom-ready", () => {
const webContents = remote.webContents.fromId(
this.$el.getWebContentsId(),
this.$el!.getWebContentsId(),
);
webContents.addListener("context-menu", (event, menuParameters) => {
contextMenu(webContents, event, menuParameters);
});
if (this.props.role === "server") {
this.$el.classList.add("onload");
this.$el!.classList.add("onload");
}
this.loading = false;
@@ -153,11 +153,11 @@ export default class WebView {
// Refocus text boxes after reload
// Remove when upstream issue https://github.com/electron/electron/issues/14474 is fixed
this.$el.blur();
this.$el.focus();
this.$el!.blur();
this.$el!.focus();
});
this.$el.addEventListener("did-fail-load", (event) => {
this.$el!.addEventListener("did-fail-load", (event) => {
const {errorDescription} = event;
const hasConnectivityError = SystemUtil.connectivityERR.includes(
errorDescription,
@@ -170,14 +170,14 @@ export default class WebView {
}
});
this.$el.addEventListener("did-start-loading", () => {
this.$el!.addEventListener("did-start-loading", () => {
const isSettingPage = this.props.url.includes("renderer/preference.html");
if (!isSettingPage) {
this.props.switchLoading(true, this.props.url);
}
});
this.$el.addEventListener("did-stop-loading", () => {
this.$el!.addEventListener("did-stop-loading", () => {
this.props.switchLoading(false, this.props.url);
});
}
@@ -189,7 +189,7 @@ export default class WebView {
showNotificationSettings(): void {
ipcRenderer.sendTo(
this.$el.getWebContentsId(),
this.$el!.getWebContentsId(),
"show-notification-settings",
);
}
@@ -207,18 +207,18 @@ export default class WebView {
this.$webviewsContainer.add("loaded");
}
this.$el.classList.remove("disabled");
this.$el.classList.add("active");
this.$el!.classList.remove("disabled");
this.$el!.classList.add("active");
setTimeout(() => {
if (this.props.role === "server") {
this.$el.classList.remove("onload");
this.$el!.classList.remove("onload");
}
}, 1000);
this.focus();
this.props.onTitleChange();
// Injecting preload css in webview to override some css rules
(async () =>
this.$el.insertCSS(
this.$el!.insertCSS(
fs.readFileSync(path.join(__dirname, "/../../css/preload.css"), "utf8"),
))();
@@ -235,15 +235,15 @@ export default class WebView {
}
(async () =>
this.$el.insertCSS(
fs.readFileSync(path.resolve(__dirname, this.customCSS), "utf8"),
this.$el!.insertCSS(
fs.readFileSync(path.resolve(__dirname, this.customCSS!), "utf8"),
))();
}
}
focus(): void {
// Focus Webview and it's contents when Window regain focus.
const webContents = remote.webContents.fromId(this.$el.getWebContentsId());
const webContents = remote.webContents.fromId(this.$el!.getWebContentsId());
// HACK: webContents.isFocused() seems to be true even without the element
// being in focus. So, we check against `document.activeElement`.
if (webContents && this.$el !== document.activeElement) {
@@ -251,14 +251,14 @@ export default class WebView {
// element to transfer focus correctly, in Electron v3.0.10
// See https://github.com/electron/electron/issues/15718
(document.activeElement as HTMLElement).blur();
this.$el.focus();
this.$el!.focus();
webContents.focus();
}
}
hide(): void {
this.$el.classList.add("disabled");
this.$el.classList.remove("active");
this.$el!.classList.add("disabled");
this.$el!.classList.remove("active");
}
load(): void {
@@ -271,34 +271,34 @@ export default class WebView {
zoomIn(): void {
this.zoomFactor += 0.1;
this.$el.setZoomFactor(this.zoomFactor);
this.$el!.setZoomFactor(this.zoomFactor);
}
zoomOut(): void {
this.zoomFactor -= 0.1;
this.$el.setZoomFactor(this.zoomFactor);
this.$el!.setZoomFactor(this.zoomFactor);
}
zoomActualSize(): void {
this.zoomFactor = 1;
this.$el.setZoomFactor(this.zoomFactor);
this.$el!.setZoomFactor(this.zoomFactor);
}
logOut(): void {
ipcRenderer.sendTo(this.$el.getWebContentsId(), "logout");
ipcRenderer.sendTo(this.$el!.getWebContentsId(), "logout");
}
showKeyboardShortcuts(): void {
ipcRenderer.sendTo(this.$el.getWebContentsId(), "show-keyboard-shortcuts");
ipcRenderer.sendTo(this.$el!.getWebContentsId(), "show-keyboard-shortcuts");
}
openDevTools(): void {
this.$el.openDevTools();
this.$el!.openDevTools();
}
back(): void {
if (this.$el.canGoBack()) {
this.$el.goBack();
if (this.$el!.canGoBack()) {
this.$el!.goBack();
this.focus();
}
}
@@ -306,8 +306,8 @@ export default class WebView {
canGoBackButton(): void {
const $backButton = document.querySelector(
"#actions-container #back-action",
);
if (this.$el.canGoBack()) {
)!;
if (this.$el!.canGoBack()) {
$backButton.classList.remove("disable");
} else {
$backButton.classList.add("disable");
@@ -315,8 +315,8 @@ export default class WebView {
}
forward(): void {
if (this.$el.canGoForward()) {
this.$el.goForward();
if (this.$el!.canGoForward()) {
this.$el!.goForward();
}
}
@@ -326,7 +326,7 @@ export default class WebView {
this.$webviewsContainer.remove("loaded");
this.loading = true;
this.props.switchLoading(true, this.props.url);
this.$el.reload();
this.$el!.reload();
}
forceLoad(): void {
@@ -335,6 +335,6 @@ export default class WebView {
async send(channel: string, ...parameters: unknown[]): Promise<void> {
await this.domReady;
await this.$el.send(channel, ...parameters);
await this.$el!.send(channel, ...parameters);
}
}

View File

@@ -9,8 +9,8 @@ const {app} = remote;
customElements.define("send-feedback", SendFeedback);
export const sendFeedback: SendFeedback = document.querySelector(
"send-feedback",
);
export const feedbackHolder = sendFeedback.parentElement;
)!;
export const feedbackHolder = sendFeedback.parentElement!;
// Make the button color match zulip app's theme
sendFeedback.customStylesheet = "css/feedback.css";

View File

@@ -86,21 +86,25 @@ class ServerManagerView {
tabIndex: number;
presetOrgs: string[];
constructor() {
this.$addServerButton = document.querySelector("#add-tab");
this.$tabsContainer = document.querySelector("#tabs-container");
this.$addServerButton = document.querySelector("#add-tab")!;
this.$tabsContainer = document.querySelector("#tabs-container")!;
const $actionsContainer = document.querySelector("#actions-container");
this.$reloadButton = $actionsContainer.querySelector("#reload-action");
this.$loadingIndicator = $actionsContainer.querySelector("#loading-action");
this.$settingsButton = $actionsContainer.querySelector("#settings-action");
this.$webviewsContainer = document.querySelector("#webviews-container");
this.$backButton = $actionsContainer.querySelector("#back-action");
this.$dndButton = $actionsContainer.querySelector("#dnd-action");
const $actionsContainer = document.querySelector("#actions-container")!;
this.$reloadButton = $actionsContainer.querySelector("#reload-action")!;
this.$loadingIndicator = $actionsContainer.querySelector(
"#loading-action",
)!;
this.$settingsButton = $actionsContainer.querySelector("#settings-action")!;
this.$webviewsContainer = document.querySelector("#webviews-container")!;
this.$backButton = $actionsContainer.querySelector("#back-action")!;
this.$dndButton = $actionsContainer.querySelector("#dnd-action")!;
this.$addServerTooltip = document.querySelector("#add-server-tooltip");
this.$reloadTooltip = $actionsContainer.querySelector("#reload-tooltip");
this.$loadingTooltip = $actionsContainer.querySelector("#loading-tooltip");
this.$settingsTooltip = $actionsContainer.querySelector("#setting-tooltip");
this.$addServerTooltip = document.querySelector("#add-server-tooltip")!;
this.$reloadTooltip = $actionsContainer.querySelector("#reload-tooltip")!;
this.$loadingTooltip = $actionsContainer.querySelector("#loading-tooltip")!;
this.$settingsTooltip = $actionsContainer.querySelector(
"#setting-tooltip",
)!;
// TODO: This should have been querySelector but the problem is that
// querySelector doesn't return elements not present in dom whereas somehow
@@ -110,12 +114,12 @@ class ServerManagerView {
this.$serverIconTooltip = document.getElementsByClassName(
"server-tooltip",
) as HTMLCollectionOf<HTMLElement>;
this.$backTooltip = $actionsContainer.querySelector("#back-tooltip");
this.$dndTooltip = $actionsContainer.querySelector("#dnd-tooltip");
this.$backTooltip = $actionsContainer.querySelector("#back-tooltip")!;
this.$dndTooltip = $actionsContainer.querySelector("#dnd-tooltip")!;
this.$sidebar = document.querySelector("#sidebar");
this.$sidebar = document.querySelector("#sidebar")!;
this.$fullscreenPopup = document.querySelector("#fullscreen-popup");
this.$fullscreenPopup = document.querySelector("#fullscreen-popup")!;
this.$fullscreenEscapeKey = process.platform === "darwin" ? "^⌘F" : "F11";
this.$fullscreenPopup.textContent = `Press ${this.$fullscreenEscapeKey} to exit full screen`;
@@ -486,12 +490,12 @@ class ServerManagerView {
// error
const $altIcon = document.createElement("div");
const $parent = $img.parentElement;
const $container = $parent.parentElement;
const webviewId = $container.dataset.tabId;
const $parent = $img.parentElement!;
const $container = $parent.parentElement!;
const webviewId = $container.dataset.tabId!;
const $webview = document.querySelector(
`webview[data-tab-id="${CSS.escape(webviewId)}"]`,
);
)!;
const realmName = $webview.getAttribute("name");
if (realmName === null) {
@@ -539,7 +543,7 @@ class ServerManagerView {
// as that of its parent element.
const {top} = this.$serverIconTooltip[
index
].parentElement.getBoundingClientRect();
].parentElement!.getBoundingClientRect();
this.$serverIconTooltip[index].style.top = `${top}px`;
}
@@ -549,7 +553,7 @@ class ServerManagerView {
openFunctionalTab(tabProps: FunctionalTabProps): void {
if (this.functionalTabs.has(tabProps.name)) {
this.activateTab(this.functionalTabs.get(tabProps.name));
this.activateTab(this.functionalTabs.get(tabProps.name)!);
return;
}
@@ -563,20 +567,20 @@ class ServerManagerView {
materialIcon: tabProps.materialIcon,
name: tabProps.name,
$root: this.$tabsContainer,
index: this.functionalTabs.get(tabProps.name),
index: this.functionalTabs.get(tabProps.name)!,
tabIndex,
onClick: this.activateTab.bind(
this,
this.functionalTabs.get(tabProps.name),
this.functionalTabs.get(tabProps.name)!,
),
onDestroy: this.destroyTab.bind(
this,
tabProps.name,
this.functionalTabs.get(tabProps.name),
this.functionalTabs.get(tabProps.name)!,
),
webview: new WebView({
$root: this.$webviewsContainer,
index: this.functionalTabs.get(tabProps.name),
index: this.functionalTabs.get(tabProps.name)!,
tabIndex,
url: tabProps.url,
role: "function",
@@ -610,7 +614,7 @@ class ServerManagerView {
// closed when the functional tab DOM is ready, handled in webview.js
this.$webviewsContainer.classList.remove("loaded");
this.activateTab(this.functionalTabs.get(tabProps.name));
this.activateTab(this.functionalTabs.get(tabProps.name)!);
}
async openSettings(nav: NavItem = "General"): Promise<void> {
@@ -620,7 +624,7 @@ class ServerManagerView {
url: `file://${rendererDirectory}/preference.html#${nav}`,
});
this.$settingsButton.classList.add("active");
await this.tabs[this.functionalTabs.get("Settings")].webview.send(
await this.tabs[this.functionalTabs.get("Settings")!].webview.send(
"switch-settings-nav",
nav,
);
@@ -798,19 +802,19 @@ class ServerManagerView {
toggleDNDButton(alert: boolean): void {
this.$dndTooltip.textContent =
(alert ? "Disable" : "Enable") + " Do Not Disturb";
this.$dndButton.querySelector("i").textContent = alert
this.$dndButton.querySelector("i")!.textContent = alert
? "notifications_off"
: "notifications";
}
isLoggedIn(tabIndex: number): boolean {
const url = this.tabs[tabIndex].webview.$el.src;
const url = this.tabs[tabIndex].webview.$el!.src;
return !(url.endsWith("/login/") || this.tabs[tabIndex].webview.loading);
}
getActiveWebview(): Electron.WebviewTag {
const selector = "webview:not(.disabled)";
const webview: Electron.WebviewTag = document.querySelector(selector);
const webview: Electron.WebviewTag = document.querySelector(selector)!;
return webview;
}
@@ -954,7 +958,7 @@ class ServerManagerView {
: this.tabs.some(
({webview}) =>
!webview.loading &&
webview.$el.getWebContentsId() === webContentsId &&
webview.$el!.getWebContentsId() === webContentsId &&
webview.props.hasPermission?.(origin, permission),
);
console.log(
@@ -1132,10 +1136,10 @@ class ServerManagerView {
);
for (const webview of webviews) {
const currentId = webview.getWebContentsId();
const tabId = webview.getAttribute("data-tab-id");
const tabId = webview.getAttribute("data-tab-id")!;
const concurrentTab: HTMLButtonElement = document.querySelector(
`div[data-tab-id="${CSS.escape(tabId)}"]`,
);
)!;
if (currentId === webviewId) {
concurrentTab.click();
}
@@ -1152,7 +1156,7 @@ class ServerManagerView {
canvas.height = 128;
canvas.width = 128;
canvas.style.letterSpacing = "-5px";
const ctx = canvas.getContext("2d");
const ctx = canvas.getContext("2d")!;
ctx.fillStyle = "#f42020";
ctx.beginPath();
ctx.ellipse(64, 64, 64, 64, 0, 0, 2 * Math.PI);

View File

@@ -53,7 +53,7 @@ export default class PreferenceNav {
registerListeners(): void {
for (const navItem of this.navItems) {
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`);
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`)!;
$item.addEventListener("click", () => {
this.props.onItemSelected(navItem);
});
@@ -71,12 +71,12 @@ export default class PreferenceNav {
}
activate(navItem: NavItem): void {
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`);
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`)!;
$item.classList.add("active");
}
deactivate(navItem: NavItem): void {
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`);
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`)!;
$item.classList.remove("active");
}
}

View File

@@ -12,7 +12,7 @@ ipcRenderer.on("logout", () => {
}
// Create the menu for the below
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle");
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle")!;
dropdown.click();
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll(
@@ -29,13 +29,13 @@ ipcRenderer.on("show-keyboard-shortcuts", () => {
// Create the menu for the below
const node: HTMLElement = document.querySelector(
"a[data-overlay-trigger=keyboard-shortcuts]",
);
)!;
// Additional check
if (node.textContent.trim().toLowerCase() === "keyboard shortcuts (?)") {
if (node.textContent!.trim().toLowerCase() === "keyboard shortcuts (?)") {
node.click();
} else {
// Atleast click the dropdown
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle");
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle")!;
dropdown.click();
}
});
@@ -46,7 +46,7 @@ ipcRenderer.on("show-notification-settings", () => {
}
// Create the menu for the below
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle");
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle")!;
dropdown.click();
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll(
@@ -69,8 +69,8 @@ window.addEventListener("load", (event: any): void => {
return;
}
const $reconnectButton = document.querySelector("#reconnect");
const $settingsButton = document.querySelector("#settings");
const $reconnectButton = document.querySelector("#reconnect")!;
const $settingsButton = document.querySelector("#settings")!;
NetworkError.init($reconnectButton, $settingsButton);
});

View File

@@ -6,7 +6,7 @@ import * as ConfigUtil from "../../common/config-util";
const {Tray, Menu, nativeImage, BrowserWindow} = remote;
let tray: Electron.Tray;
let tray: Electron.Tray | null = null;
const ICON_DIR = "../../resources/tray";
@@ -69,7 +69,7 @@ const renderCanvas = function (arg: number): HTMLCanvasElement {
const canvas = document.createElement("canvas");
canvas.width = SIZE;
canvas.height = SIZE;
const ctx = canvas.getContext("2d");
const ctx = canvas.getContext("2d")!;
// Circle
// If (!config.thick || config.thick && HAS_COUNT) {
@@ -210,15 +210,15 @@ function toggleTray(): void {
createTray();
if (process.platform === "linux" || process.platform === "win32") {
const image = renderNativeImage(unread);
tray.setImage(image);
tray.setToolTip(`${unread} unread messages`);
tray!.setImage(image);
tray!.setToolTip(`${unread} unread messages`);
}
ConfigUtil.setConfigItem("trayIcon", true);
}
const selector = "webview:not([class*=disabled])";
const webview: WebviewTag = document.querySelector(selector);
const webview: WebviewTag = document.querySelector(selector)!;
const webContents = remote.webContents.fromId(webview.getWebContentsId());
webContents.send("toggletray", state);
}

View File

@@ -17,7 +17,7 @@ const logger = new Logger({
const defaultIconUrl = "../renderer/img/icon.png";
let db: JsonDB;
let db!: JsonDB;
reloadDB();
// Migrate from old schema

View File

@@ -10,7 +10,6 @@
/* Strict type-checking */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": false,
"noImplicitThis": true,
"alwaysStrict": true,