From ca2697c1a894280563fa61af6492b6a4666cd1af Mon Sep 17 00:00:00 2001 From: Dmitriy Shilin Date: Fri, 19 Dec 2025 13:13:43 +0100 Subject: [PATCH] Allow to select firmware updater per file --- src/lib/device/updater_selector.ts | 30 ++++++++++++++++ src/ui/preact/navigation_component.tsx | 8 ++--- src/ui/preact/update_component.tsx | 47 +++++++++++++++++++++----- 3 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 src/lib/device/updater_selector.ts diff --git a/src/lib/device/updater_selector.ts b/src/lib/device/updater_selector.ts new file mode 100644 index 0000000..e6ef080 --- /dev/null +++ b/src/lib/device/updater_selector.ts @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2025 Tendry Lab + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Updater } from "@device-ui/lib/device/updater"; + +export enum UpdaterId { + // Updater type is unknown. + None, + + // Firmware updater. + Firmware, + + // UI updater. + UI, +} + +// Selected firmware updater. +export type UpdaterSelectorResult = { + id: UpdaterId; + updater: Updater | null; + error: Error | null; +}; + +// Firmware updater selector. +export interface UpdaterSelector { + // Select the firmware updater based on the given file name. + select(filename: string): UpdaterSelectorResult; +} diff --git a/src/ui/preact/navigation_component.tsx b/src/ui/preact/navigation_component.tsx index fccc8f5..cb89b6a 100644 --- a/src/ui/preact/navigation_component.tsx +++ b/src/ui/preact/navigation_component.tsx @@ -10,7 +10,7 @@ import { Locator } from "@device-ui/lib/device/locator"; import { Notificator } from "@device-ui/lib/system/notificator"; import { NotificationSeverity } from "@device-ui/lib/system/notification"; import { StateMonitor } from "@device-ui/lib/core/state_monitor"; -import { Updater } from "@device-ui/lib/device/updater"; +import { UpdaterSelector } from "@device-ui/lib/device/updater_selector"; import { MarkdownComponent } from "@device-ui/ui/preact/markdown_component"; import { UpdateComponent } from "@device-ui/ui/preact/update_component"; @@ -27,8 +27,8 @@ export type NavigationComponentProps = { // Notificator to send notifications. notificator: Notificator; - // Updater to perform the firmware update process. - updater: Updater; + // UpdaterSelector to select the updater for the firmware update process. + updaterSelector: UpdaterSelector; // Navigation bar logo. logo: JSX.Element; @@ -84,7 +84,7 @@ export class NavigationComponent extends Component< ); diff --git a/src/ui/preact/update_component.tsx b/src/ui/preact/update_component.tsx index ecd63b0..ff1437c 100644 --- a/src/ui/preact/update_component.tsx +++ b/src/ui/preact/update_component.tsx @@ -7,13 +7,18 @@ import { Component } from "preact"; import { ObjectMonitor } from "@device-ui/lib/core/object_monitor"; import { StateMonitor } from "@device-ui/lib/core/state_monitor"; -import { Updater } from "@device-ui/lib/device/updater"; + +import { + UpdaterId, + UpdaterSelector, + UpdaterSelectorResult, +} from "@device-ui/lib/device/updater_selector"; import "@device-ui/ui/preact/update_component.css"; export type UpdateComponentProps = { stateMonitor: StateMonitor; - updater: Updater; + updaterSelector: UpdaterSelector; }; type updateComponentState = { @@ -22,6 +27,7 @@ type updateComponentState = { isUpdating: boolean; updateError: string | null; updateFinished: boolean; + updaterId: UpdaterId; selectedFile: File | null; }; @@ -38,6 +44,7 @@ export class UpdateComponent isUpdating: false, updateError: null, updateFinished: false, + updaterId: UpdaterId.None, selectedFile: null, }; @@ -58,6 +65,7 @@ export class UpdateComponent isUpdating: false, updateError: null, updateFinished: false, + updaterId: UpdaterId.None, selectedFile: null, }); } @@ -69,6 +77,7 @@ export class UpdateComponent isUpdating: false, updateError: null, updateFinished: false, + updaterId: UpdaterId.None, selectedFile: null, }); } @@ -186,7 +195,14 @@ export class UpdateComponent return (
-

Updating firmware...

+ + {this.state.updaterId === UpdaterId.Firmware && ( +

Updating Firmware...

+ )} + {this.state.updaterId === UpdaterId.UI && ( +

Updating UI...

+ )} +

Please do not power off or reboot the device

@@ -216,10 +232,7 @@ export class UpdateComponent

-

- Update successfully finished. Check updated firmware version in - System Status card. -

+

Update successfully finished.

); @@ -274,6 +287,7 @@ export class UpdateComponent selectedFile: file, updateError: null, updateFinished: false, + updaterId: UpdaterId.None, }); }; @@ -283,6 +297,7 @@ export class UpdateComponent selectedFile: null, updateError: null, updateFinished: false, + updaterId: UpdaterId.None, }); if (this.fileInput) { this.fileInput.value = ""; @@ -297,9 +312,23 @@ export class UpdateComponent const buffer = await this.state.selectedFile.arrayBuffer(); const data = new Uint8Array(buffer); - this.setState({ ...this.state, isUpdating: true, updateError: null }); + let error: Error | null = null; + + const selectResult: UpdaterSelectorResult = + this.props.updaterSelector.select(this.state.selectedFile.name); - const error = await this.props.updater.update(data); + this.setState({ + ...this.state, + isUpdating: true, + updateError: null, + updaterId: selectResult.id, + }); + + if (!selectResult.error) { + error = await selectResult.updater!.update(data); + } else { + error = selectResult.error; + } if (error) { const errorMessage = `Update failed: ${error}`; console.error(`update_component: update failed: ${error}`);