mirror of
https://github.com/zulip/zulip-desktop.git
synced 2025-11-01 12:33:31 +00:00
typescript: Enable strictNullChecks.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
@@ -292,7 +292,7 @@ function getHelpSubmenu(): Electron.MenuItemConstructorOptions[] {
|
|||||||
|
|
||||||
function getWindowSubmenu(
|
function getWindowSubmenu(
|
||||||
tabs: TabData[],
|
tabs: TabData[],
|
||||||
activeTabIndex: number,
|
activeTabIndex?: number,
|
||||||
): Electron.MenuItemConstructorOptions[] {
|
): Electron.MenuItemConstructorOptions[] {
|
||||||
const initialSubmenu: Electron.MenuItemConstructorOptions[] = [
|
const initialSubmenu: Electron.MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
@@ -342,7 +342,7 @@ function getWindowSubmenu(
|
|||||||
if (focusedWindow) {
|
if (focusedWindow) {
|
||||||
sendAction(
|
sendAction(
|
||||||
"switch-server-tab",
|
"switch-server-tab",
|
||||||
getNextServer(tabs, activeTabIndex),
|
getNextServer(tabs, activeTabIndex!),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -355,7 +355,7 @@ function getWindowSubmenu(
|
|||||||
if (focusedWindow) {
|
if (focusedWindow) {
|
||||||
sendAction(
|
sendAction(
|
||||||
"switch-server-tab",
|
"switch-server-tab",
|
||||||
getPreviousServer(tabs, activeTabIndex),
|
getPreviousServer(tabs, activeTabIndex!),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -367,7 +367,7 @@ function getWindowSubmenu(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
|
function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
|
||||||
const {tabs, activeTabIndex, enableMenu} = props;
|
const {tabs, activeTabIndex, enableMenu = false} = props;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -533,7 +533,7 @@ function getDarwinTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getOtherTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
|
function getOtherTpl(props: MenuProps): Electron.MenuItemConstructorOptions[] {
|
||||||
const {tabs, activeTabIndex, enableMenu} = props;
|
const {tabs, activeTabIndex, enableMenu = false} = props;
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: t.__("File"),
|
label: t.__("File"),
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import type {TabProps} from "./tab";
|
|||||||
import Tab from "./tab";
|
import Tab from "./tab";
|
||||||
|
|
||||||
export default class FunctionalTab extends Tab {
|
export default class FunctionalTab extends Tab {
|
||||||
$closeButton: Element;
|
$el: Element;
|
||||||
|
$closeButton?: Element;
|
||||||
|
|
||||||
constructor(props: TabProps) {
|
constructor(props: TabProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -14,7 +15,7 @@ export default class FunctionalTab extends Tab {
|
|||||||
this.$el = generateNodeFromHTML(this.templateHTML());
|
this.$el = generateNodeFromHTML(this.templateHTML());
|
||||||
if (this.props.name !== "Settings") {
|
if (this.props.name !== "Settings") {
|
||||||
this.props.$root.append(this.$el);
|
this.props.$root.append(this.$el);
|
||||||
this.$closeButton = this.$el.querySelector(".server-tab-badge");
|
this.$closeButton = this.$el.querySelector(".server-tab-badge")!;
|
||||||
this.registerListeners();
|
this.registerListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,15 +37,15 @@ export default class FunctionalTab extends Tab {
|
|||||||
super.registerListeners();
|
super.registerListeners();
|
||||||
|
|
||||||
this.$el.addEventListener("mouseover", () => {
|
this.$el.addEventListener("mouseover", () => {
|
||||||
this.$closeButton.classList.add("active");
|
this.$closeButton?.classList.add("active");
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$el.addEventListener("mouseout", () => {
|
this.$el.addEventListener("mouseout", () => {
|
||||||
this.$closeButton.classList.remove("active");
|
this.$closeButton?.classList.remove("active");
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$closeButton.addEventListener("click", (event: Event) => {
|
this.$closeButton?.addEventListener("click", (event: Event) => {
|
||||||
this.props.onDestroy();
|
this.props.onDestroy?.();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default function handleExternalLink(
|
|||||||
body: "Download failed",
|
body: "Download failed",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.$el.downloadURL(url.href);
|
this.$el!.downloadURL(url.href);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import type {TabProps} from "./tab";
|
|||||||
import Tab from "./tab";
|
import Tab from "./tab";
|
||||||
|
|
||||||
export default class ServerTab extends Tab {
|
export default class ServerTab extends Tab {
|
||||||
|
$el: Element;
|
||||||
$badge: Element;
|
$badge: Element;
|
||||||
|
|
||||||
constructor(props: TabProps) {
|
constructor(props: TabProps) {
|
||||||
@@ -17,7 +18,7 @@ export default class ServerTab extends Tab {
|
|||||||
this.$el = generateNodeFromHTML(this.templateHTML());
|
this.$el = generateNodeFromHTML(this.templateHTML());
|
||||||
this.props.$root.append(this.$el);
|
this.props.$root.append(this.$el);
|
||||||
this.registerListeners();
|
this.registerListeners();
|
||||||
this.$badge = this.$el.querySelector(".server-tab-badge");
|
this.$badge = this.$el.querySelector(".server-tab-badge")!;
|
||||||
}
|
}
|
||||||
|
|
||||||
templateHTML(): HTML {
|
templateHTML(): HTML {
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ export interface TabProps {
|
|||||||
onDestroy?: () => void;
|
onDestroy?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Tab {
|
export default abstract class Tab {
|
||||||
props: TabProps;
|
props: TabProps;
|
||||||
webview: WebView;
|
webview: WebView;
|
||||||
$el: Element;
|
abstract $el: Element;
|
||||||
|
|
||||||
constructor(props: TabProps) {
|
constructor(props: TabProps) {
|
||||||
this.props = props;
|
this.props = props;
|
||||||
this.webview = this.props.webview;
|
this.webview = this.props.webview;
|
||||||
@@ -26,8 +27,14 @@ export default class Tab {
|
|||||||
|
|
||||||
registerListeners(): void {
|
registerListeners(): void {
|
||||||
this.$el.addEventListener("click", this.props.onClick);
|
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 {
|
showNetworkError(): void {
|
||||||
@@ -46,6 +53,6 @@ export default class Tab {
|
|||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
this.$el.remove();
|
this.$el.remove();
|
||||||
this.webview.$el.remove();
|
this.webview.$el!.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ export default class WebView {
|
|||||||
zoomFactor: number;
|
zoomFactor: number;
|
||||||
badgeCount: number;
|
badgeCount: number;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
customCSS: string;
|
customCSS: string | null;
|
||||||
$webviewsContainer: DOMTokenList;
|
$webviewsContainer: DOMTokenList;
|
||||||
$el: Electron.WebviewTag;
|
$el?: Electron.WebviewTag;
|
||||||
domReady?: Promise<void>;
|
domReady?: Promise<void>;
|
||||||
|
|
||||||
constructor(props: WebViewProps) {
|
constructor(props: WebViewProps) {
|
||||||
@@ -48,7 +48,7 @@ export default class WebView {
|
|||||||
this.customCSS = ConfigUtil.getConfigItem("customCSS");
|
this.customCSS = ConfigUtil.getConfigItem("customCSS");
|
||||||
this.$webviewsContainer = document.querySelector(
|
this.$webviewsContainer = document.querySelector(
|
||||||
"#webviews-container",
|
"#webviews-container",
|
||||||
).classList;
|
)!.classList;
|
||||||
}
|
}
|
||||||
|
|
||||||
templateHTML(): HTML {
|
templateHTML(): HTML {
|
||||||
@@ -74,7 +74,7 @@ export default class WebView {
|
|||||||
init(): void {
|
init(): void {
|
||||||
this.$el = generateNodeFromHTML(this.templateHTML()) as Electron.WebviewTag;
|
this.$el = generateNodeFromHTML(this.templateHTML()) as Electron.WebviewTag;
|
||||||
this.domReady = new Promise((resolve) => {
|
this.domReady = new Promise((resolve) => {
|
||||||
this.$el.addEventListener(
|
this.$el!.addEventListener(
|
||||||
"dom-ready",
|
"dom-ready",
|
||||||
() => {
|
() => {
|
||||||
resolve();
|
resolve();
|
||||||
@@ -88,23 +88,23 @@ export default class WebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerListeners(): void {
|
registerListeners(): void {
|
||||||
this.$el.addEventListener("new-window", (event) => {
|
this.$el!.addEventListener("new-window", (event) => {
|
||||||
handleExternalLink.call(this, event);
|
handleExternalLink.call(this, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (shouldSilentWebview) {
|
if (shouldSilentWebview) {
|
||||||
this.$el.addEventListener("dom-ready", () => {
|
this.$el!.addEventListener("dom-ready", () => {
|
||||||
this.$el.setAudioMuted(true);
|
this.$el!.setAudioMuted(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$el.addEventListener("page-title-updated", (event) => {
|
this.$el!.addEventListener("page-title-updated", (event) => {
|
||||||
const {title} = event;
|
const {title} = event;
|
||||||
this.badgeCount = this.getBadgeCount(title);
|
this.badgeCount = this.getBadgeCount(title);
|
||||||
this.props.onTitleChange();
|
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");
|
const isSettingPage = event.url.includes("renderer/preference.html");
|
||||||
if (isSettingPage) {
|
if (isSettingPage) {
|
||||||
return;
|
return;
|
||||||
@@ -113,11 +113,11 @@ export default class WebView {
|
|||||||
this.canGoBackButton();
|
this.canGoBackButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$el.addEventListener("did-navigate", () => {
|
this.$el!.addEventListener("did-navigate", () => {
|
||||||
this.canGoBackButton();
|
this.canGoBackButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$el.addEventListener("page-favicon-updated", (event) => {
|
this.$el!.addEventListener("page-favicon-updated", (event) => {
|
||||||
const {favicons} = 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
|
// 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(
|
const webContents = remote.webContents.fromId(
|
||||||
this.$el.getWebContentsId(),
|
this.$el!.getWebContentsId(),
|
||||||
);
|
);
|
||||||
webContents.addListener("context-menu", (event, menuParameters) => {
|
webContents.addListener("context-menu", (event, menuParameters) => {
|
||||||
contextMenu(webContents, event, menuParameters);
|
contextMenu(webContents, event, menuParameters);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.props.role === "server") {
|
if (this.props.role === "server") {
|
||||||
this.$el.classList.add("onload");
|
this.$el!.classList.add("onload");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@@ -153,11 +153,11 @@ export default class WebView {
|
|||||||
|
|
||||||
// Refocus text boxes after reload
|
// Refocus text boxes after reload
|
||||||
// Remove when upstream issue https://github.com/electron/electron/issues/14474 is fixed
|
// Remove when upstream issue https://github.com/electron/electron/issues/14474 is fixed
|
||||||
this.$el.blur();
|
this.$el!.blur();
|
||||||
this.$el.focus();
|
this.$el!.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$el.addEventListener("did-fail-load", (event) => {
|
this.$el!.addEventListener("did-fail-load", (event) => {
|
||||||
const {errorDescription} = event;
|
const {errorDescription} = event;
|
||||||
const hasConnectivityError = SystemUtil.connectivityERR.includes(
|
const hasConnectivityError = SystemUtil.connectivityERR.includes(
|
||||||
errorDescription,
|
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");
|
const isSettingPage = this.props.url.includes("renderer/preference.html");
|
||||||
if (!isSettingPage) {
|
if (!isSettingPage) {
|
||||||
this.props.switchLoading(true, this.props.url);
|
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);
|
this.props.switchLoading(false, this.props.url);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ export default class WebView {
|
|||||||
|
|
||||||
showNotificationSettings(): void {
|
showNotificationSettings(): void {
|
||||||
ipcRenderer.sendTo(
|
ipcRenderer.sendTo(
|
||||||
this.$el.getWebContentsId(),
|
this.$el!.getWebContentsId(),
|
||||||
"show-notification-settings",
|
"show-notification-settings",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -207,18 +207,18 @@ export default class WebView {
|
|||||||
this.$webviewsContainer.add("loaded");
|
this.$webviewsContainer.add("loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$el.classList.remove("disabled");
|
this.$el!.classList.remove("disabled");
|
||||||
this.$el.classList.add("active");
|
this.$el!.classList.add("active");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.props.role === "server") {
|
if (this.props.role === "server") {
|
||||||
this.$el.classList.remove("onload");
|
this.$el!.classList.remove("onload");
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
this.focus();
|
this.focus();
|
||||||
this.props.onTitleChange();
|
this.props.onTitleChange();
|
||||||
// Injecting preload css in webview to override some css rules
|
// Injecting preload css in webview to override some css rules
|
||||||
(async () =>
|
(async () =>
|
||||||
this.$el.insertCSS(
|
this.$el!.insertCSS(
|
||||||
fs.readFileSync(path.join(__dirname, "/../../css/preload.css"), "utf8"),
|
fs.readFileSync(path.join(__dirname, "/../../css/preload.css"), "utf8"),
|
||||||
))();
|
))();
|
||||||
|
|
||||||
@@ -235,15 +235,15 @@ export default class WebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(async () =>
|
(async () =>
|
||||||
this.$el.insertCSS(
|
this.$el!.insertCSS(
|
||||||
fs.readFileSync(path.resolve(__dirname, this.customCSS), "utf8"),
|
fs.readFileSync(path.resolve(__dirname, this.customCSS!), "utf8"),
|
||||||
))();
|
))();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
focus(): void {
|
focus(): void {
|
||||||
// Focus Webview and it's contents when Window regain focus.
|
// 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
|
// HACK: webContents.isFocused() seems to be true even without the element
|
||||||
// being in focus. So, we check against `document.activeElement`.
|
// being in focus. So, we check against `document.activeElement`.
|
||||||
if (webContents && this.$el !== 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
|
// element to transfer focus correctly, in Electron v3.0.10
|
||||||
// See https://github.com/electron/electron/issues/15718
|
// See https://github.com/electron/electron/issues/15718
|
||||||
(document.activeElement as HTMLElement).blur();
|
(document.activeElement as HTMLElement).blur();
|
||||||
this.$el.focus();
|
this.$el!.focus();
|
||||||
webContents.focus();
|
webContents.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hide(): void {
|
hide(): void {
|
||||||
this.$el.classList.add("disabled");
|
this.$el!.classList.add("disabled");
|
||||||
this.$el.classList.remove("active");
|
this.$el!.classList.remove("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
load(): void {
|
load(): void {
|
||||||
@@ -271,34 +271,34 @@ export default class WebView {
|
|||||||
|
|
||||||
zoomIn(): void {
|
zoomIn(): void {
|
||||||
this.zoomFactor += 0.1;
|
this.zoomFactor += 0.1;
|
||||||
this.$el.setZoomFactor(this.zoomFactor);
|
this.$el!.setZoomFactor(this.zoomFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
zoomOut(): void {
|
zoomOut(): void {
|
||||||
this.zoomFactor -= 0.1;
|
this.zoomFactor -= 0.1;
|
||||||
this.$el.setZoomFactor(this.zoomFactor);
|
this.$el!.setZoomFactor(this.zoomFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
zoomActualSize(): void {
|
zoomActualSize(): void {
|
||||||
this.zoomFactor = 1;
|
this.zoomFactor = 1;
|
||||||
this.$el.setZoomFactor(this.zoomFactor);
|
this.$el!.setZoomFactor(this.zoomFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
logOut(): void {
|
logOut(): void {
|
||||||
ipcRenderer.sendTo(this.$el.getWebContentsId(), "logout");
|
ipcRenderer.sendTo(this.$el!.getWebContentsId(), "logout");
|
||||||
}
|
}
|
||||||
|
|
||||||
showKeyboardShortcuts(): void {
|
showKeyboardShortcuts(): void {
|
||||||
ipcRenderer.sendTo(this.$el.getWebContentsId(), "show-keyboard-shortcuts");
|
ipcRenderer.sendTo(this.$el!.getWebContentsId(), "show-keyboard-shortcuts");
|
||||||
}
|
}
|
||||||
|
|
||||||
openDevTools(): void {
|
openDevTools(): void {
|
||||||
this.$el.openDevTools();
|
this.$el!.openDevTools();
|
||||||
}
|
}
|
||||||
|
|
||||||
back(): void {
|
back(): void {
|
||||||
if (this.$el.canGoBack()) {
|
if (this.$el!.canGoBack()) {
|
||||||
this.$el.goBack();
|
this.$el!.goBack();
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,8 +306,8 @@ export default class WebView {
|
|||||||
canGoBackButton(): void {
|
canGoBackButton(): void {
|
||||||
const $backButton = document.querySelector(
|
const $backButton = document.querySelector(
|
||||||
"#actions-container #back-action",
|
"#actions-container #back-action",
|
||||||
);
|
)!;
|
||||||
if (this.$el.canGoBack()) {
|
if (this.$el!.canGoBack()) {
|
||||||
$backButton.classList.remove("disable");
|
$backButton.classList.remove("disable");
|
||||||
} else {
|
} else {
|
||||||
$backButton.classList.add("disable");
|
$backButton.classList.add("disable");
|
||||||
@@ -315,8 +315,8 @@ export default class WebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
forward(): void {
|
forward(): void {
|
||||||
if (this.$el.canGoForward()) {
|
if (this.$el!.canGoForward()) {
|
||||||
this.$el.goForward();
|
this.$el!.goForward();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ export default class WebView {
|
|||||||
this.$webviewsContainer.remove("loaded");
|
this.$webviewsContainer.remove("loaded");
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.props.switchLoading(true, this.props.url);
|
this.props.switchLoading(true, this.props.url);
|
||||||
this.$el.reload();
|
this.$el!.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
forceLoad(): void {
|
forceLoad(): void {
|
||||||
@@ -335,6 +335,6 @@ export default class WebView {
|
|||||||
|
|
||||||
async send(channel: string, ...parameters: unknown[]): Promise<void> {
|
async send(channel: string, ...parameters: unknown[]): Promise<void> {
|
||||||
await this.domReady;
|
await this.domReady;
|
||||||
await this.$el.send(channel, ...parameters);
|
await this.$el!.send(channel, ...parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ const {app} = remote;
|
|||||||
customElements.define("send-feedback", SendFeedback);
|
customElements.define("send-feedback", SendFeedback);
|
||||||
export const sendFeedback: SendFeedback = document.querySelector(
|
export const sendFeedback: SendFeedback = document.querySelector(
|
||||||
"send-feedback",
|
"send-feedback",
|
||||||
);
|
)!;
|
||||||
export const feedbackHolder = sendFeedback.parentElement;
|
export const feedbackHolder = sendFeedback.parentElement!;
|
||||||
|
|
||||||
// Make the button color match zulip app's theme
|
// Make the button color match zulip app's theme
|
||||||
sendFeedback.customStylesheet = "css/feedback.css";
|
sendFeedback.customStylesheet = "css/feedback.css";
|
||||||
|
|||||||
@@ -86,21 +86,25 @@ class ServerManagerView {
|
|||||||
tabIndex: number;
|
tabIndex: number;
|
||||||
presetOrgs: string[];
|
presetOrgs: string[];
|
||||||
constructor() {
|
constructor() {
|
||||||
this.$addServerButton = document.querySelector("#add-tab");
|
this.$addServerButton = document.querySelector("#add-tab")!;
|
||||||
this.$tabsContainer = document.querySelector("#tabs-container");
|
this.$tabsContainer = document.querySelector("#tabs-container")!;
|
||||||
|
|
||||||
const $actionsContainer = document.querySelector("#actions-container");
|
const $actionsContainer = document.querySelector("#actions-container")!;
|
||||||
this.$reloadButton = $actionsContainer.querySelector("#reload-action");
|
this.$reloadButton = $actionsContainer.querySelector("#reload-action")!;
|
||||||
this.$loadingIndicator = $actionsContainer.querySelector("#loading-action");
|
this.$loadingIndicator = $actionsContainer.querySelector(
|
||||||
this.$settingsButton = $actionsContainer.querySelector("#settings-action");
|
"#loading-action",
|
||||||
this.$webviewsContainer = document.querySelector("#webviews-container");
|
)!;
|
||||||
this.$backButton = $actionsContainer.querySelector("#back-action");
|
this.$settingsButton = $actionsContainer.querySelector("#settings-action")!;
|
||||||
this.$dndButton = $actionsContainer.querySelector("#dnd-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.$addServerTooltip = document.querySelector("#add-server-tooltip")!;
|
||||||
this.$reloadTooltip = $actionsContainer.querySelector("#reload-tooltip");
|
this.$reloadTooltip = $actionsContainer.querySelector("#reload-tooltip")!;
|
||||||
this.$loadingTooltip = $actionsContainer.querySelector("#loading-tooltip");
|
this.$loadingTooltip = $actionsContainer.querySelector("#loading-tooltip")!;
|
||||||
this.$settingsTooltip = $actionsContainer.querySelector("#setting-tooltip");
|
this.$settingsTooltip = $actionsContainer.querySelector(
|
||||||
|
"#setting-tooltip",
|
||||||
|
)!;
|
||||||
|
|
||||||
// TODO: This should have been querySelector but the problem is that
|
// TODO: This should have been querySelector but the problem is that
|
||||||
// querySelector doesn't return elements not present in dom whereas somehow
|
// querySelector doesn't return elements not present in dom whereas somehow
|
||||||
@@ -110,12 +114,12 @@ class ServerManagerView {
|
|||||||
this.$serverIconTooltip = document.getElementsByClassName(
|
this.$serverIconTooltip = document.getElementsByClassName(
|
||||||
"server-tooltip",
|
"server-tooltip",
|
||||||
) as HTMLCollectionOf<HTMLElement>;
|
) as HTMLCollectionOf<HTMLElement>;
|
||||||
this.$backTooltip = $actionsContainer.querySelector("#back-tooltip");
|
this.$backTooltip = $actionsContainer.querySelector("#back-tooltip")!;
|
||||||
this.$dndTooltip = $actionsContainer.querySelector("#dnd-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.$fullscreenEscapeKey = process.platform === "darwin" ? "^⌘F" : "F11";
|
||||||
this.$fullscreenPopup.textContent = `Press ${this.$fullscreenEscapeKey} to exit full screen`;
|
this.$fullscreenPopup.textContent = `Press ${this.$fullscreenEscapeKey} to exit full screen`;
|
||||||
|
|
||||||
@@ -486,12 +490,12 @@ class ServerManagerView {
|
|||||||
// error
|
// error
|
||||||
|
|
||||||
const $altIcon = document.createElement("div");
|
const $altIcon = document.createElement("div");
|
||||||
const $parent = $img.parentElement;
|
const $parent = $img.parentElement!;
|
||||||
const $container = $parent.parentElement;
|
const $container = $parent.parentElement!;
|
||||||
const webviewId = $container.dataset.tabId;
|
const webviewId = $container.dataset.tabId!;
|
||||||
const $webview = document.querySelector(
|
const $webview = document.querySelector(
|
||||||
`webview[data-tab-id="${CSS.escape(webviewId)}"]`,
|
`webview[data-tab-id="${CSS.escape(webviewId)}"]`,
|
||||||
);
|
)!;
|
||||||
const realmName = $webview.getAttribute("name");
|
const realmName = $webview.getAttribute("name");
|
||||||
|
|
||||||
if (realmName === null) {
|
if (realmName === null) {
|
||||||
@@ -539,7 +543,7 @@ class ServerManagerView {
|
|||||||
// as that of its parent element.
|
// as that of its parent element.
|
||||||
const {top} = this.$serverIconTooltip[
|
const {top} = this.$serverIconTooltip[
|
||||||
index
|
index
|
||||||
].parentElement.getBoundingClientRect();
|
].parentElement!.getBoundingClientRect();
|
||||||
this.$serverIconTooltip[index].style.top = `${top}px`;
|
this.$serverIconTooltip[index].style.top = `${top}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,7 +553,7 @@ class ServerManagerView {
|
|||||||
|
|
||||||
openFunctionalTab(tabProps: FunctionalTabProps): void {
|
openFunctionalTab(tabProps: FunctionalTabProps): void {
|
||||||
if (this.functionalTabs.has(tabProps.name)) {
|
if (this.functionalTabs.has(tabProps.name)) {
|
||||||
this.activateTab(this.functionalTabs.get(tabProps.name));
|
this.activateTab(this.functionalTabs.get(tabProps.name)!);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,20 +567,20 @@ class ServerManagerView {
|
|||||||
materialIcon: tabProps.materialIcon,
|
materialIcon: tabProps.materialIcon,
|
||||||
name: tabProps.name,
|
name: tabProps.name,
|
||||||
$root: this.$tabsContainer,
|
$root: this.$tabsContainer,
|
||||||
index: this.functionalTabs.get(tabProps.name),
|
index: this.functionalTabs.get(tabProps.name)!,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
onClick: this.activateTab.bind(
|
onClick: this.activateTab.bind(
|
||||||
this,
|
this,
|
||||||
this.functionalTabs.get(tabProps.name),
|
this.functionalTabs.get(tabProps.name)!,
|
||||||
),
|
),
|
||||||
onDestroy: this.destroyTab.bind(
|
onDestroy: this.destroyTab.bind(
|
||||||
this,
|
this,
|
||||||
tabProps.name,
|
tabProps.name,
|
||||||
this.functionalTabs.get(tabProps.name),
|
this.functionalTabs.get(tabProps.name)!,
|
||||||
),
|
),
|
||||||
webview: new WebView({
|
webview: new WebView({
|
||||||
$root: this.$webviewsContainer,
|
$root: this.$webviewsContainer,
|
||||||
index: this.functionalTabs.get(tabProps.name),
|
index: this.functionalTabs.get(tabProps.name)!,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
url: tabProps.url,
|
url: tabProps.url,
|
||||||
role: "function",
|
role: "function",
|
||||||
@@ -610,7 +614,7 @@ class ServerManagerView {
|
|||||||
// closed when the functional tab DOM is ready, handled in webview.js
|
// closed when the functional tab DOM is ready, handled in webview.js
|
||||||
this.$webviewsContainer.classList.remove("loaded");
|
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> {
|
async openSettings(nav: NavItem = "General"): Promise<void> {
|
||||||
@@ -620,7 +624,7 @@ class ServerManagerView {
|
|||||||
url: `file://${rendererDirectory}/preference.html#${nav}`,
|
url: `file://${rendererDirectory}/preference.html#${nav}`,
|
||||||
});
|
});
|
||||||
this.$settingsButton.classList.add("active");
|
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",
|
"switch-settings-nav",
|
||||||
nav,
|
nav,
|
||||||
);
|
);
|
||||||
@@ -798,19 +802,19 @@ class ServerManagerView {
|
|||||||
toggleDNDButton(alert: boolean): void {
|
toggleDNDButton(alert: boolean): void {
|
||||||
this.$dndTooltip.textContent =
|
this.$dndTooltip.textContent =
|
||||||
(alert ? "Disable" : "Enable") + " Do Not Disturb";
|
(alert ? "Disable" : "Enable") + " Do Not Disturb";
|
||||||
this.$dndButton.querySelector("i").textContent = alert
|
this.$dndButton.querySelector("i")!.textContent = alert
|
||||||
? "notifications_off"
|
? "notifications_off"
|
||||||
: "notifications";
|
: "notifications";
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoggedIn(tabIndex: number): boolean {
|
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);
|
return !(url.endsWith("/login/") || this.tabs[tabIndex].webview.loading);
|
||||||
}
|
}
|
||||||
|
|
||||||
getActiveWebview(): Electron.WebviewTag {
|
getActiveWebview(): Electron.WebviewTag {
|
||||||
const selector = "webview:not(.disabled)";
|
const selector = "webview:not(.disabled)";
|
||||||
const webview: Electron.WebviewTag = document.querySelector(selector);
|
const webview: Electron.WebviewTag = document.querySelector(selector)!;
|
||||||
return webview;
|
return webview;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,7 +958,7 @@ class ServerManagerView {
|
|||||||
: this.tabs.some(
|
: this.tabs.some(
|
||||||
({webview}) =>
|
({webview}) =>
|
||||||
!webview.loading &&
|
!webview.loading &&
|
||||||
webview.$el.getWebContentsId() === webContentsId &&
|
webview.$el!.getWebContentsId() === webContentsId &&
|
||||||
webview.props.hasPermission?.(origin, permission),
|
webview.props.hasPermission?.(origin, permission),
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
@@ -1132,10 +1136,10 @@ class ServerManagerView {
|
|||||||
);
|
);
|
||||||
for (const webview of webviews) {
|
for (const webview of webviews) {
|
||||||
const currentId = webview.getWebContentsId();
|
const currentId = webview.getWebContentsId();
|
||||||
const tabId = webview.getAttribute("data-tab-id");
|
const tabId = webview.getAttribute("data-tab-id")!;
|
||||||
const concurrentTab: HTMLButtonElement = document.querySelector(
|
const concurrentTab: HTMLButtonElement = document.querySelector(
|
||||||
`div[data-tab-id="${CSS.escape(tabId)}"]`,
|
`div[data-tab-id="${CSS.escape(tabId)}"]`,
|
||||||
);
|
)!;
|
||||||
if (currentId === webviewId) {
|
if (currentId === webviewId) {
|
||||||
concurrentTab.click();
|
concurrentTab.click();
|
||||||
}
|
}
|
||||||
@@ -1152,7 +1156,7 @@ class ServerManagerView {
|
|||||||
canvas.height = 128;
|
canvas.height = 128;
|
||||||
canvas.width = 128;
|
canvas.width = 128;
|
||||||
canvas.style.letterSpacing = "-5px";
|
canvas.style.letterSpacing = "-5px";
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d")!;
|
||||||
ctx.fillStyle = "#f42020";
|
ctx.fillStyle = "#f42020";
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.ellipse(64, 64, 64, 64, 0, 0, 2 * Math.PI);
|
ctx.ellipse(64, 64, 64, 64, 0, 0, 2 * Math.PI);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default class PreferenceNav {
|
|||||||
|
|
||||||
registerListeners(): void {
|
registerListeners(): void {
|
||||||
for (const navItem of this.navItems) {
|
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", () => {
|
$item.addEventListener("click", () => {
|
||||||
this.props.onItemSelected(navItem);
|
this.props.onItemSelected(navItem);
|
||||||
});
|
});
|
||||||
@@ -71,12 +71,12 @@ export default class PreferenceNav {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activate(navItem: NavItem): void {
|
activate(navItem: NavItem): void {
|
||||||
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`);
|
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`)!;
|
||||||
$item.classList.add("active");
|
$item.classList.add("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivate(navItem: NavItem): void {
|
deactivate(navItem: NavItem): void {
|
||||||
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`);
|
const $item = document.querySelector(`#nav-${CSS.escape(navItem)}`)!;
|
||||||
$item.classList.remove("active");
|
$item.classList.remove("active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ ipcRenderer.on("logout", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the menu for the below
|
// Create the menu for the below
|
||||||
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle");
|
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle")!;
|
||||||
dropdown.click();
|
dropdown.click();
|
||||||
|
|
||||||
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll(
|
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll(
|
||||||
@@ -29,13 +29,13 @@ ipcRenderer.on("show-keyboard-shortcuts", () => {
|
|||||||
// Create the menu for the below
|
// Create the menu for the below
|
||||||
const node: HTMLElement = document.querySelector(
|
const node: HTMLElement = document.querySelector(
|
||||||
"a[data-overlay-trigger=keyboard-shortcuts]",
|
"a[data-overlay-trigger=keyboard-shortcuts]",
|
||||||
);
|
)!;
|
||||||
// Additional check
|
// Additional check
|
||||||
if (node.textContent.trim().toLowerCase() === "keyboard shortcuts (?)") {
|
if (node.textContent!.trim().toLowerCase() === "keyboard shortcuts (?)") {
|
||||||
node.click();
|
node.click();
|
||||||
} else {
|
} else {
|
||||||
// Atleast click the dropdown
|
// Atleast click the dropdown
|
||||||
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle");
|
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle")!;
|
||||||
dropdown.click();
|
dropdown.click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -46,7 +46,7 @@ ipcRenderer.on("show-notification-settings", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the menu for the below
|
// Create the menu for the below
|
||||||
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle");
|
const dropdown: HTMLElement = document.querySelector(".dropdown-toggle")!;
|
||||||
dropdown.click();
|
dropdown.click();
|
||||||
|
|
||||||
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll(
|
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll(
|
||||||
@@ -69,8 +69,8 @@ window.addEventListener("load", (event: any): void => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const $reconnectButton = document.querySelector("#reconnect");
|
const $reconnectButton = document.querySelector("#reconnect")!;
|
||||||
const $settingsButton = document.querySelector("#settings");
|
const $settingsButton = document.querySelector("#settings")!;
|
||||||
NetworkError.init($reconnectButton, $settingsButton);
|
NetworkError.init($reconnectButton, $settingsButton);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import * as ConfigUtil from "../../common/config-util";
|
|||||||
|
|
||||||
const {Tray, Menu, nativeImage, BrowserWindow} = remote;
|
const {Tray, Menu, nativeImage, BrowserWindow} = remote;
|
||||||
|
|
||||||
let tray: Electron.Tray;
|
let tray: Electron.Tray | null = null;
|
||||||
|
|
||||||
const ICON_DIR = "../../resources/tray";
|
const ICON_DIR = "../../resources/tray";
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ const renderCanvas = function (arg: number): HTMLCanvasElement {
|
|||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
canvas.width = SIZE;
|
canvas.width = SIZE;
|
||||||
canvas.height = SIZE;
|
canvas.height = SIZE;
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d")!;
|
||||||
|
|
||||||
// Circle
|
// Circle
|
||||||
// If (!config.thick || config.thick && HAS_COUNT) {
|
// If (!config.thick || config.thick && HAS_COUNT) {
|
||||||
@@ -210,15 +210,15 @@ function toggleTray(): void {
|
|||||||
createTray();
|
createTray();
|
||||||
if (process.platform === "linux" || process.platform === "win32") {
|
if (process.platform === "linux" || process.platform === "win32") {
|
||||||
const image = renderNativeImage(unread);
|
const image = renderNativeImage(unread);
|
||||||
tray.setImage(image);
|
tray!.setImage(image);
|
||||||
tray.setToolTip(`${unread} unread messages`);
|
tray!.setToolTip(`${unread} unread messages`);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigUtil.setConfigItem("trayIcon", true);
|
ConfigUtil.setConfigItem("trayIcon", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const selector = "webview:not([class*=disabled])";
|
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());
|
const webContents = remote.webContents.fromId(webview.getWebContentsId());
|
||||||
webContents.send("toggletray", state);
|
webContents.send("toggletray", state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const logger = new Logger({
|
|||||||
|
|
||||||
const defaultIconUrl = "../renderer/img/icon.png";
|
const defaultIconUrl = "../renderer/img/icon.png";
|
||||||
|
|
||||||
let db: JsonDB;
|
let db!: JsonDB;
|
||||||
|
|
||||||
reloadDB();
|
reloadDB();
|
||||||
// Migrate from old schema
|
// Migrate from old schema
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
/* Strict type-checking */
|
/* Strict type-checking */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"strictNullChecks": false,
|
|
||||||
"noImplicitThis": true,
|
"noImplicitThis": true,
|
||||||
"alwaysStrict": true,
|
"alwaysStrict": true,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user