CEC-179 Car download progress (#32)

* Display download progress

* Change default

* Fix

* Fix

* Update readme

* Update readme and defaults
Fix Dockerfile
This commit is contained in:
John Wu
2021-04-30 12:58:31 -07:00
committed by GitHub
parent 7a1125cb1f
commit 4280191e49
21 changed files with 268 additions and 72 deletions

View File

@@ -8,7 +8,6 @@ export const FileUploadProvider = ({ children }) => {
const [progress, setProgress] = useState(0);
const [status, setStatus] = useState(null);
const [cancelUpload, setCancelUpload] = useState(null);
const [linkURL, setLinkURL] = useState(null);
const [files, setFiles] = useState(null);
const done = () => {
@@ -45,6 +44,14 @@ export const FileUploadProvider = ({ children }) => {
if (!accessToken || accessToken.length === 0) {
throw new Error("Access token required");
}
if (!formData.description || formData.description.length === 0) {
throw new Error("Package update description required");
}
if (!formData.releasenotes || formData.releasenotes.length === 0) {
throw new Error("Package update release notes link required");
}
};
const upload = async (formData, accessToken, uploadFiles) => {
@@ -55,7 +62,6 @@ export const FileUploadProvider = ({ children }) => {
const filename = file.name;
setUploading(true);
setLinkURL(null);
setProgress(0);
setStatus(`Uploading ${filename}`);
setCancelUpload(getCancelToken());
@@ -70,11 +76,11 @@ export const FileUploadProvider = ({ children }) => {
if (data.message) {
throw new Error(`${data.error}. ${data.message}`);
}
const url = data && data.link ? data.link : "No URL available";
setLinkURL(url);
setStatus(`Uploaded ${filename}`);
setCancelUpload(null);
setProgress(100);
return data;
} catch (e) {
setUploading(true);
setStatus(`Error occured: ${e.message}`);
@@ -88,7 +94,6 @@ export const FileUploadProvider = ({ children }) => {
uploading,
progress,
status,
linkURL,
files,
upload,
cancel,

View File

@@ -7,6 +7,7 @@ import {
fireEvent,
waitFor,
} from "@testing-library/react";
import { useState } from "react";
import { setUploadFileDelay } from "../../services/uploadFile";
import {
@@ -30,21 +31,26 @@ describe("FileUploadContext", () => {
progress,
uploading,
status,
linkURL,
upload,
cancel,
} = useFileUploadContext();
const { message, setMessage } = useStatusContext();
const [link, setLink] = useState(null);
const TEST_FILE = [{ name: "test.jpg", size: 0 }];
const TEST_ACCESSTOKEN = "ACCESSTOKEN";
const TEST_FORMDATA = {
packagename: "TEST",
version: "VERSION",
vehicles: ["VIN"],
description: "TEST DESC",
releasenotes: "http://releasenotes.com",
};
const exec = async (form, token, file) => {
try {
await upload(form, token, file);
const data = await upload(form, token, file);
if (data.link) {
setLink(data.link);
}
} catch (e) {
setMessage(e.message);
}
@@ -56,7 +62,7 @@ describe("FileUploadContext", () => {
<div data-testid="progress">{progress.toString()}</div>
<div data-testid="status">{status}</div>
<div data-testid="message">{message}</div>
<div data-testid="linkURL">{linkURL}</div>
<div data-testid="linkURL">{link}</div>
<button
data-testid="uploadNoFile"
onClick={() => {

View File

@@ -10,6 +10,8 @@ export const UpdatesProvider = ({ children }) => {
const [carUpdates, setCarUpdates] = useState([]);
const [totalPackages, setTotalPackages] = useState(0);
const [totalCarUpdates, setTotalCarUpdates] = useState(0);
const [delayCount, setDelayCount] = useState(0);
let progressTimer = 0;
const getPackages = async (search, token) => {
let result;
@@ -96,6 +98,86 @@ export const UpdatesProvider = ({ children }) => {
return result;
};
const applyProgressStatus = (item, status) => {
if (status.msg === "DONE") {
delete item.progress;
item.status = "downloaded";
} else if (status.msg === "downloading" && status.total > 0) {
let progress = Math.floor((100 * status.bytes) / status.total);
if (progress > 99) progress = 0;
item.progress = progress;
item.status = `downloading ${progress}%`;
} else if (status.error > 0) {
item.status = "download error";
} else {
item.status = "downloading";
}
};
const applyProgressStatuses = (statuses) => {
let items = JSON.parse(JSON.stringify(carUpdates));
statuses.forEach((status) => {
let item = items.find((item) => status.id === item.id);
if (!item || status.id === 0) return;
applyProgressStatus(item, status);
});
setCarUpdates(items);
};
const updateStatusProgress = async (token) => {
stopMonitor();
if (!token || carUpdates.length === 0) return;
try {
setBusy(true);
const carupdateids = carUpdates.reduce((accum, update) => {
if (update.status !== "downloaded") accum.push(update.id);
return accum;
}, []);
if (carupdateids.length === 0) return;
const result = await api.getCarUpdateProgress(
carupdateids.join(","),
token
);
if (result.error)
throw new Error(`Get update progress error. ${result.message}`);
applyProgressStatuses(result.statuses);
} catch (e) {
} finally {
setBusy(false);
}
};
const getDelay = () => {
if (delayCount < 3) {
setDelayCount(delayCount + 1);
return 1000;
}
for (let i = 0, len = carUpdates.length; i < len; i++) {
if (carUpdates[i].status.indexOf("downloading") > -1) return 1000;
}
return 10000;
};
const startMonitor = async (token) => {
const delay = getDelay();
stopMonitor();
progressTimer = setTimeout(() => {
updateStatusProgress(token);
}, delay);
};
const stopMonitor = async () => {
if (progressTimer === 0) return;
clearTimeout(progressTimer);
progressTimer = 0;
};
return (
<UpdatesContext.Provider
value={{
@@ -109,6 +191,8 @@ export const UpdatesProvider = ({ children }) => {
createCarUpdates,
getCarUpdates,
getVINUpdates,
startMonitor,
stopMonitor,
}}
>
{children}

View File

@@ -23,4 +23,6 @@ export const useUpdatesContext = () => ({
createCarUpdates: jest.fn((data) => data),
getCarUpdates: jest.fn(() => carUpdates),
getVINUpdates: jest.fn(() => carUpdates),
startMonitor: jest.fn(),
stopMonitor: jest.fn(),
});