diff --git a/src/common/auto-update/auto-update-state.injectable.ts b/src/common/auto-update/auto-update-state.injectable.ts new file mode 100644 index 0000000000..c250aa72b3 --- /dev/null +++ b/src/common/auto-update/auto-update-state.injectable.ts @@ -0,0 +1,54 @@ +/** + * 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" | "idle"; + +export class AutoUpdateState { + @observable private _state: AutoUpdateStateName; + private timerId: NodeJS.Timeout; + + constructor(state: AutoUpdateStateName = "idle") { + makeObservable(this); + + this.name = state; + } + + get name() : AutoUpdateStateName { + return this._state; + } + + set name(state: AutoUpdateStateName) { + this._state = state; + + this.triggerIdle(); + } + + private triggerIdle(): void { + clearTimeout(this.timerId); + this.timerId = null; + + switch(this.name) { + case "checking": + case "available": + case "downloading": + case "idle": + break; + + case "done": + case "not-available": + this.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/components/status-bar/auto-update-status-bar-item.tsx b/src/renderer/components/status-bar/auto-update-status-bar-item.tsx new file mode 100644 index 0000000000..80c89364f3 --- /dev/null +++ b/src/renderer/components/status-bar/auto-update-status-bar-item.tsx @@ -0,0 +1,59 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +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 { Spinner } from "../spinner"; + +interface Dependencies { + state: AutoUpdateState; +} + +const checking = () => <>
{"Checking for updates"}
; +const available = () =>
{"Update is available"}
; + +const notAvailable = () => { + + return
{"Update is currently not available"}
; +}; + +const downloading = () =>
{"Downloading update"}
; +const done = () =>
{"Done checking for updates"}
; + +const idle = () => <>; + +export const NonInjectedAutoUpdateComponent = observer(({ state }: Dependencies) => { + + switch(state.name) { + case "checking": + return checking(); + + case "available": + return available(); + + case "not-available": + return notAvailable(); + + case "downloading": + return downloading(); + + case "done": + return done(); + + default: + case "idle": + return idle(); + } + +}); + +export const AutoUpdateComponent = withInjectables(NonInjectedAutoUpdateComponent, { + getProps: (di, props) => ({ + state: di.inject(AutoUpdateStateInjectable), + ...props, + }), +}); diff --git a/src/renderer/components/status-bar/status-bar.tsx b/src/renderer/components/status-bar/status-bar.tsx index 9d08cfb1fa..038f78e32e 100644 --- a/src/renderer/components/status-bar/status-bar.tsx +++ b/src/renderer/components/status-bar/status-bar.tsx @@ -11,6 +11,7 @@ import { withInjectables } from "@ogre-tools/injectable-react"; import type { RegisteredStatusBarItems } from "./registered-status-bar-items.injectable"; import registeredStatusBarItemsInjectable from "./registered-status-bar-items.injectable"; import type { IComputedValue } from "mobx"; +import { AutoUpdateComponent } from "./auto-update-status-bar-item"; export interface StatusBarProps {} @@ -19,7 +20,9 @@ interface Dependencies { } const NonInjectedStatusBar = observer(({ items }: Dependencies & StatusBarProps) => { - const { left, right } = items.get(); + const { left: leftItems, right } = items.get(); + + const left = [AutoUpdateComponent, ...leftItems]; return (
diff --git a/src/renderer/ipc/register-ipc-listeners.injectable.ts b/src/renderer/ipc/register-ipc-listeners.injectable.ts index a37f983769..6868943a56 100644 --- a/src/renderer/ipc/register-ipc-listeners.injectable.ts +++ b/src/renderer/ipc/register-ipc-listeners.injectable.ts @@ -5,12 +5,14 @@ import { getInjectable } from "@ogre-tools/injectable"; import { registerIpcListeners } from "./register-listeners"; import listNamespacesForbiddenHandlerInjectable from "./list-namespaces-forbidden-handler.injectable"; +import AutoUpdateStateInjectable from "../../common/auto-update/auto-update-state.injectable"; const registerIpcListenersInjectable = getInjectable({ id: "register-ipc-listeners", instantiate: (di) => registerIpcListeners({ listNamespacesForbiddenHandler: di.inject(listNamespacesForbiddenHandlerInjectable), + updateState: di.inject(AutoUpdateStateInjectable), }), });