Firmware upload is functional

This commit is contained in:
Pierre HUBERT 2024-10-07 22:13:47 +02:00
parent cef5b5aa5b
commit 2924d14281
3 changed files with 65 additions and 12 deletions

View File

@ -12,4 +12,22 @@ export class OTAAPI {
}) })
).data; ).data;
} }
/**
* Upload new OTA firwmare
*/
static async UploadFirmware(
platform: string,
version: string,
firmware: File
): Promise<void> {
const fd = new FormData();
fd.append("firmware", firmware);
await APIClient.exec({
method: "POST",
uri: `/ota/${platform}/${version}`,
formData: fd,
});
}
} }

View File

@ -1,3 +1,4 @@
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import { import {
Button, Button,
Dialog, Dialog,
@ -12,9 +13,12 @@ import {
styled, styled,
} from "@mui/material"; } from "@mui/material";
import React from "react"; import React from "react";
import { OTAAPI } from "../api/OTAApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { checkVersion } from "../utils/StringsUtils";
import { TextInput } from "../widgets/forms/TextInput"; import { TextInput } from "../widgets/forms/TextInput";
import { SemVer } from "semver";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
const VisuallyHiddenInput = styled("input")({ const VisuallyHiddenInput = styled("input")({
clip: "rect(0 0 0 0)", clip: "rect(0 0 0 0)",
@ -33,9 +37,32 @@ export function UploadUpdateDialog(p: {
onClose: () => void; onClose: () => void;
onCreated: () => void; onCreated: () => void;
}): React.ReactElement { }): React.ReactElement {
const alert = useAlert();
const snackbar = useSnackbar();
const loadingMessage = useLoadingMessage();
const [platform, setPlatform] = React.useState<string | undefined>(); const [platform, setPlatform] = React.useState<string | undefined>();
const [version, setVersion] = React.useState<string | undefined>(); const [version, setVersion] = React.useState<string | undefined>();
const [file, setFile] = React.useState<File | undefined>(); const [file, setFile] = React.useState<File | undefined>();
const canSubmit = platform && version && checkVersion(version) && file;
const upload = async () => {
try {
loadingMessage.show("Uploading firmware...");
await OTAAPI.UploadFirmware(platform!, version!, file!);
snackbar("Successfully uploaded new firmware!");
p.onCreated();
} catch (e) {
console.error(e);
alert(`Failed to upload firmware: ${e}`);
} finally {
loadingMessage.hide();
}
};
return ( return (
<Dialog open={true} onClose={p.onClose}> <Dialog open={true} onClose={p.onClose}>
<DialogTitle>Submit a new update</DialogTitle> <DialogTitle>Submit a new update</DialogTitle>
@ -67,15 +94,7 @@ export function UploadUpdateDialog(p: {
helperText="The version shall follow semantics requirements" helperText="The version shall follow semantics requirements"
value={version} value={version}
onValueChange={setVersion} onValueChange={setVersion}
checkValue={(v) => { checkValue={checkVersion}
try {
new SemVer(v, { loose: false });
return true;
} catch (e) {
console.error(e);
return false;
}
}}
/> />
<br /> <br />
@ -104,7 +123,9 @@ export function UploadUpdateDialog(p: {
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={p.onClose}>Cancel</Button> <Button onClick={p.onClose}>Cancel</Button>
<Button type="submit">Subscribe</Button> <Button type="submit" disabled={!canSubmit} onClick={upload}>
Upload
</Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
); );

View File

@ -1,3 +1,4 @@
import { SemVer } from "semver";
import { LenConstraint } from "../api/ServerApi"; import { LenConstraint } from "../api/ServerApi";
/** /**
@ -6,3 +7,16 @@ import { LenConstraint } from "../api/ServerApi";
export function lenValid(s: string, c: LenConstraint): boolean { export function lenValid(s: string, c: LenConstraint): boolean {
return s.length >= c.min && s.length <= c.max; return s.length >= c.min && s.length <= c.max;
} }
/**
* Check out whether a given version number respect semantics requirements or not
*/
export function checkVersion(v: string): boolean {
try {
new SemVer(v, { loose: false });
return true;
} catch (e) {
console.error(e);
return false;
}
}