Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/lib/device/updater_selector.ts
Original file line number Diff line number Diff line change
@@ -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;
}
8 changes: 4 additions & 4 deletions src/ui/preact/navigation_component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -84,7 +84,7 @@ export class NavigationComponent extends Component<

<UpdateComponent
stateMonitor={this.updateState}
updater={this.props.updater}
updaterSelector={this.props.updaterSelector}
/>
</>
);
Expand Down
47 changes: 38 additions & 9 deletions src/ui/preact/update_component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>;
updater: Updater;
updaterSelector: UpdaterSelector;
};

type updateComponentState = {
Expand All @@ -22,6 +27,7 @@ type updateComponentState = {
isUpdating: boolean;
updateError: string | null;
updateFinished: boolean;
updaterId: UpdaterId;
selectedFile: File | null;
};

Expand All @@ -38,6 +44,7 @@ export class UpdateComponent
isUpdating: false,
updateError: null,
updateFinished: false,
updaterId: UpdaterId.None,
selectedFile: null,
};

Expand All @@ -58,6 +65,7 @@ export class UpdateComponent
isUpdating: false,
updateError: null,
updateFinished: false,
updaterId: UpdaterId.None,
selectedFile: null,
});
}
Expand All @@ -69,6 +77,7 @@ export class UpdateComponent
isUpdating: false,
updateError: null,
updateFinished: false,
updaterId: UpdaterId.None,
selectedFile: null,
});
}
Expand Down Expand Up @@ -186,7 +195,14 @@ export class UpdateComponent
return (
<div className="update-updating">
<div className="update-spinner"></div>
<p className="update-updating-title">Updating firmware...</p>

{this.state.updaterId === UpdaterId.Firmware && (
<p className="update-updating-title">Updating Firmware...</p>
)}
{this.state.updaterId === UpdaterId.UI && (
<p className="update-updating-title">Updating UI...</p>
)}

<p className="update-updating-warning">
Please do not power off or reboot the device
</p>
Expand Down Expand Up @@ -216,10 +232,7 @@ export class UpdateComponent
</p>
</div>
<div className="update-success-message">
<p className="update-success-text">
Update successfully finished. Check updated firmware version in
System Status card.
</p>
<p className="update-success-text">Update successfully finished.</p>
</div>
</div>
);
Expand Down Expand Up @@ -274,6 +287,7 @@ export class UpdateComponent
selectedFile: file,
updateError: null,
updateFinished: false,
updaterId: UpdaterId.None,
});
};

Expand All @@ -283,6 +297,7 @@ export class UpdateComponent
selectedFile: null,
updateError: null,
updateFinished: false,
updaterId: UpdaterId.None,
});
if (this.fileInput) {
this.fileInput.value = "";
Expand All @@ -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}`);
Expand Down