You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Added no-floating-promises eslint rule
This commit is contained in:
		| @@ -126,6 +126,10 @@ module.exports = { | ||||
| 		{ | ||||
| 			// enable the rule specifically for TypeScript files | ||||
| 			'files': ['*.ts', '*.tsx'], | ||||
| 			'parserOptions': { | ||||
| 				// Required for @typescript-eslint/no-floating-promises | ||||
| 				'project': './tsconfig.eslint.json', | ||||
| 			}, | ||||
| 			'rules': { | ||||
| 				// Warn only because it would make it difficult to convert JS classes to TypeScript, unless we | ||||
| 				// make everything public which is not great. New code however should specify member accessibility. | ||||
| @@ -152,6 +156,7 @@ module.exports = { | ||||
| 						'requireLast': false, | ||||
| 					}, | ||||
| 				}], | ||||
| 				'@typescript-eslint/no-floating-promises': ['error'], | ||||
| 			}, | ||||
| 		}, | ||||
| 	], | ||||
|   | ||||
| @@ -156,7 +156,7 @@ export default class InteropServiceHelper { | ||||
|  | ||||
| 		if (Array.isArray(path)) path = path[0]; | ||||
|  | ||||
| 		CommandService.instance().execute('showModalMessage', _('Exporting to "%s" as "%s" format. Please wait...', path, module.format)); | ||||
| 		void CommandService.instance().execute('showModalMessage', _('Exporting to "%s" as "%s" format. Please wait...', path, module.format)); | ||||
|  | ||||
| 		const exportOptions: ExportOptions = {}; | ||||
| 		exportOptions.path = path; | ||||
| @@ -177,7 +177,7 @@ export default class InteropServiceHelper { | ||||
| 			bridge().showErrorMessageBox(_('Could not export notes: %s', error.message)); | ||||
| 		} | ||||
|  | ||||
| 		CommandService.instance().execute('hideModalMessage'); | ||||
| 		void CommandService.instance().execute('hideModalMessage'); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -424,7 +424,7 @@ class Application extends BaseApplication { | ||||
| 			const contextMenu = Menu.buildFromTemplate([ | ||||
| 				{ label: _('Open %s', app.electronApp().name), click: () => { app.window().show(); } }, | ||||
| 				{ type: 'separator' }, | ||||
| 				{ label: _('Quit'), click: () => { app.quit(); } }, | ||||
| 				{ label: _('Quit'), click: () => { void app.quit(); } }, | ||||
| 			]); | ||||
| 			app.createTray(contextMenu); | ||||
| 		} | ||||
| @@ -664,7 +664,7 @@ class Application extends BaseApplication { | ||||
| 		this.updateTray(); | ||||
|  | ||||
| 		shim.setTimeout(() => { | ||||
| 			AlarmService.garbageCollect(); | ||||
| 			void AlarmService.garbageCollect(); | ||||
| 		}, 1000 * 60 * 60); | ||||
|  | ||||
| 		if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) { | ||||
| @@ -676,12 +676,12 @@ class Application extends BaseApplication { | ||||
| 		ResourceService.runInBackground(); | ||||
|  | ||||
| 		if (Setting.value('env') === 'dev') { | ||||
| 			AlarmService.updateAllNotifications(); | ||||
| 			void AlarmService.updateAllNotifications(); | ||||
| 		} else { | ||||
| 			reg.scheduleSync(1000).then(() => { | ||||
| 				// Wait for the first sync before updating the notifications, since synchronisation | ||||
| 				// might change the notifications. | ||||
| 				AlarmService.updateAllNotifications(); | ||||
| 				void AlarmService.updateAllNotifications(); | ||||
|  | ||||
| 				DecryptionWorker.instance().scheduleStart(); | ||||
| 			}); | ||||
|   | ||||
| @@ -11,7 +11,7 @@ export const declaration: CommandDeclaration = { | ||||
| export const runtime = (): CommandRuntime => { | ||||
| 	return { | ||||
| 		execute: async () => { | ||||
| 			bridge().openItem(Setting.value('profileDir')); | ||||
| 			void bridge().openItem(Setting.value('profileDir')); | ||||
| 		}, | ||||
| 	}; | ||||
| }; | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const runtime = (): CommandRuntime => { | ||||
|  | ||||
| 			try { | ||||
| 				const note = await Note.load(noteId); | ||||
| 				ExternalEditWatcher.instance().openAndWatch(note); | ||||
| 				void ExternalEditWatcher.instance().openAndWatch(note); | ||||
| 			} catch (error) { | ||||
| 				bridge().showErrorMessageBox(_('Error opening note in editor: %s', error.message)); | ||||
| 			} | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export const runtime = (): CommandRuntime => { | ||||
| 	return { | ||||
| 		execute: async (context: CommandContext, noteId: string = null) => { | ||||
| 			noteId = noteId || stateUtils.selectedNoteId(context.state); | ||||
| 			ExternalEditWatcher.instance().stopWatching(noteId); | ||||
| 			void ExternalEditWatcher.instance().stopWatching(noteId); | ||||
| 		}, | ||||
| 		enabledCondition: 'oneNoteSelected', | ||||
| 	}; | ||||
|   | ||||
| @@ -17,9 +17,9 @@ export const runtime = (): CommandRuntime => { | ||||
| 			if (!noteId) return; | ||||
|  | ||||
| 			if (context.state.watchedNoteFiles.includes(noteId)) { | ||||
| 				CommandService.instance().execute('stopExternalEditing', noteId); | ||||
| 				void CommandService.instance().execute('stopExternalEditing', noteId); | ||||
| 			} else { | ||||
| 				CommandService.instance().execute('startExternalEditing', noteId); | ||||
| 				void CommandService.instance().execute('startExternalEditing', noteId); | ||||
| 			} | ||||
| 		}, | ||||
| 		enabledCondition: 'oneNoteSelected', | ||||
|   | ||||
| @@ -696,7 +696,7 @@ class ConfigScreenComponent extends React.Component<any, any> { | ||||
| 		const needRestartComp: any = this.state.needRestart ? ( | ||||
| 			<div style={{ ...theme.textStyle, padding: 10, paddingLeft: 24, backgroundColor: theme.warningBackgroundColor, color: theme.color }}> | ||||
| 				{this.restartMessage()} | ||||
| 				<a style={{ ...theme.urlStyle, marginLeft: 10 }} href="#" onClick={() => { this.restartApp(); }}>{_('Restart now')}</a> | ||||
| 				<a style={{ ...theme.urlStyle, marginLeft: 10 }} href="#" onClick={() => { void this.restartApp(); }}>{_('Restart now')}</a> | ||||
| 			</div> | ||||
| 		) : null; | ||||
|  | ||||
|   | ||||
| @@ -86,7 +86,7 @@ const useKeymap = (): [ | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		saveKeymap(); | ||||
| 		void saveKeymap(); | ||||
| 	}, [keymapItems, mustSave]); | ||||
|  | ||||
| 	return [keymapItems, keymapError, overrideKeymapItems, setAccelerator, resetAccelerator]; | ||||
|   | ||||
| @@ -330,7 +330,7 @@ class MainScreenComponent extends React.Component<Props, State> { | ||||
| 	layoutModeListenerKeyDown(event: any) { | ||||
| 		if (event.key !== 'Escape') return; | ||||
| 		if (!this.props.layoutMoveMode) return; | ||||
| 		CommandService.instance().execute('toggleLayoutMoveMode'); | ||||
| 		void CommandService.instance().execute('toggleLayoutMoveMode'); | ||||
| 	} | ||||
|  | ||||
| 	componentDidMount() { | ||||
|   | ||||
| @@ -18,9 +18,9 @@ export const runtime = (comp: any): CommandRuntime => { | ||||
| 					onClose: async (answer: any) => { | ||||
| 						if (answer) { | ||||
| 							if (noteType === 'note' || noteType === 'todo') { | ||||
| 								CommandService.instance().execute('newNote', answer.value, noteType === 'todo'); | ||||
| 								void CommandService.instance().execute('newNote', answer.value, noteType === 'todo'); | ||||
| 							} else { | ||||
| 								CommandService.instance().execute('insertText', TemplateUtils.render(answer.value)); | ||||
| 								void CommandService.instance().execute('insertText', TemplateUtils.render(answer.value)); | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const runtime = (comp: any): CommandRuntime => { | ||||
| 					noteId: noteId, | ||||
| 					visible: true, | ||||
| 					onRevisionLinkClick: () => { | ||||
| 						CommandService.instance().execute('showRevisions'); | ||||
| 						void CommandService.instance().execute('showRevisions'); | ||||
| 					}, | ||||
| 				}, | ||||
| 			}); | ||||
|   | ||||
| @@ -112,7 +112,7 @@ function useMenu(props: Props) { | ||||
| 	const [modulesLastChangeTime, setModulesLastChangeTime] = useState(Date.now()); | ||||
|  | ||||
| 	const onMenuItemClick = useCallback((commandName: string) => { | ||||
| 		CommandService.instance().execute(commandName); | ||||
| 		void CommandService.instance().execute(commandName); | ||||
| 	}, []); | ||||
|  | ||||
| 	const onImportModuleClick = useCallback(async (module: Module, moduleSource: string) => { | ||||
| @@ -134,7 +134,7 @@ function useMenu(props: Props) { | ||||
|  | ||||
| 		const modalMessage =  _('Importing from "%s" as "%s" format. Please wait...', path, module.format); | ||||
|  | ||||
| 		CommandService.instance().execute('showModalMessage', modalMessage); | ||||
| 		void CommandService.instance().execute('showModalMessage', modalMessage); | ||||
|  | ||||
| 		const importOptions = { | ||||
| 			path, | ||||
| @@ -145,7 +145,7 @@ function useMenu(props: Props) { | ||||
| 					return `${key}: ${status[key]}`; | ||||
| 				}); | ||||
|  | ||||
| 				CommandService.instance().execute('showModalMessage', `${modalMessage}\n\n${statusStrings.join('\n')}`); | ||||
| 				void CommandService.instance().execute('showModalMessage', `${modalMessage}\n\n${statusStrings.join('\n')}`); | ||||
| 			}, | ||||
| 			onError: console.warn, | ||||
| 			destinationFolderId: !module.isNoteArchive && moduleSource === 'file' ? props.selectedFolderId : null, | ||||
| @@ -159,7 +159,7 @@ function useMenu(props: Props) { | ||||
| 			bridge().showErrorMessageBox(error.message); | ||||
| 		} | ||||
|  | ||||
| 		CommandService.instance().execute('hideModalMessage'); | ||||
| 		void CommandService.instance().execute('hideModalMessage'); | ||||
| 	}, [props.selectedFolderId]); | ||||
|  | ||||
| 	const onMenuItemClickRef = useRef(null); | ||||
| @@ -177,7 +177,7 @@ function useMenu(props: Props) { | ||||
| 		const quitMenuItem = { | ||||
| 			label: _('Quit'), | ||||
| 			accelerator: keymapService.getAccelerator('quit'), | ||||
| 			click: () => { bridge().electronApp().quit(); }, | ||||
| 			click: () => { void bridge().electronApp().quit(); }, | ||||
| 		}; | ||||
|  | ||||
| 		const sortNoteFolderItems = (type: string) => { | ||||
| @@ -284,23 +284,23 @@ function useMenu(props: Props) { | ||||
| 		templateItems.push({ | ||||
| 			label: _('Create note from template'), | ||||
| 			click: () => { | ||||
| 				CommandService.instance().execute('selectTemplate', 'note'); | ||||
| 				void CommandService.instance().execute('selectTemplate', 'note'); | ||||
| 			}, | ||||
| 		}, { | ||||
| 			label: _('Create to-do from template'), | ||||
| 			click: () => { | ||||
| 				CommandService.instance().execute('selectTemplate', 'todo'); | ||||
| 				void CommandService.instance().execute('selectTemplate', 'todo'); | ||||
| 			}, | ||||
| 		}, { | ||||
| 			label: _('Insert template'), | ||||
| 			accelerator: keymapService.getAccelerator('insertTemplate'), | ||||
| 			click: () => { | ||||
| 				CommandService.instance().execute('selectTemplate'); | ||||
| 				void CommandService.instance().execute('selectTemplate'); | ||||
| 			}, | ||||
| 		}, { | ||||
| 			label: _('Open template directory'), | ||||
| 			click: () => { | ||||
| 				bridge().openItem(Setting.value('templateDir')); | ||||
| 				void bridge().openItem(Setting.value('templateDir')); | ||||
| 			}, | ||||
| 		}, { | ||||
| 			label: _('Refresh templates'), | ||||
|   | ||||
| @@ -323,7 +323,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		loadScripts(); | ||||
| 		void loadScripts(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
| @@ -630,7 +630,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { | ||||
| 							editorPasteText(); | ||||
| 						} else { | ||||
| 							// To handle pasting images | ||||
| 							onEditorPaste(); | ||||
| 							void onEditorPaste(); | ||||
| 						} | ||||
| 					}, | ||||
| 				}) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import shim from '@joplin/lib/shim'; | ||||
| export default function useKeymap(CodeMirror: any) { | ||||
|  | ||||
| 	function save() { | ||||
| 		CommandService.instance().execute('synchronize'); | ||||
| 		void CommandService.instance().execute('synchronize'); | ||||
| 	} | ||||
|  | ||||
| 	function setupEmacs() { | ||||
|   | ||||
| @@ -371,7 +371,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
| 			setScriptLoaded(true); | ||||
| 		} | ||||
|  | ||||
| 		loadScripts(); | ||||
| 		void loadScripts(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
| @@ -661,7 +661,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
| 						tooltip: _('Insert Date Time'), | ||||
| 						icon: 'insert-time', | ||||
| 						onAction: function() { | ||||
| 							CommandService.instance().execute('insertDateTime'); | ||||
| 							void CommandService.instance().execute('insertDateTime'); | ||||
| 						}, | ||||
| 					}); | ||||
|  | ||||
| @@ -670,7 +670,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
| 							tooltip: CommandService.instance().label(pluginCommandName), | ||||
| 							icon: CommandService.instance().iconName(pluginCommandName, 'tinymce'), | ||||
| 							onAction: function() { | ||||
| 								CommandService.instance().execute(pluginCommandName); | ||||
| 								void CommandService.instance().execute(pluginCommandName); | ||||
| 							}, | ||||
| 						}); | ||||
| 					} | ||||
| @@ -708,7 +708,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
| 			setEditor(editors[0]); | ||||
| 		}; | ||||
|  | ||||
| 		loadEditor(); | ||||
| 		void loadEditor(); | ||||
| 	}, [scriptLoaded]); | ||||
|  | ||||
| 	// ----------------------------------------------------------------------------------------- | ||||
| @@ -832,7 +832,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
| 			dispatchDidUpdate(editor); | ||||
| 		}; | ||||
|  | ||||
| 		loadContent(); | ||||
| 		void loadContent(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
| @@ -914,7 +914,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
| 	// the note. | ||||
| 	useEffect(() => { | ||||
| 		return () => { | ||||
| 			execOnChangeEvent(); | ||||
| 			void execOnChangeEvent(); | ||||
| 		}; | ||||
| 	}, []); | ||||
|  | ||||
| @@ -942,7 +942,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { | ||||
|  | ||||
| 			onChangeHandlerTimeoutRef.current = shim.setTimeout(async () => { | ||||
| 				onChangeHandlerTimeoutRef.current = null; | ||||
| 				execOnChangeEvent(); | ||||
| 				void execOnChangeEvent(); | ||||
| 			}, 1000); | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -113,7 +113,7 @@ function NoteEditor(props: NoteEditorProps) { | ||||
| 					return { ...prev, user_updated_time: savedNote.user_updated_time }; | ||||
| 				}); | ||||
|  | ||||
| 				ExternalEditWatcher.instance().updateNoteFile(savedNote); | ||||
| 				void ExternalEditWatcher.instance().updateNoteFile(savedNote); | ||||
|  | ||||
| 				props.dispatch({ | ||||
| 					type: 'EDITOR_NOTE_STATUS_REMOVE', | ||||
| @@ -141,7 +141,7 @@ function NoteEditor(props: NoteEditorProps) { | ||||
| 	} | ||||
|  | ||||
| 	async function saveNoteAndWait(formNote: FormNote) { | ||||
| 		saveNoteIfWillChange(formNote); | ||||
| 		await saveNoteIfWillChange(formNote); | ||||
| 		return formNote.saveActionQueue.waitForAllDone(); | ||||
| 	} | ||||
|  | ||||
| @@ -184,7 +184,7 @@ function NoteEditor(props: NoteEditorProps) { | ||||
| 			value: props.selectedNoteHash ? props.selectedNoteHash : props.lastEditorScrollPercents[props.noteId] || 0, | ||||
| 		}); | ||||
|  | ||||
| 		ResourceEditWatcher.instance().stopWatchingAll(); | ||||
| 		void ResourceEditWatcher.instance().stopWatchingAll(); | ||||
| 	}, [formNote.id, previousNoteId]); | ||||
|  | ||||
| 	const onFieldChange = useCallback((field: string, value: any, changeId = 0) => { | ||||
| @@ -365,7 +365,7 @@ function NoteEditor(props: NoteEditorProps) { | ||||
| 	function renderTagBar() { | ||||
| 		const theme = themeStyle(props.themeId); | ||||
| 		const noteIds = [formNote.id]; | ||||
| 		const instructions = <span onClick={() => { CommandService.instance().execute('setTags', noteIds); }} style={{ ...theme.clickableTextStyle, whiteSpace: 'nowrap' }}>Click to add tags...</span>; | ||||
| 		const instructions = <span onClick={() => { void CommandService.instance().execute('setTags', noteIds); }} style={{ ...theme.clickableTextStyle, whiteSpace: 'nowrap' }}>Click to add tags...</span>; | ||||
| 		const tagList = props.selectedNoteTags.length ? <TagList items={props.selectedNoteTags} /> : null; | ||||
|  | ||||
| 		return ( | ||||
|   | ||||
| @@ -82,9 +82,9 @@ export default function NoteTitleBar(props: Props) { | ||||
| 			event.preventDefault(); | ||||
|  | ||||
| 			if (event.shiftKey) { | ||||
| 				CommandService.instance().execute('focusElement', 'noteList'); | ||||
| 				void CommandService.instance().execute('focusElement', 'noteList'); | ||||
| 			} else { | ||||
| 				CommandService.instance().execute('focusElement', 'noteBody'); | ||||
| 				void CommandService.instance().execute('focusElement', 'noteBody'); | ||||
| 			} | ||||
| 		} | ||||
| 	}, []); | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export default function(dependencies: HookDependencies) { | ||||
| 			setFolder(f); | ||||
| 		} | ||||
|  | ||||
| 		loadFolder(); | ||||
| 		void loadFolder(); | ||||
|  | ||||
| 		return function() { | ||||
| 			cancelled = true; | ||||
|   | ||||
| @@ -133,7 +133,7 @@ export default function useFormNote(dependencies: HookDependencies) { | ||||
| 			await initNoteState(n); | ||||
| 		}; | ||||
|  | ||||
| 		loadNote(); | ||||
| 		void loadNote(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
| @@ -183,7 +183,7 @@ export default function useFormNote(dependencies: HookDependencies) { | ||||
| 			handleAutoFocus(!!n.is_todo); | ||||
| 		} | ||||
|  | ||||
| 		loadNote(); | ||||
| 		void loadNote(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
| @@ -207,7 +207,7 @@ export default function useFormNote(dependencies: HookDependencies) { | ||||
|  | ||||
| 	useEffect(() => { | ||||
| 		if (previousNoteId !== formNote.id) { | ||||
| 			onResourceChange(); | ||||
| 			void onResourceChange(); | ||||
| 		} | ||||
| 	}, [previousNoteId, formNote.id, onResourceChange]); | ||||
|  | ||||
| @@ -222,7 +222,7 @@ export default function useFormNote(dependencies: HookDependencies) { | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		runEffect(); | ||||
| 		void runEffect(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
|   | ||||
| @@ -389,9 +389,9 @@ class NoteListComponent extends React.Component { | ||||
| 			event.preventDefault(); | ||||
|  | ||||
| 			if (event.shiftKey) { | ||||
| 				CommandService.instance().execute('focusElement', 'sideBar'); | ||||
| 				void CommandService.instance().execute('focusElement', 'sideBar'); | ||||
| 			} else { | ||||
| 				CommandService.instance().execute('focusElement', 'noteTitle'); | ||||
| 				void CommandService.instance().execute('focusElement', 'noteTitle'); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -41,11 +41,11 @@ export default function NoteListControls(props: Props) { | ||||
| 	}, []); | ||||
|  | ||||
| 	function onNewTodoButtonClick() { | ||||
| 		CommandService.instance().execute('newTodo'); | ||||
| 		void CommandService.instance().execute('newTodo'); | ||||
| 	} | ||||
|  | ||||
| 	function onNewNoteButtonClick() { | ||||
| 		CommandService.instance().execute('newNote'); | ||||
| 		void CommandService.instance().execute('newNote'); | ||||
| 	} | ||||
|  | ||||
| 	function renderNewNoteButtons() { | ||||
|   | ||||
| @@ -161,7 +161,7 @@ class ResourceScreenComponent extends React.Component<Props, State> { | ||||
| 	} | ||||
|  | ||||
| 	componentDidMount() { | ||||
| 		this.reloadResources(this.state.sorting); | ||||
| 		void this.reloadResources(this.state.sorting); | ||||
| 	} | ||||
|  | ||||
| 	onResourceDelete(resource: InnerResource) { | ||||
| @@ -177,7 +177,7 @@ class ResourceScreenComponent extends React.Component<Props, State> { | ||||
| 				bridge().showErrorMessageBox(error.message); | ||||
| 			}) | ||||
| 			.finally(() => { | ||||
| 				this.reloadResources(this.state.sorting); | ||||
| 				void this.reloadResources(this.state.sorting); | ||||
| 			}); | ||||
| 	} | ||||
|  | ||||
| @@ -200,7 +200,7 @@ class ResourceScreenComponent extends React.Component<Props, State> { | ||||
| 			}; | ||||
| 		} | ||||
| 		this.setState({ sorting: newSorting }); | ||||
| 		this.reloadResources(newSorting); | ||||
| 		void this.reloadResources(newSorting); | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
|   | ||||
| @@ -103,17 +103,17 @@ function SearchBar(props: Props) { | ||||
| 	const onKeyDown = useCallback((event: any) => { | ||||
| 		if (event.key === 'Escape') { | ||||
| 			if (document.activeElement) (document.activeElement as any).blur(); | ||||
| 			onExitSearch(); | ||||
| 			void onExitSearch(); | ||||
| 		} | ||||
| 	}, [onExitSearch]); | ||||
|  | ||||
| 	const onSearchButtonClick = useCallback(() => { | ||||
| 		onExitSearch(); | ||||
| 		void onExitSearch(); | ||||
| 	}, [onExitSearch]); | ||||
|  | ||||
| 	useEffect(() => { | ||||
| 		if (props.notesParentType !== 'Search') { | ||||
| 			onExitSearch(false); | ||||
| 			void onExitSearch(false); | ||||
| 		} | ||||
| 	}, [props.notesParentType, onExitSearch]); | ||||
|  | ||||
|   | ||||
| @@ -79,7 +79,7 @@ export default function ShareNoteDialog(props: ShareNoteDialogProps) { | ||||
| 			setNotes(result); | ||||
| 		} | ||||
|  | ||||
| 		fetchNotes(); | ||||
| 		void fetchNotes(); | ||||
| 	}, [props.noteIds]); | ||||
|  | ||||
| 	const appApi = async () => { | ||||
|   | ||||
| @@ -510,9 +510,9 @@ class SideBarComponent extends React.Component<Props, State> { | ||||
| 			event.preventDefault(); | ||||
|  | ||||
| 			if (event.shiftKey) { | ||||
| 				CommandService.instance().execute('focusElement', 'noteBody'); | ||||
| 				void CommandService.instance().execute('focusElement', 'noteBody'); | ||||
| 			} else { | ||||
| 				CommandService.instance().execute('focusElement', 'noteList'); | ||||
| 				void CommandService.instance().execute('focusElement', 'noteList'); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -559,14 +559,14 @@ class SideBarComponent extends React.Component<Props, State> { | ||||
| 				iconAnimation={iconAnimation} | ||||
| 				title={label} | ||||
| 				onClick={() => { | ||||
| 					CommandService.instance().execute('synchronize', type !== 'sync'); | ||||
| 					void CommandService.instance().execute('synchronize', type !== 'sync'); | ||||
| 				}} | ||||
| 			/> | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	onAddFolderButtonClick() { | ||||
| 		CommandService.instance().execute('newFolder'); | ||||
| 		void CommandService.instance().execute('newFolder'); | ||||
| 	} | ||||
|  | ||||
| 	// componentDidUpdate(prevProps:any, prevState:any) { | ||||
|   | ||||
| @@ -41,7 +41,7 @@ function StatusScreen(props: Props) { | ||||
| 	} | ||||
|  | ||||
| 	useEffect(() => { | ||||
| 		resfreshScreen(); | ||||
| 		void resfreshScreen(); | ||||
| 	}, []); | ||||
|  | ||||
| 	const theme = themeStyle(props.themeId); | ||||
| @@ -91,7 +91,7 @@ function StatusScreen(props: Props) { | ||||
| 				if (item.canRetry) { | ||||
| 					const onClick = async () => { | ||||
| 						await item.retryHandler(); | ||||
| 						resfreshScreen(); | ||||
| 						void resfreshScreen(); | ||||
| 					}; | ||||
|  | ||||
| 					retryLink = ( | ||||
|   | ||||
| @@ -381,7 +381,7 @@ class Dialog extends React.PureComponent<Props, State> { | ||||
| 		}); | ||||
|  | ||||
| 		if (item.type === BaseModel.TYPE_COMMAND) { | ||||
| 			CommandService.instance().execute(item.id); | ||||
| 			void CommandService.instance().execute(item.id); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| @@ -423,7 +423,7 @@ class Dialog extends React.PureComponent<Props, State> { | ||||
| 		const parentId = event.currentTarget.getAttribute('data-parent-id'); | ||||
| 		const itemType = Number(event.currentTarget.getAttribute('data-type')); | ||||
|  | ||||
| 		this.gotoItem({ | ||||
| 		void this.gotoItem({ | ||||
| 			id: itemId, | ||||
| 			parent_id: parentId, | ||||
| 			type: itemType, | ||||
| @@ -496,7 +496,7 @@ class Dialog extends React.PureComponent<Props, State> { | ||||
| 			const item = this.selectedItem(); | ||||
| 			if (!item) return; | ||||
|  | ||||
| 			this.gotoItem(item); | ||||
| 			void this.gotoItem(item); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ export default function useThemeCss(dep: HookDependencies) { | ||||
| 			setCssFilePath(filePath); | ||||
| 		} | ||||
|  | ||||
| 		createThemeStyleSheet(); | ||||
| 		void createThemeStyleSheet(); | ||||
|  | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
|   | ||||
| @@ -186,7 +186,7 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number, | ||||
| 			setSource(undefined); | ||||
| 			setInjectedJs([]); | ||||
| 		} else { | ||||
| 			renderNote(); | ||||
| 			void renderNote(); | ||||
| 		} | ||||
|  | ||||
| 		return () => { | ||||
|   | ||||
| @@ -259,11 +259,11 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 	} | ||||
|  | ||||
| 	screenHeader_undoButtonPress() { | ||||
| 		this.undoRedo('undo'); | ||||
| 		void this.undoRedo('undo'); | ||||
| 	} | ||||
|  | ||||
| 	screenHeader_redoButtonPress() { | ||||
| 		this.undoRedo('redo'); | ||||
| 		void this.undoRedo('redo'); | ||||
| 	} | ||||
|  | ||||
| 	styles() { | ||||
| @@ -404,7 +404,7 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 		// Although it is async, we don't wait for the answer so that if permission | ||||
| 		// has already been granted, it doesn't slow down opening the note. If it hasn't | ||||
| 		// been granted, the popup will open anyway. | ||||
| 		this.requestGeoLocationPermissions(); | ||||
| 		void this.requestGeoLocationPermissions(); | ||||
| 	} | ||||
|  | ||||
| 	onMarkForDownload(event: any) { | ||||
| @@ -703,7 +703,7 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 	} | ||||
|  | ||||
| 	cameraView_onPhoto(data: any) { | ||||
| 		this.attachFile( | ||||
| 		void this.attachFile( | ||||
| 			{ | ||||
| 				uri: data.uri, | ||||
| 				didCancel: false, | ||||
| @@ -810,14 +810,14 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 		output.push({ | ||||
| 			title: _('View on map'), | ||||
| 			onPress: () => { | ||||
| 				this.showOnMap_onPress(); | ||||
| 				void this.showOnMap_onPress(); | ||||
| 			}, | ||||
| 		}); | ||||
| 		if (note.source_url) { | ||||
| 			output.push({ | ||||
| 				title: _('Go to source URL'), | ||||
| 				onPress: () => { | ||||
| 					this.showSource_onPress(); | ||||
| 					void this.showSource_onPress(); | ||||
| 				}, | ||||
| 			}); | ||||
| 		} | ||||
| @@ -866,8 +866,8 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 					const buttonId = await dialogs.pop(this, _('Choose an option'), buttons); | ||||
|  | ||||
| 					if (buttonId === 'takePhoto') this.takePhoto_onPress(); | ||||
| 					if (buttonId === 'attachFile') this.attachFile_onPress(); | ||||
| 					if (buttonId === 'attachPhoto') this.attachPhoto_onPress(); | ||||
| 					if (buttonId === 'attachFile') void this.attachFile_onPress(); | ||||
| 					if (buttonId === 'attachPhoto') void this.attachPhoto_onPress(); | ||||
| 				}, | ||||
| 			}); | ||||
| 		} | ||||
| @@ -884,7 +884,7 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 		output.push({ | ||||
| 			title: _('Share'), | ||||
| 			onPress: () => { | ||||
| 				this.share_onPress(); | ||||
| 				void this.share_onPress(); | ||||
| 			}, | ||||
| 		}); | ||||
| 		if (isSaved) { | ||||
| @@ -918,7 +918,7 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 		output.push({ | ||||
| 			title: _('Delete'), | ||||
| 			onPress: () => { | ||||
| 				this.deleteNote_onPress(); | ||||
| 				void this.deleteNote_onPress(); | ||||
| 			}, | ||||
| 		}); | ||||
|  | ||||
| @@ -1010,7 +1010,7 @@ class NoteScreenComponent extends BaseScreenComponent { | ||||
| 	} | ||||
|  | ||||
| 	onBodyViewerCheckboxChange(newBody: string) { | ||||
| 		this.saveOneProperty('body', newBody); | ||||
| 		void this.saveOneProperty('body', newBody); | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
|   | ||||
| @@ -54,7 +54,7 @@ export default class AsyncActionQueue { | ||||
|  | ||||
| 		this.scheduleProcessingIID_ = shim.setTimeout(() => { | ||||
| 			this.scheduleProcessingIID_ = null; | ||||
| 			this.processQueue(); | ||||
| 			void this.processQueue(); | ||||
| 		}, interval); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -354,7 +354,7 @@ export default class Synchronizer { | ||||
| 			this.lockHandler().startAutoLockRefresh(syncLock, (error: any) => { | ||||
| 				this.logger().warn('Could not refresh lock - cancelling sync. Error was:', error); | ||||
| 				this.syncTargetIsLocked_ = true; | ||||
| 				this.cancel(); | ||||
| 				void this.cancel(); | ||||
| 			}); | ||||
|  | ||||
| 			// ======================================================================== | ||||
|   | ||||
| @@ -37,13 +37,13 @@ export default class AlarmServiceDriverNode { | ||||
| 		return id in this.notifications_; | ||||
| 	} | ||||
|  | ||||
| 	async clearNotification(id: number) { | ||||
| 	clearNotification(id: number) { | ||||
| 		if (!this.notificationIsSet(id)) return; | ||||
| 		shim.clearTimeout(this.notifications_[id].timeoutId); | ||||
| 		delete this.notifications_[id]; | ||||
| 	} | ||||
|  | ||||
| 	async scheduleNotification(notification: Notification) { | ||||
| 	scheduleNotification(notification: Notification) { | ||||
| 		const now = Date.now(); | ||||
| 		const interval = notification.date.getTime() - now; | ||||
| 		if (interval < 0) return; | ||||
|   | ||||
| @@ -232,7 +232,7 @@ export default class CommandService extends BaseService { | ||||
|  | ||||
| 	public scheduleExecute(commandName: string, args: any) { | ||||
| 		shim.setTimeout(() => { | ||||
| 			this.execute(commandName, args); | ||||
| 			void this.execute(commandName, args); | ||||
| 		}, 10); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -100,7 +100,7 @@ export default class ExternalEditWatcher { | ||||
|  | ||||
| 						if (!note) { | ||||
| 							this.logger().warn(`ExternalEditWatcher: Watched note has been deleted: ${id}`); | ||||
| 							this.stopWatching(id); | ||||
| 							void this.stopWatching(id); | ||||
| 							return; | ||||
| 						} | ||||
|  | ||||
| @@ -339,7 +339,7 @@ export default class ExternalEditWatcher { | ||||
| 		// avoid update loops. We only want to listen to file changes made by the user. | ||||
| 		this.skipNextChangeEvent_[note.id] = true; | ||||
|  | ||||
| 		this.writeNoteToFile_(note); | ||||
| 		await this.writeNoteToFile_(note); | ||||
| 	} | ||||
|  | ||||
| 	async writeNoteToFile_(note: NoteEntity) { | ||||
|   | ||||
| @@ -157,7 +157,7 @@ export default class ResourceEditWatcher { | ||||
|  | ||||
| 		if (!this.watcher_) { | ||||
| 			this.watcher_ = this.chokidar_.watch(fileToWatch); | ||||
| 			this.watcher_.on('all', async (event: any, path: string) => { | ||||
| 			this.watcher_.on('all', (event: any, path: string) => { | ||||
| 				path = toSystemSlashes(path, 'linux'); | ||||
|  | ||||
| 				this.logger().info(`ResourceEditWatcher: Event: ${event}: ${path}`); | ||||
| @@ -170,7 +170,7 @@ export default class ResourceEditWatcher { | ||||
| 					// See: https://github.com/laurent22/joplin/issues/710#issuecomment-420997167 | ||||
| 					// this.watcher_.unwatch(path); | ||||
| 				} else if (event === 'change') { | ||||
| 					handleChangeEvent(path); | ||||
| 					void handleChangeEvent(path); | ||||
| 				} else if (event === 'error') { | ||||
| 					this.logger().error('ResourceEditWatcher: error'); | ||||
| 				} | ||||
| @@ -185,14 +185,14 @@ export default class ResourceEditWatcher { | ||||
| 			// https://github.com/laurent22/joplin/issues/3407 | ||||
| 			// | ||||
| 			// @ts-ignore Leave unused path variable | ||||
| 			this.watcher_.on('raw', async (event: string, path: string, options: any) => { | ||||
| 			this.watcher_.on('raw', (event: string, path: string, options: any) => { | ||||
| 				const watchedPath = toSystemSlashes(options.watchedPath, 'linux'); | ||||
|  | ||||
| 				this.logger().debug(`ResourceEditWatcher: Raw event: ${event}: ${watchedPath}`); | ||||
| 				if (event === 'rename') { | ||||
| 					this.watcher_.unwatch(watchedPath); | ||||
| 					this.watcher_.add(watchedPath); | ||||
| 					handleChangeEvent(watchedPath); | ||||
| 					void handleChangeEvent(watchedPath); | ||||
| 				} | ||||
| 			}); | ||||
| 		} else { | ||||
|   | ||||
| @@ -154,11 +154,11 @@ export default class ResourceService extends BaseService { | ||||
| 		const service = this.instance(); | ||||
|  | ||||
| 		service.maintenanceTimer1_ = shim.setTimeout(() => { | ||||
| 			service.maintenance(); | ||||
| 			void service.maintenance(); | ||||
| 		}, 1000 * 30); | ||||
|  | ||||
| 		service.maintenanceTimer2_ = shim.setInterval(() => { | ||||
| 			service.maintenance(); | ||||
| 			void service.maintenance(); | ||||
| 		}, 1000 * 60 * 60 * 4); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -52,8 +52,8 @@ export default class ToolbarButtonUtils { | ||||
| 			tooltip: this.service.label(commandName), | ||||
| 			iconName: command.declaration.iconName, | ||||
| 			enabled: newEnabled, | ||||
| 			onClick: async () => { | ||||
| 				this.service.execute(commandName); | ||||
| 			onClick: () => { | ||||
| 				void this.service.execute(commandName); | ||||
| 			}, | ||||
| 			title: newTitle, | ||||
| 		}; | ||||
|   | ||||
| @@ -27,7 +27,7 @@ export default class InteropService_Importer_Md extends InteropService_Importer_ | ||||
| 				parentFolderId = this.options_.destinationFolder.id; | ||||
| 			} | ||||
|  | ||||
| 			this.importDirectory(sourcePath, parentFolderId); | ||||
| 			await this.importDirectory(sourcePath, parentFolderId); | ||||
| 		} else { | ||||
| 			if (!this.options_.destinationFolder) throw new Error(_('Please specify the notebook where the notes should be imported to.')); | ||||
| 			parentFolderId = this.options_.destinationFolder.id; | ||||
| @@ -52,9 +52,9 @@ export default class InteropService_Importer_Md extends InteropService_Importer_ | ||||
| 			if (stat.isDirectory()) { | ||||
| 				const folderTitle = await Folder.findUniqueItemTitle(basename(stat.path)); | ||||
| 				const folder = await Folder.save({ title: folderTitle, parent_id: parentFolderId }); | ||||
| 				this.importDirectory(`${dirPath}/${basename(stat.path)}`, folder.id); | ||||
| 				await this.importDirectory(`${dirPath}/${basename(stat.path)}`, folder.id); | ||||
| 			} else if (supportedFileExtension.indexOf(fileExtension(stat.path).toLowerCase()) >= 0) { | ||||
| 				this.importFile(`${dirPath}/${stat.path}`, parentFolderId); | ||||
| 				await this.importFile(`${dirPath}/${stat.path}`, parentFolderId); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -103,7 +103,7 @@ export default class WebviewController extends ViewController { | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	public async close() { | ||||
| 	public close() { | ||||
| 		this.setStoreProp('opened', false); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ export default class JoplinPlugins { | ||||
| 			// We don't use `await` when calling onStart because the plugin might be awaiting | ||||
| 			// in that call too (for example, when opening a dialog on startup) so we don't | ||||
| 			// want to get stuck here. | ||||
| 			script.onStart({}).catch((error: any) => { | ||||
| 			void script.onStart({}).catch((error: any) => { | ||||
| 				// For some reason, error thrown from the executed script do not have the type "Error" | ||||
| 				// but are instead plain object. So recreate the Error object here so that it can | ||||
| 				// be handled correctly by loggers, etc. | ||||
|   | ||||
| @@ -66,7 +66,7 @@ export default class SpellCheckerService { | ||||
| 	public setLanguage(language: string) { | ||||
| 		Setting.setValue('spellChecker.language', language); | ||||
| 		this.applyStateToDriver(); | ||||
| 		this.addLatestSelectedLanguage(language); | ||||
| 		void this.addLatestSelectedLanguage(language); | ||||
| 	} | ||||
|  | ||||
| 	public get language(): string { | ||||
| @@ -98,7 +98,7 @@ export default class SpellCheckerService { | ||||
| 				output.push({ | ||||
| 					label: suggestion, | ||||
| 					click: () => { | ||||
| 						CommandService.instance().execute('replaceSelection', suggestion); | ||||
| 						void CommandService.instance().execute('replaceSelection', suggestion); | ||||
| 					}, | ||||
| 				}); | ||||
| 			} | ||||
| @@ -115,7 +115,7 @@ export default class SpellCheckerService { | ||||
| 		output.push({ | ||||
| 			label: _('Add to dictionary'), | ||||
| 			click: () => { | ||||
| 				this.addToDictionary(this.language, misspelledWord); | ||||
| 				void this.addToDictionary(this.language, misspelledWord); | ||||
| 			}, | ||||
| 		}); | ||||
|  | ||||
|   | ||||
| @@ -51,7 +51,7 @@ export default function useSyncTargetUpgrade(): SyncTargetUpgradeResult { | ||||
| 	} | ||||
|  | ||||
| 	useEffect(function() { | ||||
| 		upgradeSyncTarget(); | ||||
| 		void upgradeSyncTarget(); | ||||
| 	}, []); | ||||
|  | ||||
| 	return upgradeResult; | ||||
|   | ||||
							
								
								
									
										7
									
								
								tsconfig.eslint.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tsconfig.eslint.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| { | ||||
| 	"extends": "./tsconfig.json", | ||||
|     "include": [ | ||||
|         "**/*.ts", | ||||
|         "**/*.tsx", | ||||
| 	], | ||||
| } | ||||
		Reference in New Issue
	
	Block a user