ESLint Migration

This commit is contained in:
Sidney Keese 2020-09-03 07:59:24 -07:00 committed by Josh Perez
parent 315be542b8
commit 48df8ab3b1
13 changed files with 133 additions and 112 deletions

View file

@ -33,16 +33,10 @@ webpack.config.ts
# Temporarily ignored during TSLint transition # Temporarily ignored during TSLint transition
# JIRA: DESKTOP-304 # JIRA: DESKTOP-304
ts/*.ts ts/*.ts
ts/backbone/**
ts/build/**
ts/components/*.ts ts/components/*.ts
ts/components/*.tsx ts/components/*.tsx
ts/components/conversation/** ts/components/conversation/**
ts/components/stickers/** ts/components/stickers/**
ts/notifications/**
ts/protobuf/**
ts/scripts/**
ts/services/**
ts/shims/** ts/shims/**
ts/sql/** ts/sql/**
ts/state/** ts/state/**

View file

@ -1,48 +1,6 @@
// For reference: https://github.com/airbnb/javascript // For reference: https://github.com/airbnb/javascript
module.exports = { const rules = {
root: true,
settings: {
react: {
version: 'detect',
},
'import/core-modules': ['electron'],
},
extends: ['airbnb-base', 'prettier'],
plugins: ['mocha', 'more'],
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'airbnb-typescript-prettier',
],
},
{
files: ['**/*.stories.tsx'],
rules: {
'import/no-extraneous-dependencies': 'off',
'react/jsx-props-no-spreading': 'off',
},
},
],
rules: {
'comma-dangle': [ 'comma-dangle': [
'error', 'error',
{ {
@ -66,6 +24,9 @@ module.exports = {
// useful for unused or internal fields // useful for unused or internal fields
'no-underscore-dangle': 'off', 'no-underscore-dangle': 'off',
// useful for unused parameters
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
// though we have a logger, we still remap console to log to disk // though we have a logger, we still remap console to log to disk
'no-console': 'error', 'no-console': 'error',
@ -105,5 +66,53 @@ module.exports = {
ignoreUrls: true, ignoreUrls: true,
}, },
], ],
},
'import/prefer-default-export': 'off',
};
module.exports = {
root: true,
settings: {
react: {
version: 'detect',
},
'import/core-modules': ['electron'],
},
extends: ['airbnb-base', 'prettier'],
plugins: ['mocha', 'more'],
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'airbnb-typescript-prettier',
],
rules,
},
{
files: ['**/*.stories.tsx', 'ts/build/**'],
rules: {
...rules,
'import/no-extraneous-dependencies': 'off',
'react/jsx-props-no-spreading': 'off',
},
},
],
rules,
}; };

View file

@ -5,7 +5,6 @@ export const show = (element: HTMLElement): void => {
if (!container) { if (!container) {
throw new TypeError("'.lightbox-container' is required"); throw new TypeError("'.lightbox-container' is required");
} }
// tslint:disable-next-line:no-inner-html
container.innerHTML = ''; container.innerHTML = '';
container.style.display = 'block'; container.style.display = 'block';
container.appendChild(element); container.appendChild(element);
@ -18,7 +17,6 @@ export const hide = (): void => {
if (!container) { if (!container) {
return; return;
} }
// tslint:disable-next-line:no-inner-html
container.innerHTML = ''; container.innerHTML = '';
container.style.display = 'none'; container.style.display = 'none';
}; };

View file

@ -3,15 +3,13 @@ import { readdir as readdirCallback } from 'fs';
import pify from 'pify'; import pify from 'pify';
// tslint:disable-next-line no-implicit-dependencies
import { notarize } from 'electron-notarize'; import { notarize } from 'electron-notarize';
// @ts-ignore
import * as packageJson from '../../package.json'; import * as packageJson from '../../package.json';
const readdir = pify(readdirCallback); const readdir = pify(readdirCallback);
/* tslint:disable:no-console */ /* eslint-disable no-console */
go().catch(error => { go().catch(error => {
console.error(error.stack); console.error(error.stack);

2
ts/model-types.d.ts vendored
View file

@ -70,7 +70,7 @@ type ConversationAttributesType = {
version: number; version: number;
}; };
declare class ConversationModelType extends Backbone.Model< export declare class ConversationModelType extends Backbone.Model<
ConversationAttributesType ConversationAttributesType
> { > {
id: string; id: string;

View file

@ -1,11 +1,12 @@
/* tslint:disable no-console non-literal-fs-path */ /* eslint-disable no-console */
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import rimraf from 'rimraf'; import rimraf from 'rimraf';
import { execSync } from 'child_process'; import { execSync } from 'child_process';
import packageJSON from '../../package.json'; import packageJSON from '../../package.json';
export function zipMacOSRelease() { export function zipMacOSRelease(): void {
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
return; return;
} }

View file

@ -2,15 +2,11 @@ import { app, BrowserWindow, ipcMain } from 'electron';
let bounceId = -1; let bounceId = -1;
export function init(win: BrowserWindow) { export function init(win: BrowserWindow): void {
ipcMain.on('bounce-app-icon-start', (_, isCritical = false) => { ipcMain.on('bounce-app-icon-start', (_, isCritical = false) => {
if (app.dock) { if (app.dock) {
const type = isCritical ? 'critical' : 'informational'; const type = isCritical ? 'critical' : 'informational';
bounceId = app.dock.bounce(type); bounceId = app.dock.bounce(type);
if (bounceId < 0) {
return;
}
} else if (win && win.flashFrame) { } else if (win && win.flashFrame) {
win.once('focus', () => { win.once('focus', () => {
win.flashFrame(false); win.flashFrame(false);

View file

@ -1,3 +1,5 @@
/* eslint-disable class-methods-use-this */
import { import {
Call, Call,
CallEndedReason, CallEndedReason,
@ -39,9 +41,13 @@ export type CallHistoryDetailsType = {
export class CallingClass { export class CallingClass {
readonly videoCapturer: GumVideoCapturer; readonly videoCapturer: GumVideoCapturer;
readonly videoRenderer: CanvasVideoRenderer; readonly videoRenderer: CanvasVideoRenderer;
private uxActions?: UxActionsType; private uxActions?: UxActionsType;
private lastMediaDeviceSettings?: MediaDeviceSettings; private lastMediaDeviceSettings?: MediaDeviceSettings;
private deviceReselectionTimer?: NodeJS.Timeout; private deviceReselectionTimer?: NodeJS.Timeout;
constructor() { constructor() {
@ -85,7 +91,7 @@ export class CallingClass {
async startOutgoingCall( async startOutgoingCall(
conversation: ConversationModelType, conversation: ConversationModelType,
isVideoCall: boolean isVideoCall: boolean
) { ): Promise<void> {
if (!this.uxActions) { if (!this.uxActions) {
window.log.error('Missing uxActions, new call not allowed.'); window.log.error('Missing uxActions, new call not allowed.');
return; return;
@ -130,7 +136,7 @@ export class CallingClass {
}); });
} }
async accept(callId: CallId, asVideoCall: boolean) { async accept(callId: CallId, asVideoCall: boolean): Promise<void> {
const haveMediaPermissions = await this.requestPermissions(asVideoCall); const haveMediaPermissions = await this.requestPermissions(asVideoCall);
if (haveMediaPermissions) { if (haveMediaPermissions) {
await this.startDeviceReselectionTimer(); await this.startDeviceReselectionTimer();
@ -143,19 +149,19 @@ export class CallingClass {
} }
} }
decline(callId: CallId) { decline(callId: CallId): void {
RingRTC.decline(callId); RingRTC.decline(callId);
} }
hangup(callId: CallId) { hangup(callId: CallId): void {
RingRTC.hangup(callId); RingRTC.hangup(callId);
} }
setOutgoingAudio(callId: CallId, enabled: boolean) { setOutgoingAudio(callId: CallId, enabled: boolean): void {
RingRTC.setOutgoingAudio(callId, enabled); RingRTC.setOutgoingAudio(callId, enabled);
} }
setOutgoingVideo(callId: CallId, enabled: boolean) { setOutgoingVideo(callId: CallId, enabled: boolean): void {
RingRTC.setOutgoingVideo(callId, enabled); RingRTC.setOutgoingVideo(callId, enabled);
} }
@ -177,7 +183,6 @@ export class CallingClass {
} }
} }
// tslint:disable-next-line cyclomatic-complexity
private mediaDeviceSettingsEqual( private mediaDeviceSettingsEqual(
a?: MediaDeviceSettings, a?: MediaDeviceSettings,
b?: MediaDeviceSettings b?: MediaDeviceSettings
@ -195,7 +200,7 @@ export class CallingClass {
) { ) {
return false; return false;
} }
for (let i = 0; i < a.availableCameras.length; i++) { for (let i = 0; i < a.availableCameras.length; i += 1) {
if ( if (
a.availableCameras[i].deviceId !== b.availableCameras[i].deviceId || a.availableCameras[i].deviceId !== b.availableCameras[i].deviceId ||
a.availableCameras[i].groupId !== b.availableCameras[i].groupId || a.availableCameras[i].groupId !== b.availableCameras[i].groupId ||
@ -204,7 +209,7 @@ export class CallingClass {
return false; return false;
} }
} }
for (let i = 0; i < a.availableMicrophones.length; i++) { for (let i = 0; i < a.availableMicrophones.length; i += 1) {
if ( if (
a.availableMicrophones[i].name !== b.availableMicrophones[i].name || a.availableMicrophones[i].name !== b.availableMicrophones[i].name ||
a.availableMicrophones[i].uniqueId !== a.availableMicrophones[i].uniqueId !==
@ -213,7 +218,7 @@ export class CallingClass {
return false; return false;
} }
} }
for (let i = 0; i < a.availableSpeakers.length; i++) { for (let i = 0; i < a.availableSpeakers.length; i += 1) {
if ( if (
a.availableSpeakers[i].name !== b.availableSpeakers[i].name || a.availableSpeakers[i].name !== b.availableSpeakers[i].name ||
a.availableSpeakers[i].uniqueId !== b.availableSpeakers[i].uniqueId a.availableSpeakers[i].uniqueId !== b.availableSpeakers[i].uniqueId
@ -351,7 +356,8 @@ export class CallingClass {
const matchingId = available.filter(d => d.deviceId === preferred); const matchingId = available.filter(d => d.deviceId === preferred);
const nonInfrared = available.filter(d => !d.label.includes('IR Camera')); const nonInfrared = available.filter(d => !d.label.includes('IR Camera'));
/// By default, pick the first non-IR camera (but allow the user to pick the infrared if they so desire) // By default, pick the first non-IR camera (but allow the user to pick the
// infrared if they so desire)
if (matchingId.length > 0) { if (matchingId.length > 0) {
return matchingId[0].deviceId; return matchingId[0].deviceId;
} else if (nonInfrared.length > 0) { } else if (nonInfrared.length > 0) {
@ -361,19 +367,19 @@ export class CallingClass {
} }
} }
setPreferredMicrophone(device: AudioDevice) { setPreferredMicrophone(device: AudioDevice): void {
window.log.info('MediaDevice: setPreferredMicrophone', device); window.log.info('MediaDevice: setPreferredMicrophone', device);
window.storage.put('preferred-audio-input-device', device); window.storage.put('preferred-audio-input-device', device);
RingRTC.setAudioInput(device.index); RingRTC.setAudioInput(device.index);
} }
setPreferredSpeaker(device: AudioDevice) { setPreferredSpeaker(device: AudioDevice): void {
window.log.info('MediaDevice: setPreferredSpeaker', device); window.log.info('MediaDevice: setPreferredSpeaker', device);
window.storage.put('preferred-audio-output-device', device); window.storage.put('preferred-audio-output-device', device);
RingRTC.setAudioOutput(device.index); RingRTC.setAudioOutput(device.index);
} }
async setPreferredCamera(device: string) { async setPreferredCamera(device: string): Promise<void> {
window.log.info('MediaDevice: setPreferredCamera', device); window.log.info('MediaDevice: setPreferredCamera', device);
window.storage.put('preferred-video-input-device', device); window.storage.put('preferred-video-input-device', device);
await this.videoCapturer.setPreferredDevice(device); await this.videoCapturer.setPreferredDevice(device);
@ -382,7 +388,7 @@ export class CallingClass {
async handleCallingMessage( async handleCallingMessage(
envelope: EnvelopeClass, envelope: EnvelopeClass,
callingMessage: CallingMessageClass callingMessage: CallingMessageClass
) { ): Promise<void> {
const enableIncomingCalls = await window.getIncomingCallNotification(); const enableIncomingCalls = await window.getIncomingCallNotification();
if (callingMessage.offer && !enableIncomingCalls) { if (callingMessage.offer && !enableIncomingCalls) {
// Drop offers silently if incoming call notifications are disabled. // Drop offers silently if incoming call notifications are disabled.
@ -421,7 +427,8 @@ export class CallingClass {
await this.videoCapturer.setPreferredDevice(settings.selectedCamera); await this.videoCapturer.setPreferredDevice(settings.selectedCamera);
} }
// Assume that the MediaDeviceSettings have been obtained very recently and the index is still valid (no devices have been plugged in in between). // Assume that the MediaDeviceSettings have been obtained very recently and
// the index is still valid (no devices have been plugged in in between).
if (settings.selectedMicrophone) { if (settings.selectedMicrophone) {
window.log.info( window.log.info(
'MediaDevice: selecting microphone', 'MediaDevice: selecting microphone',
@ -583,6 +590,7 @@ export class CallingClass {
let acceptedTime: number | undefined; let acceptedTime: number | undefined;
// eslint-disable-next-line no-param-reassign
call.handleStateChanged = () => { call.handleStateChanged = () => {
if (call.state === CallState.Accepted) { if (call.state === CallState.Accepted) {
acceptedTime = Date.now(); acceptedTime = Date.now();
@ -597,6 +605,7 @@ export class CallingClass {
}); });
}; };
// eslint-disable-next-line no-param-reassign
call.handleRemoteVideoEnabled = () => { call.handleRemoteVideoEnabled = () => {
uxActions.remoteVideoChange({ uxActions.remoteVideoChange({
remoteVideoEnabled: call.remoteVideoEnabled, remoteVideoEnabled: call.remoteVideoEnabled,
@ -610,8 +619,6 @@ export class CallingClass {
line: number, line: number,
message: string message: string
) { ) {
// info/warn/error are only needed to be logged for now.
// tslint:disable-next-line switch-default
switch (level) { switch (level) {
case CallLogLevel.Info: case CallLogLevel.Info:
window.log.info(`${fileName}:${line} ${message}`); window.log.info(`${fileName}:${line} ${message}`);
@ -621,6 +628,9 @@ export class CallingClass {
break; break;
case CallLogLevel.Error: case CallLogLevel.Error:
window.log.error(`${fileName}:${line} ${message}`); window.log.error(`${fileName}:${line} ${message}`);
break;
default:
break;
} }
} }
@ -686,8 +696,10 @@ export class CallingClass {
private addCallHistoryForEndedCall( private addCallHistoryForEndedCall(
conversation: ConversationModelType, conversation: ConversationModelType,
call: Call, call: Call,
acceptedTime: number | undefined acceptedTimeParam: number | undefined
) { ) {
let acceptedTime = acceptedTimeParam;
const { endedReason, isIncoming } = call; const { endedReason, isIncoming } = call;
const wasAccepted = Boolean(acceptedTime); const wasAccepted = Boolean(acceptedTime);
const isOutgoing = !isIncoming; const isOutgoing = !isIncoming;
@ -700,7 +712,6 @@ export class CallingClass {
(isOutgoing && (isOutgoing &&
endedReason === CallEndedReason.RemoteHangupNeedPermission)); endedReason === CallEndedReason.RemoteHangupNeedPermission));
if (call.endedReason === CallEndedReason.AcceptedOnAnotherDevice) { if (call.endedReason === CallEndedReason.AcceptedOnAnotherDevice) {
// tslint:disable-next-line no-parameter-reassignment
acceptedTime = Date.now(); acceptedTime = Date.now();
} }

View file

@ -11,7 +11,9 @@ type NetworkActions = {
const REFRESH_INTERVAL = 5000; const REFRESH_INTERVAL = 5000;
export function initializeNetworkObserver(networkActions: NetworkActions) { export function initializeNetworkObserver(
networkActions: NetworkActions
): void {
const { log } = window; const { log } = window;
log.info(`Initializing network observer every ${REFRESH_INTERVAL}ms`); log.info(`Initializing network observer every ${REFRESH_INTERVAL}ms`);

View file

@ -13,7 +13,7 @@ type EventsType = {
export function initializeUpdateListener( export function initializeUpdateListener(
updatesActions: UpdatesActions, updatesActions: UpdatesActions,
events: EventsType events: EventsType
) { ): void {
ipcRenderer.on('show-update-dialog', (_, dialogType: Dialogs) => { ipcRenderer.on('show-update-dialog', (_, dialogType: Dialogs) => {
updatesActions.showUpdateDialog(dialogType); updatesActions.showUpdateDialog(dialogType);
}); });

View file

@ -10251,7 +10251,7 @@
"rule": "DOM-innerHTML", "rule": "DOM-innerHTML",
"path": "ts/backbone/views/Lightbox.js", "path": "ts/backbone/views/Lightbox.js",
"line": " container.innerHTML = '';", "line": " container.innerHTML = '';",
"lineNumber": 9, "lineNumber": 8,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2018-09-17T20:50:40.689Z", "updated": "2018-09-17T20:50:40.689Z",
"reasonDetail": "Hard-coded value" "reasonDetail": "Hard-coded value"
@ -10260,7 +10260,7 @@
"rule": "DOM-innerHTML", "rule": "DOM-innerHTML",
"path": "ts/backbone/views/Lightbox.js", "path": "ts/backbone/views/Lightbox.js",
"line": " container.innerHTML = '';", "line": " container.innerHTML = '';",
"lineNumber": 19, "lineNumber": 17,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2018-09-17T20:50:40.689Z", "updated": "2018-09-17T20:50:40.689Z",
"reasonDetail": "Hard-coded value" "reasonDetail": "Hard-coded value"
@ -10269,7 +10269,7 @@
"rule": "DOM-innerHTML", "rule": "DOM-innerHTML",
"path": "ts/backbone/views/Lightbox.ts", "path": "ts/backbone/views/Lightbox.ts",
"line": " container.innerHTML = '';", "line": " container.innerHTML = '';",
"lineNumber": 9, "lineNumber": 8,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2018-09-17T20:50:40.689Z", "updated": "2018-09-17T20:50:40.689Z",
"reasonDetail": "Hard-coded value" "reasonDetail": "Hard-coded value"
@ -10278,7 +10278,7 @@
"rule": "DOM-innerHTML", "rule": "DOM-innerHTML",
"path": "ts/backbone/views/Lightbox.ts", "path": "ts/backbone/views/Lightbox.ts",
"line": " container.innerHTML = '';", "line": " container.innerHTML = '';",
"lineNumber": 22, "lineNumber": 20,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2018-09-17T20:50:40.689Z", "updated": "2018-09-17T20:50:40.689Z",
"reasonDetail": "Hard-coded value" "reasonDetail": "Hard-coded value"

View file

@ -53,5 +53,9 @@
// "experimentalDecorators": true, // Enables experimental support for ES7 decorators. // "experimentalDecorators": true, // Enables experimental support for ES7 decorators.
// "emitDecoratorMetadata": true, // Enables experimental support for emitting type metadata for decorators. // "emitDecoratorMetadata": true, // Enables experimental support for emitting type metadata for decorators.
}, },
"include": ["ts/**/*", "node_modules/zkgroup/zkgroup/modules/*"] "include": [
"ts/**/*",
"node_modules/zkgroup/zkgroup/modules/*",
"package.json"
]
} }

View file

@ -176,6 +176,14 @@
}, },
"rulesDirectory": ["node_modules/tslint-microsoft-contrib"], "rulesDirectory": ["node_modules/tslint-microsoft-contrib"],
"linterOptions": { "linterOptions": {
"exclude": ["ts/components/emoji/**/*.ts"] "exclude": [
"ts/components/emoji/**",
"ts/backbone/**",
"ts/build/**",
"ts/notifications/**",
"ts/protobuf/**",
"ts/scripts/**",
"ts/services/**"
]
} }
} }