mirror of
https://github.com/CringeStudios/element-desktop.git
synced 2025-01-18 23:44:59 +01:00
Enable Typescript strict mode (#426)
This commit is contained in:
parent
d0c7e3e24b
commit
d0e1596bf2
@ -30,8 +30,9 @@ module.exports = {
|
|||||||
"prefer-promise-reject-errors": "off",
|
"prefer-promise-reject-errors": "off",
|
||||||
"quotes": "off",
|
"quotes": "off",
|
||||||
|
|
||||||
// We disable this while we're transitioning
|
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
// We're okay with assertion errors when we ask for them
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
|
12
src/ipc.ts
12
src/ipc.ts
@ -46,7 +46,7 @@ ipcMain.on('loudNotification', function(): void {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let powerSaveBlockerId: number = null;
|
let powerSaveBlockerId: number | null = null;
|
||||||
ipcMain.on('app_onAction', function(_ev: IpcMainEvent, payload) {
|
ipcMain.on('app_onAction', function(_ev: IpcMainEvent, payload) {
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
case 'call_state': {
|
case 'call_state': {
|
||||||
@ -147,11 +147,11 @@ ipcMain.on('ipcCall', async function(_ev: IpcMainEvent, payload) {
|
|||||||
|
|
||||||
case 'getPickleKey':
|
case 'getPickleKey':
|
||||||
try {
|
try {
|
||||||
ret = await keytar.getPassword("element.io", `${args[0]}|${args[1]}`);
|
ret = await keytar?.getPassword("element.io", `${args[0]}|${args[1]}`);
|
||||||
// migrate from riot.im (remove once we think there will no longer be
|
// migrate from riot.im (remove once we think there will no longer be
|
||||||
// logins from the time of riot.im)
|
// logins from the time of riot.im)
|
||||||
if (ret === null) {
|
if (ret === null) {
|
||||||
ret = await keytar.getPassword("riot.im", `${args[0]}|${args[1]}`);
|
ret = await keytar?.getPassword("riot.im", `${args[0]}|${args[1]}`);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// if an error is thrown (e.g. keytar can't connect to the keychain),
|
// if an error is thrown (e.g. keytar can't connect to the keychain),
|
||||||
@ -163,7 +163,7 @@ ipcMain.on('ipcCall', async function(_ev: IpcMainEvent, payload) {
|
|||||||
case 'createPickleKey':
|
case 'createPickleKey':
|
||||||
try {
|
try {
|
||||||
const pickleKey = await randomArray(32);
|
const pickleKey = await randomArray(32);
|
||||||
await keytar.setPassword("element.io", `${args[0]}|${args[1]}`, pickleKey);
|
await keytar?.setPassword("element.io", `${args[0]}|${args[1]}`, pickleKey);
|
||||||
ret = pickleKey;
|
ret = pickleKey;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ret = null;
|
ret = null;
|
||||||
@ -172,10 +172,10 @@ ipcMain.on('ipcCall', async function(_ev: IpcMainEvent, payload) {
|
|||||||
|
|
||||||
case 'destroyPickleKey':
|
case 'destroyPickleKey':
|
||||||
try {
|
try {
|
||||||
await keytar.deletePassword("element.io", `${args[0]}|${args[1]}`);
|
await keytar?.deletePassword("element.io", `${args[0]}|${args[1]}`);
|
||||||
// migrate from riot.im (remove once we think there will no longer be
|
// migrate from riot.im (remove once we think there will no longer be
|
||||||
// logins from the time of riot.im)
|
// logins from the time of riot.im)
|
||||||
await keytar.deletePassword("riot.im", `${args[0]}|${args[1]}`);
|
await keytar?.deletePassword("riot.im", `${args[0]}|${args[1]}`);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
break;
|
break;
|
||||||
case 'getDesktopCapturerSources':
|
case 'getDesktopCapturerSources':
|
||||||
|
@ -21,7 +21,7 @@ try {
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
keytar = require('keytar');
|
keytar = require('keytar');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code === "MODULE_NOT_FOUND") {
|
if ((<NodeJS.ErrnoException>e).code === "MODULE_NOT_FOUND") {
|
||||||
console.log("Keytar isn't installed; secure key storage is disabled.");
|
console.log("Keytar isn't installed; secure key storage is disabled.");
|
||||||
} else {
|
} else {
|
||||||
console.warn("Keytar unexpected error:", e);
|
console.warn("Keytar unexpected error:", e);
|
||||||
|
@ -27,7 +27,7 @@ export function _td(text: string): string {
|
|||||||
type SubstitutionValue = number | string;
|
type SubstitutionValue = number | string;
|
||||||
|
|
||||||
interface IVariables {
|
interface IVariables {
|
||||||
[key: string]: SubstitutionValue;
|
[key: string]: SubstitutionValue | undefined;
|
||||||
count?: number;
|
count?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,13 +66,13 @@ export function _t(text: string, variables: IVariables = {}): string {
|
|||||||
|
|
||||||
type Component = () => void;
|
type Component = () => void;
|
||||||
|
|
||||||
type TypedStore = Store<{ locale?: string | string[] }>;
|
type TypedStore = Store<{ locale?: string[] }>;
|
||||||
|
|
||||||
export class AppLocalization {
|
export class AppLocalization {
|
||||||
private static readonly STORE_KEY = "locale";
|
private static readonly STORE_KEY = "locale";
|
||||||
|
|
||||||
private readonly store: TypedStore;
|
private readonly store: TypedStore;
|
||||||
private readonly localizedComponents: Set<Component>;
|
private readonly localizedComponents?: Set<Component>;
|
||||||
|
|
||||||
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
|
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
|
||||||
counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN"));
|
counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN"));
|
||||||
@ -86,7 +86,8 @@ export class AppLocalization {
|
|||||||
this.store = store;
|
this.store = store;
|
||||||
if (this.store.has(AppLocalization.STORE_KEY)) {
|
if (this.store.has(AppLocalization.STORE_KEY)) {
|
||||||
const locales = this.store.get(AppLocalization.STORE_KEY);
|
const locales = this.store.get(AppLocalization.STORE_KEY);
|
||||||
this.setAppLocale(locales);
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
this.setAppLocale(locales!);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resetLocalizedUI();
|
this.resetLocalizedUI();
|
||||||
@ -110,7 +111,7 @@ export class AppLocalization {
|
|||||||
return require(`./i18n/strings/${this.denormalize(locale)}.json`);
|
return require(`./i18n/strings/${this.denormalize(locale)}.json`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`Could not fetch translation json for locale: '${locale}'`, e);
|
console.log(`Could not fetch translation json for locale: '${locale}'`, e);
|
||||||
return null;
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ export class AppLocalization {
|
|||||||
|
|
||||||
public resetLocalizedUI(): void {
|
public resetLocalizedUI(): void {
|
||||||
console.log("Resetting the UI components after locale change");
|
console.log("Resetting the UI components after locale change");
|
||||||
this.localizedComponents.forEach(componentSetup => {
|
this.localizedComponents?.forEach(componentSetup => {
|
||||||
if (typeof componentSetup === "function") {
|
if (typeof componentSetup === "function") {
|
||||||
componentSetup();
|
componentSetup();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ export function getProfileFromDeeplink(args: string[]): string | undefined {
|
|||||||
if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
|
if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
|
||||||
const parsedUrl = new URL(deeplinkUrl);
|
const parsedUrl = new URL(deeplinkUrl);
|
||||||
if (parsedUrl.protocol === PROTOCOL) {
|
if (parsedUrl.protocol === PROTOCOL) {
|
||||||
const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM);
|
const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM)!;
|
||||||
const store = readStore();
|
const store = readStore();
|
||||||
console.log("Forwarding to profile: ", store[ssoID]);
|
console.log("Forwarding to profile: ", store[ssoID]);
|
||||||
return store[ssoID];
|
return store[ssoID];
|
||||||
|
@ -40,7 +40,7 @@ try {
|
|||||||
ReindexError = seshatModule.ReindexError;
|
ReindexError = seshatModule.ReindexError;
|
||||||
seshatSupported = true;
|
seshatSupported = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.code === "MODULE_NOT_FOUND") {
|
if ((<NodeJS.ErrnoException>e).code === "MODULE_NOT_FOUND") {
|
||||||
console.log("Seshat isn't installed, event indexing is disabled.");
|
console.log("Seshat isn't installed, event indexing is disabled.");
|
||||||
} else {
|
} else {
|
||||||
console.warn("Seshat unexpected error:", e);
|
console.warn("Seshat unexpected error:", e);
|
||||||
@ -49,7 +49,7 @@ try {
|
|||||||
|
|
||||||
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
|
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
|
||||||
|
|
||||||
let eventIndex: SeshatType = null;
|
let eventIndex: SeshatType | null = null;
|
||||||
|
|
||||||
const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE";
|
const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE";
|
||||||
async function getOrCreatePassphrase(key: string): Promise<string> {
|
async function getOrCreatePassphrase(key: string): Promise<string> {
|
||||||
@ -66,9 +66,8 @@ async function getOrCreatePassphrase(key: string): Promise<string> {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error getting the event index passphrase out of the secret store", e);
|
console.log("Error getting the event index passphrase out of the secret store", e);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return seshatDefaultPassphrase;
|
|
||||||
}
|
}
|
||||||
|
return seshatDefaultPassphrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteContents = async (p: string): Promise<void> => {
|
const deleteContents = async (p: string): Promise<void> => {
|
||||||
@ -180,7 +179,7 @@ ipcMain.on('seshat', async function(_ev: IpcMainEvent, payload): Promise<void> {
|
|||||||
|
|
||||||
case 'addEventToIndex':
|
case 'addEventToIndex':
|
||||||
try {
|
try {
|
||||||
eventIndex.addEvent(args[0], args[1]);
|
eventIndex?.addEvent(args[0], args[1]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sendError(payload.id, e);
|
sendError(payload.id, e);
|
||||||
return;
|
return;
|
||||||
@ -189,7 +188,7 @@ ipcMain.on('seshat', async function(_ev: IpcMainEvent, payload): Promise<void> {
|
|||||||
|
|
||||||
case 'deleteEvent':
|
case 'deleteEvent':
|
||||||
try {
|
try {
|
||||||
ret = await eventIndex.deleteEvent(args[0]);
|
ret = await eventIndex?.deleteEvent(args[0]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sendError(payload.id, e);
|
sendError(payload.id, e);
|
||||||
return;
|
return;
|
||||||
@ -198,7 +197,7 @@ ipcMain.on('seshat', async function(_ev: IpcMainEvent, payload): Promise<void> {
|
|||||||
|
|
||||||
case 'commitLiveEvents':
|
case 'commitLiveEvents':
|
||||||
try {
|
try {
|
||||||
ret = await eventIndex.commit();
|
ret = await eventIndex?.commit();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sendError(payload.id, e);
|
sendError(payload.id, e);
|
||||||
return;
|
return;
|
||||||
@ -207,7 +206,7 @@ ipcMain.on('seshat', async function(_ev: IpcMainEvent, payload): Promise<void> {
|
|||||||
|
|
||||||
case 'searchEventIndex':
|
case 'searchEventIndex':
|
||||||
try {
|
try {
|
||||||
ret = await eventIndex.search(args[0]);
|
ret = await eventIndex?.search(args[0]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sendError(payload.id, e);
|
sendError(payload.id, e);
|
||||||
return;
|
return;
|
||||||
|
@ -22,7 +22,7 @@ import fs from "fs";
|
|||||||
|
|
||||||
import { _t } from "./language-helper";
|
import { _t } from "./language-helper";
|
||||||
|
|
||||||
let trayIcon: Tray = null;
|
let trayIcon: Tray | null = null;
|
||||||
|
|
||||||
export function hasTray(): boolean {
|
export function hasTray(): boolean {
|
||||||
return (trayIcon !== null);
|
return (trayIcon !== null);
|
||||||
@ -65,7 +65,7 @@ export function create(config: IConfig): void {
|
|||||||
if (!favicons || favicons.length <= 0 || !favicons[0].startsWith('data:')) {
|
if (!favicons || favicons.length <= 0 || !favicons[0].startsWith('data:')) {
|
||||||
if (lastFavicon !== null) {
|
if (lastFavicon !== null) {
|
||||||
global.mainWindow.setIcon(defaultIcon);
|
global.mainWindow.setIcon(defaultIcon);
|
||||||
trayIcon.setImage(defaultIcon);
|
trayIcon?.setImage(defaultIcon);
|
||||||
lastFavicon = null;
|
lastFavicon = null;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -88,12 +88,12 @@ export function create(config: IConfig): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trayIcon.setImage(newFavicon);
|
trayIcon?.setImage(newFavicon);
|
||||||
global.mainWindow.setIcon(newFavicon);
|
global.mainWindow.setIcon(newFavicon);
|
||||||
});
|
});
|
||||||
|
|
||||||
global.mainWindow.webContents.on('page-title-updated', function(ev, title) {
|
global.mainWindow.webContents.on('page-title-updated', function(ev, title) {
|
||||||
trayIcon.setToolTip(title);
|
trayIcon?.setToolTip(title);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ export function start(updateBaseUrl: string): void {
|
|||||||
// I'm not even going to try to guess which feed style they'd use if they
|
// I'm not even going to try to guess which feed style they'd use if they
|
||||||
// implemented it on Linux, or if it would be different again.
|
// implemented it on Linux, or if it would be different again.
|
||||||
console.log('Auto update not supported on this platform');
|
console.log('Auto update not supported on this platform');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
|
@ -50,7 +50,7 @@ function safeOpenURL(target: string): void {
|
|||||||
// (for instance, open /bin/sh does indeed open a terminal
|
// (for instance, open /bin/sh does indeed open a terminal
|
||||||
// with a shell, albeit with no arguments)
|
// with a shell, albeit with no arguments)
|
||||||
const parsedUrl = url.parse(target);
|
const parsedUrl = url.parse(target);
|
||||||
if (PERMITTED_URL_SCHEMES.indexOf(parsedUrl.protocol) > -1) {
|
if (PERMITTED_URL_SCHEMES.includes(parsedUrl.protocol!)) {
|
||||||
// explicitly use the URL re-assembled by the url library,
|
// explicitly use the URL re-assembled by the url library,
|
||||||
// so we know the url parser has understood all the parts
|
// so we know the url parser has understood all the parts
|
||||||
// of the input string
|
// of the input string
|
||||||
@ -69,7 +69,7 @@ function onWindowOrNavigate(ev: Event, target: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function writeNativeImage(filePath: string, img: NativeImage): Promise<void> {
|
function writeNativeImage(filePath: string, img: NativeImage): Promise<void> {
|
||||||
switch (filePath.split('.').pop().toLowerCase()) {
|
switch (filePath.split('.').pop()?.toLowerCase()) {
|
||||||
case "jpg":
|
case "jpg":
|
||||||
case "jpeg":
|
case "jpeg":
|
||||||
return fs.promises.writeFile(filePath, img.toJPEG(100));
|
return fs.promises.writeFile(filePath, img.toJPEG(100));
|
||||||
@ -181,7 +181,7 @@ function cutCopyPasteSelectContextMenus(params: ContextMenuParams): MenuItemCons
|
|||||||
options.push({
|
options.push({
|
||||||
label: word,
|
label: word,
|
||||||
click: (menuItem, browserWindow) => {
|
click: (menuItem, browserWindow) => {
|
||||||
browserWindow.webContents.replaceMisspelling(word);
|
browserWindow?.webContents.replaceMisspelling(word);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -190,7 +190,7 @@ function cutCopyPasteSelectContextMenus(params: ContextMenuParams): MenuItemCons
|
|||||||
}, {
|
}, {
|
||||||
label: _t('Add to dictionary'),
|
label: _t('Add to dictionary'),
|
||||||
click: (menuItem, browserWindow) => {
|
click: (menuItem, browserWindow) => {
|
||||||
browserWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord);
|
browserWindow?.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord);
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
type: 'separator',
|
type: 'separator',
|
||||||
@ -251,8 +251,9 @@ function onEditableContextMenu(ev: Event, params: ContextMenuParams) {
|
|||||||
let userDownloadIndex = 0;
|
let userDownloadIndex = 0;
|
||||||
const userDownloadMap = new Map<number, string>(); // Map from id to path
|
const userDownloadMap = new Map<number, string>(); // Map from id to path
|
||||||
ipcMain.on('userDownloadAction', function(ev: IpcMainEvent, { id, open = false }) {
|
ipcMain.on('userDownloadAction', function(ev: IpcMainEvent, { id, open = false }) {
|
||||||
if (open) {
|
const path = userDownloadMap.get(id);
|
||||||
shell.openPath(userDownloadMap.get(id));
|
if (open && path) {
|
||||||
|
shell.openPath(path);
|
||||||
}
|
}
|
||||||
userDownloadMap.delete(id);
|
userDownloadMap.delete(id);
|
||||||
});
|
});
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"dom"
|
"dom"
|
||||||
],
|
],
|
||||||
"types": ["jest", "node"],
|
"types": ["jest", "node"],
|
||||||
|
"strict": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src/**/*.ts",
|
"./src/**/*.ts",
|
||||||
|
Loading…
Reference in New Issue
Block a user