diff --git a/packages/app-desktop/gui/utils/NoteListUtils.ts b/packages/app-desktop/gui/utils/NoteListUtils.ts index 332d92431d..40714459cf 100644 --- a/packages/app-desktop/gui/utils/NoteListUtils.ts +++ b/packages/app-desktop/gui/utils/NoteListUtils.ts @@ -77,8 +77,8 @@ export default class NoteListUtils { const note = await Note.load(noteIds[i]); const newNote = Note.changeNoteType(note, type); if (newNote === note) continue; - await Note.save(newNote, { userSideValidation: true }); - eventManager.emit(EventName.NoteTypeToggle, { noteId: note.id }); + const savedNote = await Note.save(newNote, { userSideValidation: true }); + eventManager.emit(EventName.NoteTypeToggle, { noteId: note.id, note: savedNote }); } }; diff --git a/packages/lib/eventManager.ts b/packages/lib/eventManager.ts index c777085935..91dc1729c0 100644 --- a/packages/lib/eventManager.ts +++ b/packages/lib/eventManager.ts @@ -1,6 +1,8 @@ const fastDeepEqual = require('fast-deep-equal'); import { EventEmitter } from 'events'; import type { State as AppState } from './reducer'; +import { ModelType } from './BaseModel'; +import { NoteEntity } from './services/database/types'; export enum EventName { ResourceCreate = 'resourceCreate', @@ -20,8 +22,60 @@ export enum EventName { NoteResourceIndexed = 'noteResourceIndexed', } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of old code from before rule was applied -export type EventListenerCallback = (...args: any[])=> void; +interface ItemChangeEvent { + itemType: ModelType; + itemId: string; + eventType: number; +} + +interface SyncCompleteEvent { + withErrors: boolean; +} + +interface ResourceChangeEvent { + id: string; +} + +interface NoteContentChangeEvent { + note: NoteEntity; +} + +interface NoteAlarmTriggerEvent { + noteId: string; +} + +interface SettingsChangeEvent { + keys: string[]; +} + +interface NoteChangeEvent { + noteId: string; + note: NoteEntity; +} + +type EventArgs = { + [EventName.ResourceCreate]: []; + [EventName.ResourceChange]: [ResourceChangeEvent]; + [EventName.SettingsChange]: [SettingsChangeEvent]; + [EventName.TodoToggle]: []; + [EventName.NoteTypeToggle]: [NoteChangeEvent]; + [EventName.SyncStart]: []; + [EventName.SessionEstablished]: []; + [EventName.SyncComplete]: [SyncCompleteEvent]; + [EventName.ItemChange]: [ItemChangeEvent]; + [EventName.NoteAlarmTrigger]: [NoteAlarmTriggerEvent]; + [EventName.AlarmChange]: [NoteChangeEvent]; + [EventName.KeymapChange]: []; + [EventName.NoteContentChange]: [NoteContentChangeEvent]; + [EventName.OcrServiceResourcesProcessed]: []; + [EventName.NoteResourceIndexed]: []; +}; + +type EventListenerCallbacks = { + [n in EventName]: (...args: EventArgs[n])=> void; +}; +export type EventListenerCallback = EventListenerCallbacks[Name]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of old code from before rule was applied type AppStateChangeCallback = (event: { value: any })=> void; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of old code from before rule was applied @@ -47,20 +101,19 @@ export class EventManager { this.appStateListeners_ = {}; } - public on(eventName: EventName, callback: EventListenerCallback) { + public on(eventName: Name, callback: EventListenerCallback) { return this.emitter_.on(eventName, callback); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied - public emit(eventName: EventName, object: any = null) { - return this.emitter_.emit(eventName, object); + public emit(eventName: Name, ...args: EventArgs[Name]) { + return this.emitter_.emit(eventName, ...args); } - public removeListener(eventName: string, callback: EventListenerCallback) { + public removeListener(eventName: Name, callback: EventListenerCallback) { return this.emitter_.removeListener(eventName, callback); } - public off(eventName: EventName, callback: EventListenerCallback) { + public off(eventName: Name, callback: EventListenerCallback) { return this.removeListener(eventName, callback); } @@ -69,7 +122,7 @@ export class EventManager { } public filterOff(filterName: string, callback: FilterHandler) { - return this.removeListener(`filter:${filterName}`, callback); + return this.emitter_.off(`filter:${filterName}`, callback); } // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied @@ -154,7 +207,7 @@ export class EventManager { } } - public once(eventName: string, callback: EventListenerCallback) { + public once(eventName: Name, callback: EventListenerCallback) { return this.emitter_.once(eventName, callback); } diff --git a/packages/lib/services/CommandService.ts b/packages/lib/services/CommandService.ts index 1b91d8692c..b39c824b34 100644 --- a/packages/lib/services/CommandService.ts +++ b/packages/lib/services/CommandService.ts @@ -124,11 +124,11 @@ export default class CommandService extends BaseService { this.stateToWhenClauseContext_ = stateToWhenClauseContext; } - public on(eventName: EventName, callback: EventListenerCallback) { + public on(eventName: Name, callback: EventListenerCallback) { eventManager.on(eventName, callback); } - public off(eventName: EventName, callback: EventListenerCallback) { + public off(eventName: Name, callback: EventListenerCallback) { eventManager.off(eventName, callback); } diff --git a/packages/lib/services/KeymapService.ts b/packages/lib/services/KeymapService.ts index b78a2365e0..fc8f95fa7a 100644 --- a/packages/lib/services/KeymapService.ts +++ b/packages/lib/services/KeymapService.ts @@ -416,11 +416,11 @@ export default class KeymapService extends BaseService { return parts.join('+'); } - public on(eventName: EventName, callback: EventListenerCallback) { + public on(eventName: Name, callback: EventListenerCallback) { eventManager.on(eventName, callback); } - public off(eventName: EventName, callback: EventListenerCallback) { + public off(eventName: Name, callback: EventListenerCallback) { eventManager.off(eventName, callback); } diff --git a/packages/lib/services/plugins/api/JoplinWorkspace.ts b/packages/lib/services/plugins/api/JoplinWorkspace.ts index f702d050a7..07fce360cc 100644 --- a/packages/lib/services/plugins/api/JoplinWorkspace.ts +++ b/packages/lib/services/plugins/api/JoplinWorkspace.ts @@ -35,12 +35,6 @@ interface ItemChangeEvent { event: ItemChangeEventType; } -interface SyncStartEvent { - // Tells whether there were errors during sync or not. The log will - // have the complete information about any error. - withErrors: boolean; -} - interface ResourceChangeEvent { id: string; } @@ -59,13 +53,15 @@ interface NoteAlarmTriggerEvent { } interface SyncCompleteEvent { + // Tells whether there were errors during sync or not. The log will + // have the complete information about any error. withErrors: boolean; } type WorkspaceEventHandler = (event: EventType)=> void; type ItemChangeHandler = WorkspaceEventHandler; -type SyncStartHandler = WorkspaceEventHandler; +type SyncStartHandler = ()=> void; type ResourceChangeHandler = WorkspaceEventHandler; /** diff --git a/packages/lib/services/plugins/utils/makeListener.ts b/packages/lib/services/plugins/utils/makeListener.ts index ffb39bdc08..9f702d65b5 100644 --- a/packages/lib/services/plugins/utils/makeListener.ts +++ b/packages/lib/services/plugins/utils/makeListener.ts @@ -2,8 +2,8 @@ import Plugin from '../Plugin'; import { EventListenerCallback, EventManager, EventName } from '../../../eventManager'; import { Disposable } from '../api/types'; -export default function( - plugin: Plugin, eventManager: EventManager, eventName: EventName, callback: EventListenerCallback, +export default function( + plugin: Plugin, eventManager: EventManager, eventName: Name, callback: EventListenerCallback, ): Disposable { eventManager.on(eventName, callback); const dispose = () => { diff --git a/packages/lib/utils/userFetcher.ts b/packages/lib/utils/userFetcher.ts index f19f345b4d..341a90f44f 100644 --- a/packages/lib/utils/userFetcher.ts +++ b/packages/lib/utils/userFetcher.ts @@ -1,5 +1,5 @@ import SyncTargetRegistry from '../SyncTargetRegistry'; -import eventManager from '../eventManager'; +import eventManager, { EventName } from '../eventManager'; import Setting from '../models/Setting'; import { reg } from '../registry'; import Logger from '@joplin/utils/Logger'; @@ -44,7 +44,7 @@ const userFetcher = async () => { // Listen to the event only once export const initializeUserFetcher = () => { - eventManager.once('sessionEstablished', userFetcher); + eventManager.once(EventName.SessionEstablished, userFetcher); }; export default userFetcher;