Browse Source

Custom firmware upload

pull/110/head
Malte Grimm 3 years ago
parent
commit
872da63b7d
  1. 1
      package.json
  2. 6
      pnpm-lock.yaml
  3. 25
      src/components/Dashboard.tsx
  4. 25
      src/core/flashing/Flasher.ts

1
package.json

@ -75,6 +75,7 @@
"@types/web-bluetooth": "^0.0.16", "@types/web-bluetooth": "^0.0.16",
"@typescript-eslint/eslint-plugin": "^5.53.0", "@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0", "@typescript-eslint/parser": "^5.53.0",
"@types/wicg-file-system-access": "^2020.9.6",
"@vitejs/plugin-react": "^3.1.0", "@vitejs/plugin-react": "^3.1.0",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"eslint": "^8.34.0", "eslint": "^8.34.0",

6
pnpm-lock.yaml

@ -31,6 +31,7 @@ specifiers:
'@types/react-dom': ^18.0.11 '@types/react-dom': ^18.0.11
'@types/w3c-web-serial': ^1.0.3 '@types/w3c-web-serial': ^1.0.3
'@types/web-bluetooth': ^0.0.16 '@types/web-bluetooth': ^0.0.16
'@types/wicg-file-system-access': ^2020.9.6
'@typescript-eslint/eslint-plugin': ^5.53.0 '@typescript-eslint/eslint-plugin': ^5.53.0
'@typescript-eslint/parser': ^5.53.0 '@typescript-eslint/parser': ^5.53.0
'@vitejs/plugin-react': ^3.1.0 '@vitejs/plugin-react': ^3.1.0
@ -131,6 +132,7 @@ devDependencies:
'@types/react-dom': 18.0.11 '@types/react-dom': 18.0.11
'@types/w3c-web-serial': 1.0.3 '@types/w3c-web-serial': 1.0.3
'@types/web-bluetooth': 0.0.16 '@types/web-bluetooth': 0.0.16
'@types/wicg-file-system-access': 2020.9.6
'@typescript-eslint/eslint-plugin': 5.53.0_ny4s7qc6yg74faf3d6xty2ofzy '@typescript-eslint/eslint-plugin': 5.53.0_ny4s7qc6yg74faf3d6xty2ofzy
'@typescript-eslint/parser': 5.53.0_7kw3g6rralp5ps6mg3uyzz6azm '@typescript-eslint/parser': 5.53.0_7kw3g6rralp5ps6mg3uyzz6azm
'@vitejs/plugin-react': 3.1[email protected] '@vitejs/plugin-react': 3.1[email protected]
@ -3806,6 +3808,10 @@ packages:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
dev: true dev: true
/@types/wicg-file-system-access/2020.9.6:
resolution: {integrity: sha512-6hogE75Hl2Ov/jgp8ZhDaGmIF/q3J07GtXf8nCJCwKTHq7971po5+DId7grft09zG7plBwpF6ZU0yx9Du4/e1A==}
dev: true
/@typescript-eslint/eslint-plugin/5.53.0_ny4s7qc6yg74faf3d6xty2ofzy: /@typescript-eslint/eslint-plugin/5.53.0_ny4s7qc6yg74faf3d6xty2ofzy:
resolution: {integrity: sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==} resolution: {integrity: sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}

25
src/components/Dashboard.tsx

@ -23,6 +23,7 @@ import {
nextBatch, nextBatch,
OverallFlashingState, OverallFlashingState,
setup, setup,
uploadCustomFirmware,
} from '@app/core/flashing/Flasher'; } from '@app/core/flashing/Flasher';
import { import {
ConfigPreset, ConfigPreset,
@ -450,23 +451,37 @@ const FirmwareSelection = () => {
} }
else { else {
const versions = firmwareList.map((f, index) => ( const versions = firmwareList.map((f, index) => (
<SelectItem key={index} value={f.name}> <SelectItem key={index} value={f.id}>
<div className="flex gap-2 items-center">{f.name} {f.inLocalDb ? <ArrowDownCircleIcon size={20}/> : <div/>}</div> <div className="flex gap-2 items-center">{f.name} {f.inLocalDb ? <ArrowDownCircleIcon size={20}/> : <div/>}</div>
</SelectItem> </SelectItem>
)) ))
selectItems.push(...versions); selectItems.push(...versions);
} }
selectItems.push( selectItems.push(
<SelectItem key={100} value={"custom"}> <SelectItem key={100} value={"custom"}>
{"< Select custom firmware >"} {"< Load custom firmware >"}
</SelectItem> </SelectItem>
); );
return ( return (
<div className="flex gap-1 w-full"> <div className="flex gap-1 w-full">
<Select <Select
disabled={firmwareRefreshing} disabled={firmwareRefreshing}
onValueChange={setSelectedFirmware} onValueChange={async (v) => {
if(v == "custom") {
const desc = await uploadCustomFirmware();
if(desc === undefined)
return;
if(!firmwareList.find(f => f.id == desc.id)) {
const newFirmwareList: FirmwareVersion[] = firmwareList.map(f => f).concat([ desc ]);
setFirmwareList(newFirmwareList);
}
setSelectedFirmware(desc.id);
}
else {
setSelectedFirmware(v);
}
}}
value={selection} // << Value of selected item value={selection} // << Value of selected item
> >
<SelectTrigger> <SelectTrigger>

25
src/core/flashing/Flasher.ts

@ -99,6 +99,31 @@ async function loadFromDb(firmware: FirmwareVersion) {
}); });
} }
export async function uploadCustomFirmware() {
//@ts-ignore
const promise: Promise<FileSystemFileHandle[]> = window.showOpenFilePicker({
types: [ { description: "ZIP file", accept: { "application/zip": [".zip"] } }]
});
const fileHandle: FileSystemFileHandle | undefined = await promise.then(f => f[0], () => undefined);
if(fileHandle == undefined)
return undefined;
try {
const file = await fileHandle.getFile();
const content = await file.arrayBuffer();
const firmwareDesc: FirmwareVersion = {
id: "custom_" + file.name,
name: file.name,
inLocalDb: true,
tag: "custom_" + file.name
}
storeInDb(firmwareDesc, content);
return firmwareDesc;
} catch {
console.error("Insufficient permission to access file.");
}
return undefined;
}
function store(db: IDBDatabase, firmware: FirmwareVersion, file: ArrayBuffer) { function store(db: IDBDatabase, firmware: FirmwareVersion, file: ArrayBuffer) {
debugger; debugger;
const fileStore = db.transaction("files", "readwrite").objectStore("files"); const fileStore = db.transaction("files", "readwrite").objectStore("files");

Loading…
Cancel
Save