Firmware upload is functional
This commit is contained in:
		@@ -12,4 +12,22 @@ export class OTAAPI {
 | 
			
		||||
      })
 | 
			
		||||
    ).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,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
 | 
			
		||||
import {
 | 
			
		||||
  Button,
 | 
			
		||||
  Dialog,
 | 
			
		||||
@@ -12,9 +13,12 @@ import {
 | 
			
		||||
  styled,
 | 
			
		||||
} from "@mui/material";
 | 
			
		||||
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 { SemVer } from "semver";
 | 
			
		||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
 | 
			
		||||
 | 
			
		||||
const VisuallyHiddenInput = styled("input")({
 | 
			
		||||
  clip: "rect(0 0 0 0)",
 | 
			
		||||
@@ -33,9 +37,32 @@ export function UploadUpdateDialog(p: {
 | 
			
		||||
  onClose: () => void;
 | 
			
		||||
  onCreated: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const alert = useAlert();
 | 
			
		||||
  const snackbar = useSnackbar();
 | 
			
		||||
  const loadingMessage = useLoadingMessage();
 | 
			
		||||
 | 
			
		||||
  const [platform, setPlatform] = React.useState<string | undefined>();
 | 
			
		||||
  const [version, setVersion] = React.useState<string | 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 (
 | 
			
		||||
    <Dialog open={true} onClose={p.onClose}>
 | 
			
		||||
      <DialogTitle>Submit a new update</DialogTitle>
 | 
			
		||||
@@ -67,15 +94,7 @@ export function UploadUpdateDialog(p: {
 | 
			
		||||
          helperText="The version shall follow semantics requirements"
 | 
			
		||||
          value={version}
 | 
			
		||||
          onValueChange={setVersion}
 | 
			
		||||
          checkValue={(v) => {
 | 
			
		||||
            try {
 | 
			
		||||
              new SemVer(v, { loose: false });
 | 
			
		||||
              return true;
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
              console.error(e);
 | 
			
		||||
              return false;
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
          checkValue={checkVersion}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <br />
 | 
			
		||||
@@ -104,7 +123,9 @@ export function UploadUpdateDialog(p: {
 | 
			
		||||
      </DialogContent>
 | 
			
		||||
      <DialogActions>
 | 
			
		||||
        <Button onClick={p.onClose}>Cancel</Button>
 | 
			
		||||
        <Button type="submit">Subscribe</Button>
 | 
			
		||||
        <Button type="submit" disabled={!canSubmit} onClick={upload}>
 | 
			
		||||
          Upload
 | 
			
		||||
        </Button>
 | 
			
		||||
      </DialogActions>
 | 
			
		||||
    </Dialog>
 | 
			
		||||
  );
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
import { SemVer } from "semver";
 | 
			
		||||
import { LenConstraint } from "../api/ServerApi";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -6,3 +7,16 @@ import { LenConstraint } from "../api/ServerApi";
 | 
			
		||||
export function lenValid(s: string, c: LenConstraint): boolean {
 | 
			
		||||
  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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user