From b7754bcea0e4228ac8c193816c6c3311a7ff4ac4 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 25 Jul 2024 20:55:04 +0300 Subject: [PATCH] client-ts: Port services/app/app_context --- .../{app_context.js => app_context.ts} | 46 +++++++++++++++---- src/public/app/components/component.ts | 12 ++--- src/public/app/services/froca.ts | 2 +- src/public/app/services/utils.ts | 8 ++-- src/public/app/types.d.ts | 1 + 5 files changed, 48 insertions(+), 21 deletions(-) rename src/public/app/components/{app_context.js => app_context.ts} (81%) diff --git a/src/public/app/components/app_context.js b/src/public/app/components/app_context.ts similarity index 81% rename from src/public/app/components/app_context.js rename to src/public/app/components/app_context.ts index 2e06493dc..c4b6abbe4 100644 --- a/src/public/app/components/app_context.js +++ b/src/public/app/components/app_context.ts @@ -14,8 +14,32 @@ import MainTreeExecutors from "./main_tree_executors.js"; import toast from "../services/toast.js"; import ShortcutComponent from "./shortcut_component.js"; +interface Layout { + getRootWidget: (appContext: AppContext) => RootWidget; +} + +interface RootWidget extends Component { + render: () => JQuery; +} + +interface BeforeUploadListener extends Component { + beforeUnloadEvent(): boolean; +} + +interface TriggerData { + noteIds?: string[]; + callback?: () => void; +} + class AppContext extends Component { - constructor(isMainWindow) { + + isMainWindow: boolean; + components: Component[]; + beforeUnloadListeners: WeakRef[]; + tabManager!: TabManager; + layout?: Layout; + + constructor(isMainWindow: boolean) { super(); this.isMainWindow = isMainWindow; @@ -24,7 +48,7 @@ class AppContext extends Component { this.beforeUnloadListeners = []; } - setLayout(layout) { + setLayout(layout: Layout) { this.layout = layout; } @@ -68,6 +92,10 @@ class AppContext extends Component { } renderWidgets() { + if (!this.layout) { + throw new Error("Missing layout."); + } + const rootWidget = this.layout.getRootWidget(this); const $renderedWidget = rootWidget.render(); @@ -92,15 +120,13 @@ class AppContext extends Component { this.triggerEvent('initialRenderComplete'); } - /** @returns {Promise} */ - triggerEvent(name, data = {}) { + triggerEvent(name: string, data: TriggerData = {}) { return this.handleEvent(name, data); } - /** @returns {Promise<*>} */ - triggerCommand(name, data = {}) { + triggerCommand(name: string, data: TriggerData = {}) { for (const executor of this.components) { - const fun = executor[`${name}Command`]; + const fun = (executor as any)[`${name}Command`]; if (fun) { return executor.callMethod(fun, data); @@ -114,17 +140,17 @@ class AppContext extends Component { return this.triggerEvent(name, data); } - getComponentByEl(el) { + getComponentByEl(el: HTMLElement) { return $(el).closest(".component").prop('component'); } - addBeforeUnloadListener(obj) { + addBeforeUnloadListener(obj: BeforeUploadListener) { if (typeof WeakRef !== "function") { // older browsers don't support WeakRef return; } - this.beforeUnloadListeners.push(new WeakRef(obj)); + this.beforeUnloadListeners.push(new WeakRef(obj)); } } diff --git a/src/public/app/components/component.ts b/src/public/app/components/component.ts index 4b2445526..3e9cdfa36 100644 --- a/src/public/app/components/component.ts +++ b/src/public/app/components/component.ts @@ -12,10 +12,10 @@ import utils from '../services/utils.js'; * event / command is executed in all components - by simply awaiting the `triggerEvent()`. */ export default class Component { - private componentId: string; - private children: Component[]; - private initialized: Promise | null; - private parent?: Component; + componentId: string; + children: Component[]; + initialized: Promise | null; + parent?: Component; constructor() { this.componentId = `${this.sanitizedClassName}-${utils.randomString(8)}`; @@ -64,7 +64,7 @@ export default class Component { } } - triggerEvent(name: string, data = {}): Promise | undefined { + triggerEvent(name: string, data = {}): Promise | undefined | null { return this.parent?.triggerEvent(name, data); } @@ -83,7 +83,7 @@ export default class Component { return promises.length > 0 ? Promise.all(promises) : null; } - triggerCommand(name: string, data = {}): Promise | undefined { + triggerCommand(name: string, data = {}): Promise | undefined | null { const fun = (this as any)[`${name}Command`]; if (fun) { diff --git a/src/public/app/services/froca.ts b/src/public/app/services/froca.ts index cd12e7c30..5bc1191e3 100644 --- a/src/public/app/services/froca.ts +++ b/src/public/app/services/froca.ts @@ -31,7 +31,7 @@ interface SearchNoteResponse { * Backend has a similar cache called Becca */ class FrocaImpl implements Froca { - private initializedPromise: Promise; + initializedPromise: Promise; notes!: Record; branches!: Record; diff --git a/src/public/app/services/utils.ts b/src/public/app/services/utils.ts index 2ea61a876..b194edf0e 100644 --- a/src/public/app/services/utils.ts +++ b/src/public/app/services/utils.ts @@ -100,10 +100,10 @@ function isCtrlKey(evt: KeyboardEvent) { || (isMac() && evt.metaKey); } -function assertArguments() { - for (const i in arguments) { - if (!arguments[i]) { - console.trace(`Argument idx#${i} should not be falsy: ${arguments[i]}`); +function assertArguments(...args: string[]) { + for (const i in args) { + if (!args[i]) { + console.trace(`Argument idx#${i} should not be falsy: ${args[i]}`); } } } diff --git a/src/public/app/types.d.ts b/src/public/app/types.d.ts index edd022181..6844e530d 100644 --- a/src/public/app/types.d.ts +++ b/src/public/app/types.d.ts @@ -26,6 +26,7 @@ interface CustomGlobals { baseApiUrl: string; isProtectedSessionAvailable: boolean; isDev: boolean; + isMainWindow: boolean; maxEntityChangeIdAtLoad: number; maxEntityChangeSyncIdAtLoad: number; }