From 2c39b9019f85dcac5ef9d1e454f52b7f273cb504 Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Tue, 28 Jun 2022 12:11:13 +0300 Subject: [PATCH] Make update warning level completely reactive and responsibility of a renderer Co-authored-by: Alex Andreev Signed-off-by: Janne Savolainen --- ...alling-update-using-topbar-button.test.tsx | 14 +++--- ...t-and-install-update-channel.injectable.ts | 0 .../update-downloaded-date-time.injectable.ts | 24 ++++++++++ .../download-update.injectable.ts | 7 +++ .../restart-and-install-update.listener.ts | 2 +- .../update-downloaded-date.injectable.ts | 24 ---------- .../restart-and-install-update.injectable.ts | 2 +- .../update-button/update-button.tsx | 21 ++++----- .../update-warning-level.injectable.ts | 45 +++++++++++++++++++ 9 files changed, 93 insertions(+), 46 deletions(-) rename src/common/application-update/{update-warning-level => restart-and-install-update-channel}/restart-and-install-update-channel.injectable.ts (100%) create mode 100644 src/common/application-update/update-downloaded-date-time/update-downloaded-date-time.injectable.ts rename src/main/application-update/{update-warning-level => restart-and-install-update}/restart-and-install-update.listener.ts (90%) delete mode 100644 src/main/application-update/update-warning-level/update-downloaded-date.injectable.ts create mode 100644 src/renderer/components/update-button/update-warning-level.injectable.ts diff --git a/src/behaviours/application-update/installing-update-using-topbar-button.test.tsx b/src/behaviours/application-update/installing-update-using-topbar-button.test.tsx index a2f1d9be5e..5f01233820 100644 --- a/src/behaviours/application-update/installing-update-using-topbar-button.test.tsx +++ b/src/behaviours/application-update/installing-update-using-topbar-button.test.tsx @@ -11,7 +11,6 @@ import checkForPlatformUpdatesInjectable from "../../main/application-update/che import type { DownloadPlatformUpdate } from "../../main/application-update/download-platform-update/download-platform-update.injectable"; import downloadPlatformUpdateInjectable from "../../main/application-update/download-platform-update/download-platform-update.injectable"; import publishIsConfiguredInjectable from "../../main/application-update/publish-is-configured.injectable"; -import periodicalCheckForUpdateWarningInjectable from "../../main/application-update/update-warning-level/periodical-check-for-update-warning.injectable"; import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable"; import closeWindowInjectable from "../../renderer/components/layout/top-bar/close-window.injectable"; import goBackInjectable from "../../renderer/components/layout/top-bar/go-back.injectable"; @@ -22,6 +21,7 @@ import toggleMaximizeWindowInjectable from "../../renderer/components/layout/top import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import restartAndInstallUpdateInjectable from "../../renderer/components/update-button/restart-and-install-update.injectable"; +import processCheckingForUpdatesInjectable from "../../main/application-update/check-for-updates/process-checking-for-updates.injectable"; function daysToMilliseconds(days: number) { return Math.round(days * 24 * 60 * 60 * 1000); @@ -53,9 +53,6 @@ describe("encourage user to update when sufficient time passed since update was mainDi.override(electronUpdaterIsActiveInjectable, () => true); mainDi.override(publishIsConfiguredInjectable, () => true); - mainDi.unoverride(periodicalCheckForUpdateWarningInjectable); - mainDi.permitSideEffects(periodicalCheckForUpdateWarningInjectable); - rendererDi.override(restartAndInstallUpdateInjectable, () => restartAndInstallUpdate = jest.fn()); // TODO: Remove below lines when TopBar are free from side-effects @@ -96,8 +93,9 @@ describe("encourage user to update when sufficient time passed since update was let processCheckingForUpdatesPromise: Promise; beforeEach(async () => { - // TODO: initiate update check process automatically, not from tray - processCheckingForUpdatesPromise = applicationBuilder.tray.click("check-for-updates"); + const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable); + + processCheckingForUpdatesPromise = processCheckingForUpdates("irrelevant"); }); describe("when update downloaded", () => { @@ -112,7 +110,7 @@ describe("encourage user to update when sufficient time passed since update was it("shows update button to help user to update", () => { const button = rendered.queryByTestId("update-button"); - + expect(button).toBeInTheDocument(); }); @@ -148,7 +146,7 @@ describe("encourage user to update when sufficient time passed since update was const button = rendered.queryByTestId("update-button"); act(() => button?.click()); - + act(() => button?.click()); expect(restartAndInstallUpdate).not.toBeCalled(); diff --git a/src/common/application-update/update-warning-level/restart-and-install-update-channel.injectable.ts b/src/common/application-update/restart-and-install-update-channel/restart-and-install-update-channel.injectable.ts similarity index 100% rename from src/common/application-update/update-warning-level/restart-and-install-update-channel.injectable.ts rename to src/common/application-update/restart-and-install-update-channel/restart-and-install-update-channel.injectable.ts diff --git a/src/common/application-update/update-downloaded-date-time/update-downloaded-date-time.injectable.ts b/src/common/application-update/update-downloaded-date-time/update-downloaded-date-time.injectable.ts new file mode 100644 index 0000000000..32a15d310a --- /dev/null +++ b/src/common/application-update/update-downloaded-date-time/update-downloaded-date-time.injectable.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import createSyncBoxInjectable from "../../utils/sync-box/create-sync-box.injectable"; +import { syncBoxInjectionToken } from "../../utils/sync-box/sync-box-injection-token"; + +const updateDownloadedDateTimeInjectable = getInjectable({ + id: "update-downloaded-date-time", + + instantiate: (di) => { + const createSyncBox = di.inject(createSyncBoxInjectable); + + return createSyncBox( + "update-downloaded-date-time", + null, + ); + }, + + injectionToken: syncBoxInjectionToken, +}); + +export default updateDownloadedDateTimeInjectable; diff --git a/src/main/application-update/download-update/download-update.injectable.ts b/src/main/application-update/download-update/download-update.injectable.ts index d0ac141b9c..f68b5166c0 100644 --- a/src/main/application-update/download-update/download-update.injectable.ts +++ b/src/main/application-update/download-update/download-update.injectable.ts @@ -9,6 +9,8 @@ import discoveredUpdateVersionInjectable from "../../../common/application-updat import { action, runInAction } from "mobx"; import type { ProgressOfDownload } from "../../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; import progressOfUpdateDownloadInjectable from "../../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; +import { getCurrentDateTime } from "../../../common/utils/date/get-current-date-time"; +import updateDownloadedDateTimeInjectable from "../../../common/application-update/update-downloaded-date-time/update-downloaded-date-time.injectable"; const downloadUpdateInjectable = getInjectable({ id: "download-update", @@ -18,6 +20,7 @@ const downloadUpdateInjectable = getInjectable({ const downloadingUpdateState = di.inject(updateIsBeingDownloadedInjectable); const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable); const progressOfUpdateDownload = di.inject(progressOfUpdateDownloadInjectable); + const updateDownloadedDate = di.inject(updateDownloadedDateTimeInjectable); const updateDownloadProgress = action((progressOfDownload: ProgressOfDownload) => { progressOfUpdateDownload.set(progressOfDownload); @@ -38,6 +41,10 @@ const downloadUpdateInjectable = getInjectable({ discoveredVersionState.set(null); } + const currentDateTime = getCurrentDateTime(); + + updateDownloadedDate.set(currentDateTime); + downloadingUpdateState.set(false); }); diff --git a/src/main/application-update/update-warning-level/restart-and-install-update.listener.ts b/src/main/application-update/restart-and-install-update/restart-and-install-update.listener.ts similarity index 90% rename from src/main/application-update/update-warning-level/restart-and-install-update.listener.ts rename to src/main/application-update/restart-and-install-update/restart-and-install-update.listener.ts index d1c612846d..0580114885 100644 --- a/src/main/application-update/update-warning-level/restart-and-install-update.listener.ts +++ b/src/main/application-update/restart-and-install-update/restart-and-install-update.listener.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import restartAndInstallUpdateChannel from "../../../common/application-update/update-warning-level/restart-and-install-update-channel.injectable"; +import restartAndInstallUpdateChannel from "../../../common/application-update/restart-and-install-update-channel/restart-and-install-update-channel.injectable"; import { messageChannelListenerInjectionToken } from "../../../common/utils/channel/message-channel-listener-injection-token"; import quitAndInstallUpdateInjectable from "../quit-and-install-update.injectable"; 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 deleted file mode 100644 index 3d02dd6862..0000000000 --- a/src/main/application-update/update-warning-level/update-downloaded-date.injectable.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -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; diff --git a/src/renderer/components/update-button/restart-and-install-update.injectable.ts b/src/renderer/components/update-button/restart-and-install-update.injectable.ts index 5aecaafe2a..854e0a428f 100644 --- a/src/renderer/components/update-button/restart-and-install-update.injectable.ts +++ b/src/renderer/components/update-button/restart-and-install-update.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import restartAndInstallUpdateChannel from "../../../common/application-update/update-warning-level/restart-and-install-update-channel.injectable"; +import restartAndInstallUpdateChannel from "../../../common/application-update/restart-and-install-update-channel/restart-and-install-update-channel.injectable"; import messageToChannelInjectable from "../../utils/channel/message-to-channel.injectable"; const restartAndInstallUpdateInjectable = getInjectable({ diff --git a/src/renderer/components/update-button/update-button.tsx b/src/renderer/components/update-button/update-button.tsx index 7d0e030d06..85f86d8193 100644 --- a/src/renderer/components/update-button/update-button.tsx +++ b/src/renderer/components/update-button/update-button.tsx @@ -13,13 +13,11 @@ import type { IconProps } from "../icon"; import { Icon } from "../icon"; import { withInjectables } from "@ogre-tools/injectable-react"; import { observer } from "mobx-react"; -import updateWarningLevelInjectable from "../../../common/application-update/update-warning-level/update-warning-level.injectable"; import type { IComputedValue } from "mobx"; -import { computed } from "mobx"; import restartAndInstallUpdateInjectable from "./restart-and-install-update.injectable"; +import updateWarningLevelInjectable from "./update-warning-level.injectable"; -interface UpdateButtonProps extends HTMLAttributes { -} +interface UpdateButtonProps extends HTMLAttributes {} interface Dependencies { warningLevel: IComputedValue<"light" | "medium" | "high" | "">; @@ -72,14 +70,13 @@ export const NonInjectedUpdateButton = observer(({ warningLevel, update, id }: U ); }); -export const UpdateButton = withInjectables(NonInjectedUpdateButton, { - getProps: (di, props) => { - const warnignLevel = di.inject(updateWarningLevelInjectable); - - return { +export const UpdateButton = withInjectables( + NonInjectedUpdateButton, + { + getProps: (di, props) => ({ ...props, - warningLevel: computed(() => warnignLevel.value.get()), + warningLevel: di.inject(updateWarningLevelInjectable), update: di.inject(restartAndInstallUpdateInjectable), - }; + }), }, -}); +); diff --git a/src/renderer/components/update-button/update-warning-level.injectable.ts b/src/renderer/components/update-button/update-warning-level.injectable.ts new file mode 100644 index 0000000000..7db021c472 --- /dev/null +++ b/src/renderer/components/update-button/update-warning-level.injectable.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import { now as reactiveDateNow } from "mobx-utils"; +import updateDownloadedDateTimeInjectable from "../../../common/application-update/update-downloaded-date-time/update-downloaded-date-time.injectable"; + +const updateWarningLevelInjectable = getInjectable({ + id: "update-warning-level", + + instantiate: (di) => { + const updateDownloadedDateTime = di.inject(updateDownloadedDateTimeInjectable); + + return computed(() => { + const downloadedAt = updateDownloadedDateTime.value.get(); + + if (!downloadedAt) { + return ""; + } + + const ONE_DAY = 1000 * 60 * 60 * 24; + + const downloadedAtTimestamp = new Date(downloadedAt).getTime(); + const currentDateTimeTimestamp = reactiveDateNow(ONE_DAY); + + const elapsedTime = currentDateTimeTimestamp - downloadedAtTimestamp; + + const elapsedDays = elapsedTime / ONE_DAY; + + if (elapsedDays < 20) { + return "light"; + } + + if (elapsedDays >= 20 && elapsedDays < 25) { + return "medium"; + } + + return "high"; + }); + }, +}); + +export default updateWarningLevelInjectable;