From 041141fe3946a6caae8eaff207c8bafa7c55bf64 Mon Sep 17 00:00:00 2001 From: Jim Ehrismann Date: Wed, 22 Jun 2022 19:43:33 -0400 Subject: [PATCH] using the update syncBox injectables directly for status bar notifications Signed-off-by: Jim Ehrismann --- ...cation-update-status-channel.injectable.ts | 3 +- .../discovered-update-version.injectable.ts | 14 +-- .../progress-of-update-download.injectable.ts | 3 + .../update-is-being-downloaded.injectable.ts | 3 + ...updates-are-being-discovered.injectable.ts | 3 + .../auto-update-state.injectable.ts | 67 ----------- ...ation-update-status-listener.injectable.ts | 14 +-- .../auto-update-status-bar-item.tsx | 107 ++++++++++-------- 8 files changed, 86 insertions(+), 128 deletions(-) delete mode 100644 src/common/auto-update/auto-update-state.injectable.ts diff --git a/src/common/application-update/application-update-status-channel.injectable.ts b/src/common/application-update/application-update-status-channel.injectable.ts index 1365fd19af..e87849e3a7 100644 --- a/src/common/application-update/application-update-status-channel.injectable.ts +++ b/src/common/application-update/application-update-status-channel.injectable.ts @@ -10,7 +10,8 @@ export type ApplicationUpdateStatusEventId = | "checking-for-updates" | "no-updates-available" | "download-for-update-started" - | "download-for-update-failed"; + | "download-for-update-failed" + | "download-for-update-succeeded"; // eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type ApplicationUpdateStatusChannelMessage = { eventId: ApplicationUpdateStatusEventId; version?: string }; diff --git a/src/common/application-update/discovered-update-version/discovered-update-version.injectable.ts b/src/common/application-update/discovered-update-version/discovered-update-version.injectable.ts index 60557de211..29e89d3ea3 100644 --- a/src/common/application-update/discovered-update-version/discovered-update-version.injectable.ts +++ b/src/common/application-update/discovered-update-version/discovered-update-version.injectable.ts @@ -5,21 +5,21 @@ import { getInjectable } from "@ogre-tools/injectable"; import createSyncBoxInjectable from "../../utils/sync-box/create-sync-box.injectable"; import type { UpdateChannel } from "../update-channels"; +import type { SyncBox } from "../../utils/sync-box/sync-box-injection-token"; import { syncBoxInjectionToken } from "../../utils/sync-box/sync-box-injection-token"; +export type DiscoveredUpdateVersion = SyncBox<{ version: string; updateChannel: UpdateChannel } | null>; + const discoveredUpdateVersionInjectable = getInjectable({ id: "discovered-update-version", instantiate: (di) => { const createSyncBox = di.inject(createSyncBoxInjectable); - return createSyncBox< - | { version: string; updateChannel: UpdateChannel } - | null - >( - "discovered-update-version", - null, - ); + return createSyncBox( + "discovered-update-version", + null, + ) as DiscoveredUpdateVersion; }, injectionToken: syncBoxInjectionToken, diff --git a/src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts b/src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts index 26ecd1d618..3473e845be 100644 --- a/src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts +++ b/src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts @@ -4,12 +4,15 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import createSyncBoxInjectable from "../../utils/sync-box/create-sync-box.injectable"; +import type { SyncBox } from "../../utils/sync-box/sync-box-injection-token"; import { syncBoxInjectionToken } from "../../utils/sync-box/sync-box-injection-token"; export interface ProgressOfDownload { percentage: number; } +export type ProgressOfUpdateDownload = SyncBox; + const progressOfUpdateDownloadInjectable = getInjectable({ id: "progress-of-update-download-state", diff --git a/src/common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable.ts b/src/common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable.ts index e1701d7952..0eae5779ed 100644 --- a/src/common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable.ts +++ b/src/common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable.ts @@ -4,8 +4,11 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import createSyncBoxInjectable from "../../utils/sync-box/create-sync-box.injectable"; +import type { SyncBox } from "../../utils/sync-box/sync-box-injection-token"; import { syncBoxInjectionToken } from "../../utils/sync-box/sync-box-injection-token"; +export type UpdateIsBeingDownloaded = SyncBox; + const updateIsBeingDownloadedInjectable = getInjectable({ id: "update-is-being-downloaded", diff --git a/src/common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable.ts b/src/common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable.ts index 21f1c14bec..97ff920af4 100644 --- a/src/common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable.ts +++ b/src/common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable.ts @@ -4,8 +4,11 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import createSyncBoxInjectable from "../../utils/sync-box/create-sync-box.injectable"; +import type { SyncBox } from "../../utils/sync-box/sync-box-injection-token"; import { syncBoxInjectionToken } from "../../utils/sync-box/sync-box-injection-token"; +export type UpdatesAreBeingDiscovered = SyncBox; + const updatesAreBeingDiscoveredInjectable = getInjectable({ id: "updates-are-being-discovered", diff --git a/src/common/auto-update/auto-update-state.injectable.ts b/src/common/auto-update/auto-update-state.injectable.ts deleted file mode 100644 index b024c733fa..0000000000 --- a/src/common/auto-update/auto-update-state.injectable.ts +++ /dev/null @@ -1,67 +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 { makeObservable, observable } from "mobx"; - -export type AutoUpdateStateName = "checking" | "available" | "not-available" | "done" | "downloading" | "download-failed" | "download-succeeded" | "idle"; - -let timerId: NodeJS.Timeout; - -export class AutoUpdateState { - @observable private _state: AutoUpdateStateName; - @observable private _version: string | undefined = undefined; - - constructor(state: AutoUpdateStateName = "idle") { - makeObservable(this); - - this._state = state; - } - - get name(): AutoUpdateStateName { - return this._state; - } - - set name(state: AutoUpdateStateName) { - this._state = state; - - this.triggerIdle(); - } - - get version(): string | undefined { - return this._version; - } - - set version(version: string | undefined) { - this._version = version; - - this.triggerIdle(); - } - - private triggerIdle(): void { - clearTimeout(timerId); - - switch (this.name) { - case "checking": - case "available": - case "downloading": - case "idle": - break; - - case "done": - case "not-available": - case "download-failed": - case "download-succeeded": - timerId = setTimeout(() => this.name = "idle", 5000); - break; - } - } -} - -const AutoUpdateStateInjectable = getInjectable({ - id: "auto-update-state", - instantiate: () => new AutoUpdateState("idle"), -}); - -export default AutoUpdateStateInjectable; diff --git a/src/renderer/application-update/application-update-status-listener.injectable.ts b/src/renderer/application-update/application-update-status-listener.injectable.ts index 9c5332c386..1e48c8f66c 100644 --- a/src/renderer/application-update/application-update-status-listener.injectable.ts +++ b/src/renderer/application-update/application-update-status-listener.injectable.ts @@ -8,7 +8,6 @@ import applicationUpdateStatusChannelInjectable from "../../common/application-u //import showInfoNotificationInjectable from "../components/notifications/show-info-notification.injectable"; import type { MessageChannelListener } from "../../common/utils/channel/message-channel-listener-injection-token"; import { messageChannelListenerInjectionToken } from "../../common/utils/channel/message-channel-listener-injection-token"; -import AutoUpdateStateInjectable from "../../common/auto-update/auto-update-state.injectable"; const applicationUpdateStatusListenerInjectable = getInjectable({ id: "application-update-status-listener", @@ -16,35 +15,34 @@ const applicationUpdateStatusListenerInjectable = getInjectable({ instantiate: (di): MessageChannelListener => { const channel = di.inject(applicationUpdateStatusChannelInjectable); //const showInfoNotification = di.inject(showInfoNotificationInjectable); - const autoUpdateState = di.inject(AutoUpdateStateInjectable); const eventHandlers: Record void }> = { "checking-for-updates": { handle: () => { //showInfoNotification("Checking for updates..."); - autoUpdateState.name = "checking"; }, }, "no-updates-available": { handle: () => { //showInfoNotification("No new updates available"); - autoUpdateState.name = "not-available"; }, }, "download-for-update-started": { - handle: (version) => { + handle: (/*version*/) => { //showInfoNotification(`Download for version ${version} started...`); - autoUpdateState.name = "downloading"; - autoUpdateState.version = version; }, }, "download-for-update-failed": { handle: () => { //showInfoNotification("Download of update failed"); - autoUpdateState.name = "download-failed"; + }, + }, + + "download-for-update-succeeded": { + handle: () => { }, }, }; diff --git a/src/renderer/components/status-bar/auto-update-status-bar-item.tsx b/src/renderer/components/status-bar/auto-update-status-bar-item.tsx index 702c427814..19e246e190 100644 --- a/src/renderer/components/status-bar/auto-update-status-bar-item.tsx +++ b/src/renderer/components/status-bar/auto-update-status-bar-item.tsx @@ -4,30 +4,58 @@ */ import { withInjectables } from "@ogre-tools/injectable-react"; import { observer } from "mobx-react"; -import React from "react"; -import AutoUpdateStateInjectable from "../../../common/auto-update/auto-update-state.injectable"; -import type { AutoUpdateState } from "../../../common/auto-update/auto-update-state.injectable"; +import assert from "assert"; +import React, { useEffect, useState } from "react"; import { Spinner } from "../spinner"; +import type { ProgressOfUpdateDownload } 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 type { ProgressOfDownload } from "../../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; -import type { SyncBox } from "../../../common/utils/sync-box/sync-box-injection-token"; +import type { DiscoveredUpdateVersion } from "../../../common/application-update/discovered-update-version/discovered-update-version.injectable"; +import discoveredUpdateVersionInjectable from "../../../common/application-update/discovered-update-version/discovered-update-version.injectable"; +import type { UpdateIsBeingDownloaded } from "../../../common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable"; +import updateIsBeingDownloadedInjectable from "../../../common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable"; +import type { UpdatesAreBeingDiscovered } from "../../../common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable"; +import updatesAreBeingDiscoveredInjectable from "../../../common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable"; interface Dependencies { - state: AutoUpdateState; - progressOfUpdateDownload: SyncBox; + progressOfUpdateDownload: ProgressOfUpdateDownload; + discoveredVersionState: DiscoveredUpdateVersion; + downloadingUpdateState: UpdateIsBeingDownloaded; + checkingForUpdatesState: UpdatesAreBeingDiscovered; } +interface EndNoteProps { + version?: string; + note: (version: string) => JSX.Element; +} + +const EndNote = ({ version, note }: EndNoteProps) => { + const [idling, setIdling] = useState(false); + + useEffect(() => { + const timerId = setTimeout(() => setIdling(true), 5000); + + return () => clearTimeout(timerId); + }); + + if (idling) { + return idle(); + } + + return note(version ?? ""); +}; + const checking = () => ( <>
{"Checking for updates..."}
); -const available = () =>
{"Update is available"}
; -const notAvailable = () =>
{"No new updates available"}
; -const downloading = (state: AutoUpdateState, percentDone: number) => { - const { version } = state; +const available = (version: string) =>
{`${version ?? "Update"} is available`}
; + +const notAvailable = () =>
{"No new updates available"}
; + +const downloading = (version: string, percentDone: number) => { if ( percentDone === 0 ) { return ( <> @@ -37,57 +65,46 @@ const downloading = (state: AutoUpdateState, percentDone: number) => { ); } - if ( percentDone < 100 ) { - return
{`Download for version ${version} ${percentDone}%...`}
; - } - - state.name = "download-succeeded"; - - return null; + return
{`Download for version ${version} ${percentDone}%...`}
; }; -const done = () =>
{"Done checking for updates"}
; -const downloadFailed = (version: string | undefined) =>
{`Download for version ${version} failed`}
; -const downloadSucceeded = (version: string | undefined) =>
{`Download for version ${version} complete`}
; +const downloadSucceeded = (version: string) =>
{`Download for version ${version} complete`}
; + const idle = () => <>; -export const NonInjectedAutoUpdateComponent = observer(({ state, progressOfUpdateDownload }: Dependencies) => { +export const NonInjectedAutoUpdateComponent = observer(({ progressOfUpdateDownload, discoveredVersionState, downloadingUpdateState, checkingForUpdatesState }: Dependencies) => { + const discoveredVersion = discoveredVersionState.value.get(); - switch(state.name) { - case "checking": - return checking(); + if (downloadingUpdateState.value.get()) { - case "available": - return available(); + assert(discoveredVersion); - case "not-available": - return notAvailable(); + const roundedPercentage = Math.round(progressOfUpdateDownload.value.get().percentage); - case "downloading": { - const roundedPercentage = Math.round(progressOfUpdateDownload.value.get().percentage); - - return downloading(state, roundedPercentage); + if ( roundedPercentage > 99 ) { + return ; } - case "done": - return done(); - - case "download-failed": - return downloadFailed(state.version); - - case "download-succeeded": - return downloadSucceeded(state.version); - - case "idle": - return idle(); + return downloading(discoveredVersion.version, roundedPercentage); } + if (checkingForUpdatesState.value.get()) { + return checking(); + } + + if ( discoveredVersion) { + return ; + } + + return ; }); export const AutoUpdateComponent = withInjectables(NonInjectedAutoUpdateComponent, { getProps: (di, props) => ({ - state: di.inject(AutoUpdateStateInjectable), progressOfUpdateDownload: di.inject(progressOfUpdateDownloadInjectable), + discoveredVersionState: di.inject(discoveredUpdateVersionInjectable), + downloadingUpdateState: di.inject(updateIsBeingDownloadedInjectable), + checkingForUpdatesState: di.inject(updatesAreBeingDiscoveredInjectable), ...props, }), });