diff --git a/src/main/application-update/update-warning-level/periodical-check-for-update-warning.injectable.ts b/src/main/application-update/update-warning-level/periodical-check-for-update-warning.injectable.ts new file mode 100644 index 0000000000..8c1dc144bc --- /dev/null +++ b/src/main/application-update/update-warning-level/periodical-check-for-update-warning.injectable.ts @@ -0,0 +1,29 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import { getStartableStoppable } from "../../../common/utils/get-startable-stoppable"; +import setUpdateWarningLevelInjectable from "./set-update-warning-level.injectable"; + +const periodicalCheckForUpdateWarningInjectable = getInjectable({ + id: "periodical-check-for-update-warning", + + instantiate: (di) => { + const processCheckingForUpdateWarning = di.inject(setUpdateWarningLevelInjectable); + + return getStartableStoppable("periodical-check-for-update-warning", () => { + const ONCE_A_DAY = 1000 * 60 * 60 * 24; + + processCheckingForUpdateWarning(); + + const intervalId = setInterval(() => { + processCheckingForUpdateWarning(); + }, ONCE_A_DAY); + + return () => { + clearInterval(intervalId); + }; + }); + }, + + causesSideEffects: true, +}); + +export default periodicalCheckForUpdateWarningInjectable; \ No newline at end of file diff --git a/src/main/application-update/update-warning-level/set-update-downloaded-date.injectable.ts b/src/main/application-update/update-warning-level/set-update-downloaded-date.injectable.ts new file mode 100644 index 0000000000..c7fea2b665 --- /dev/null +++ b/src/main/application-update/update-warning-level/set-update-downloaded-date.injectable.ts @@ -0,0 +1,16 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import updateDownloadedDateInjectable from "./update-downloaded-date.injectable"; + +const setUpdateDownloadedDateInjectable = getInjectable({ + id: "set-update-downloaded-date", + + instantiate: (di) => { + const downloadedDate = di.inject(updateDownloadedDateInjectable); + + return (date: Date) => { + downloadedDate.set(date); + } + } +}); + +export default setUpdateDownloadedDateInjectable; \ No newline at end of file diff --git a/src/main/application-update/update-warning-level/set-update-warning-level.injectable.ts b/src/main/application-update/update-warning-level/set-update-warning-level.injectable.ts new file mode 100644 index 0000000000..89c25c9a29 --- /dev/null +++ b/src/main/application-update/update-warning-level/set-update-warning-level.injectable.ts @@ -0,0 +1,20 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import updateDownloadedDateInjectable from "./update-downloaded-date.injectable"; +import { UpdateWarningLevelCalculator } from "./update-warning-level-calculator"; +import updateWarningLevelInjectable from "./update-warning-level.injectable"; + +const setUpdateWarningLevelInjectable = getInjectable({ + id: "set-update-warning", + + instantiate: (di) => { + const updateDownloadedDate = di.inject(updateDownloadedDateInjectable); + const updateWarningLevel = di.inject(updateWarningLevelInjectable); + const newLevel = new UpdateWarningLevelCalculator(updateDownloadedDate.value.get()).get(); + + return () => { + updateWarningLevel.set(newLevel) + } + } +}); + +export default setUpdateWarningLevelInjectable; \ No newline at end of file diff --git a/src/main/application-update/update-warning-level/start-checking-for-update-warning.injectable.ts b/src/main/application-update/update-warning-level/start-checking-for-update-warning.injectable.ts new file mode 100644 index 0000000000..b5b21f96a0 --- /dev/null +++ b/src/main/application-update/update-warning-level/start-checking-for-update-warning.injectable.ts @@ -0,0 +1,35 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import { afterRootFrameIsReadyInjectionToken } from "../../start-main-application/runnable-tokens/after-root-frame-is-ready-injection-token"; +import downloadUpdateInjectable from "../download-update/download-update.injectable"; +import periodicalCheckForUpdateWarningInjectable from "./periodical-check-for-update-warning.injectable"; +import setUpdateDownloadedDateInjectable from "./set-update-downloaded-date.injectable"; +import updateDownloadedDateInjectable from "./update-downloaded-date.injectable"; + +const startCheckingForUpdateWarningInjectable = getInjectable({ + id: "start-checking-for-update-warning", + + instantiate: (di) => { + const downloadUpdate = di.inject(downloadUpdateInjectable); + const updateDownloadedDate = di.inject(updateDownloadedDateInjectable); + const setUpdateDownloadedDate = di.inject(setUpdateDownloadedDateInjectable); + const periodicalCheckForUpdateWarning = di.inject(periodicalCheckForUpdateWarningInjectable); + + return { + run: async () => { + const { downloadWasSuccessful } = await downloadUpdate(); + + if (downloadWasSuccessful) { + if (!updateDownloadedDate.value.get()) { + setUpdateDownloadedDate(new Date()); + } + + await periodicalCheckForUpdateWarning.start(); + } + }, + }; + }, + + injectionToken: afterRootFrameIsReadyInjectionToken, +}); + +export default startCheckingForUpdateWarningInjectable; diff --git a/src/main/application-update/update-warning-level/update-downloaded-date.injectable.ts b/src/main/application-update/update-warning-level/update-downloaded-date.injectable.ts new file mode 100644 index 0000000000..b5712eaa07 --- /dev/null +++ b/src/main/application-update/update-warning-level/update-downloaded-date.injectable.ts @@ -0,0 +1,20 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import createSyncBoxInjectable from "../../../common/utils/sync-box/create-sync-box.injectable"; +import { syncBoxInjectionToken } from "../../../common/utils/sync-box/sync-box-injection-token"; + +const updateDownloadedDateInjectable = getInjectable({ + id: "update-downloaded-date", + + instantiate: (di) => { + const createSyncBox = di.inject(createSyncBoxInjectable); + + return createSyncBox( + "update-downloaded-date", + null, + ); + }, + + injectionToken: syncBoxInjectionToken, +}); + +export default updateDownloadedDateInjectable; \ No newline at end of file diff --git a/src/main/application-update/update-warning-level/update-warning-level-calculator.ts b/src/main/application-update/update-warning-level/update-warning-level-calculator.ts new file mode 100644 index 0000000000..86efda568b --- /dev/null +++ b/src/main/application-update/update-warning-level/update-warning-level-calculator.ts @@ -0,0 +1,51 @@ + + +type WarningLevel = "high" | "medium" | "light" | ""; + +export class UpdateWarningLevelCalculator { + private onceADay = 1000 * 60 * 60 * 24; + private level: WarningLevel = ""; + + constructor (private updateDownloadedDate: Date | null) { + } + + get(): WarningLevel { + const days = this.daysAfterUpdateAvailable; + + this.setHighWarningLevel(days); + this.setMediumWarningLevel(days); + this.setLightWarningLevel(days); + + return this.level; + } + + private get daysAfterUpdateAvailable() { + if (!this.updateDownloadedDate) { + return 0; + } + + const today = Date.now(); + const elapsedTime = today - this.updateDownloadedDate.getTime(); + const elapsedDays = elapsedTime / (this.onceADay); + + return elapsedDays; + } + + private setHighWarningLevel(elapsedDays: number) { + if (elapsedDays >= 25) { + this.level = "high"; + } + } + + private setMediumWarningLevel(elapsedDays: number) { + if (elapsedDays >= 20 && elapsedDays < 25) { + this.level = "medium"; + } + } + + private setLightWarningLevel(elapsedDays: number) { + if (elapsedDays < 20) { + this.level = "light"; + } + } +} \ No newline at end of file diff --git a/src/main/application-update/update-warning-level/update-warning-level.injectable.ts b/src/main/application-update/update-warning-level/update-warning-level.injectable.ts new file mode 100644 index 0000000000..c347177bd4 --- /dev/null +++ b/src/main/application-update/update-warning-level/update-warning-level.injectable.ts @@ -0,0 +1,20 @@ +import { getInjectable } from "@ogre-tools/injectable"; +import createSyncBoxInjectable from "../../../common/utils/sync-box/create-sync-box.injectable"; +import { syncBoxInjectionToken } from "../../../common/utils/sync-box/sync-box-injection-token"; + +const updateWarningLevelInjectable = getInjectable({ + id: "update-warning-level", + + instantiate: (di) => { + const createSyncBox = di.inject(createSyncBoxInjectable); + + return createSyncBox<"light" | "medium" | "high" | "">( + "update-warning-level", + "", + ); + }, + + injectionToken: syncBoxInjectionToken, +}); + +export default updateWarningLevelInjectable; \ No newline at end of file diff --git a/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts b/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts index 68d1327774..9342696c77 100644 --- a/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts +++ b/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts @@ -9,7 +9,7 @@ import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHand import type { ClusterId } from "../../../../common/cluster-types"; import { ClusterStore } from "../../../../common/cluster-store/cluster-store"; import { appEventBus } from "../../../../common/app-event-bus/event-bus"; -import { AutoUpdateQuitAndInstalledChannel, broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc"; +import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc"; import type { CatalogEntityRegistry } from "../../../catalog"; import { pushCatalogToRenderer } from "../../../catalog-pusher"; import type { ClusterManager } from "../../../cluster-manager"; @@ -24,7 +24,6 @@ import { openFilePickingDialogChannel } from "../../../../common/ipc/dialog"; import { getNativeThemeChannel } from "../../../../common/ipc/native-theme"; import type { Theme } from "../../../theme/operating-system-theme-state.injectable"; import type { AskUserForFilePaths } from "../../../ipc/ask-user-for-file-paths.injectable"; -import { quitAndInstallUpdate } from "../../../app-updater"; interface Dependencies { directoryForLensLocalStorage: string; @@ -172,9 +171,5 @@ export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLoc return operatingSystemTheme.get(); }); - ipcMainOn(AutoUpdateQuitAndInstalledChannel, () => { - quitAndInstallUpdate(); - }); - clusterStore.provideInitialFromMain(); };