Added better auto-update handling. RPS-17

This commit is contained in:
Patrick Fic
2020-10-27 10:21:55 -07:00
parent cab6df75fe
commit 41f0682fd5
14 changed files with 249 additions and 54 deletions

View File

@@ -78,3 +78,13 @@ body {
.ant-tabs-content {
height: 100%;
}
.blink_me {
animation: blinker 1s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0;
}
}

View File

@@ -1,9 +0,0 @@
.blink_me {
animation: blinker 1s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0;
}
}

View File

@@ -0,0 +1,124 @@
import { AlertFilled } from "@ant-design/icons";
import { Button, Layout, Progress } from "antd";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import ipcTypes from "../../../ipc.types";
import {
selectUpdateAvailable,
selectUpdateProgress,
} from "../../../redux/application/application.selectors";
const { ipcRenderer } = window;
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
updateAvailable: selectUpdateAvailable,
updateProgress: selectUpdateProgress,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function UpdateManagerOrganism({ updateAvailable, updateProgress }) {
if (!updateAvailable) return null;
return (
<Layout.Footer>
{updateAvailable && !updateProgress && (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div>
<AlertFilled
style={{ marginRight: ".5rem", color: "tomato" }}
className="blink_me"
/>
<span>{`An update to ImEX RPS is available. (Version ${updateAvailable.version})`}</span>
</div>
<Button
type="primary"
style={{ margin: "0rem .5rem" }}
onClick={() =>
ipcRenderer.send(ipcTypes.default.app.toMain.downloadUpdates)
}
>
Download
</Button>
</div>
)}
{updateAvailable && updateProgress && (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Progress
style={{ flex: 1, margin: "0rem .5rem" }}
status={updateProgress.percent === 100 ? "success" : "active"}
percent={updateProgress.percent.toFixed(1)}
/>
{updateProgress.percent === 100 ? (
<div tyle={{ margin: "0rem .5rem" }}>
<span
style={{ margin: "0rem .5rem" }}
>{`Updated downloaded.`}</span>
<Button
type="primary"
style={{ margin: "0rem .5rem" }}
onClick={() =>
ipcRenderer.send(ipcTypes.default.app.toMain.installUpdates)
}
>
Install
</Button>
</div>
) : (
<span
style={{ margin: "0rem .5rem" }}
>{`Downloading update at ${formatBytes(
updateProgress.bytesPerSecond
)})`}</span>
)}
</div>
)}
</Layout.Footer>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(UpdateManagerOrganism);
// download Info
// {
// // bytesPerSecond: 6633258;
// // delta: 2479242;
// // percent: 100;
// // total: 95651575;
// // transferred: 95651575;
// }
function formatBytes(bytes) {
var marker = 1024; // Change to 1000 if required
var decimal = 1; // Change as required
var kiloBytes = marker; // One Kilobyte is 1024 bytes
var megaBytes = marker * marker; // One MB is 1024 KB
var gigaBytes = marker * marker * marker; // One GB is 1024 MB
//var teraBytes = marker * marker * marker * marker; // One TB is 1024 GB
// return bytes if less than a KB
if (bytes < kiloBytes) return bytes + " Bytes/sec";
// return KB if less than a MB
else if (bytes < megaBytes)
return (bytes / kiloBytes).toFixed(decimal) + " KB/sec";
// return MB if less than a GB
else if (bytes < gigaBytes)
return (bytes / megaBytes).toFixed(decimal) + " MB/sec";
// return GB if less than a TB
else return (bytes / gigaBytes).toFixed(decimal) + " GB/sec";
}

View File

@@ -6,6 +6,7 @@ import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../../redux/user/user.selectors";
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
import SiderMenuOrganism from "../../organisms/sider-menu/sider-menu.organism";
import UpdateManagerOrganism from "../../organisms/update-manager/update-manager.organism";
import JobsPage from "../jobs/jobs.page";
import ReportingPage from "../reporting/reporting.page";
import ScanPage from "../scan/scan.page";
@@ -39,6 +40,8 @@ export function RoutesPage({ bodyshop }) {
<Route exact path="/scan" component={ScanPage} />
<Route exact path="/" component={JobsPage} />
</Layout.Content>
<UpdateManagerOrganism />
</Layout>
</Layout>
);

View File

@@ -9,6 +9,13 @@ exports.default = {
setAcceptableInsCoNm: "setAcceptableInsCoNm",
setUserName: "setUserName",
track: "analytics_track",
checkForUpdates: "app_checkForUpdates",
downloadUpdates: "app_downloadUpdates",
installUpdates: "app_installupdates",
},
toRenderer: {
updateAvailable: "app_updateAvailable",
downloadProgress: "app_downloadProgress",
},
},
store: {

View File

@@ -1,6 +1,8 @@
import ipcTypes from "../ipc.types";
import {
setSettings,
setUpdateAvailable,
setUpdateProgress,
setWatchedPaths,
setWatcherStatus,
} from "../redux/application/application.actions";
@@ -65,3 +67,16 @@ ipcRenderer.on(
store.dispatch(setScanEstimateList(listOfEstimates));
}
);
ipcRenderer.on(
ipcTypes.default.app.toRenderer.updateAvailable,
async (event, updateInfo) => {
store.dispatch(setUpdateAvailable(updateInfo));
}
);
ipcRenderer.on(
ipcTypes.default.app.toRenderer.downloadProgress,
async (event, progress) => {
store.dispatch(setUpdateProgress(progress));
}
);

View File

@@ -48,3 +48,7 @@ export const setUpdateAvailable = (available) => ({
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
payload: available,
});
export const setUpdateProgress = (progress) => ({
type: ApplicationActionTypes.SET_UPDATE_PROGRESS,
payload: progress,
});

View File

@@ -8,6 +8,7 @@ const INITIAL_STATE = {
selectedJobTargetPc: 0,
settings: {},
updateAvailable: false,
updateProgress: null,
};
const { ipcRenderer } = window;
@@ -63,6 +64,8 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
return { ...state, settings: { ...state.settings, ...action.payload } };
case ApplicationActionTypes.SET_UPDATE_AVAILABLE:
return { ...state, updateAvailable: action.payload };
case ApplicationActionTypes.SET_UPDATE_PROGRESS:
return { ...state, updateProgress: action.payload };
default:
return state;
}

View File

@@ -36,3 +36,7 @@ export const selectUpdateAvailable = createSelector(
[selectApplication],
(application) => application.updateAvailable
);
export const selectUpdateProgress = createSelector(
[selectApplication],
(application) => application.updateProgress
);

View File

@@ -9,5 +9,7 @@ const ApplicationActionTypes = {
SET_SELECTED_JOB_TARGET_PC_SUCCESS: "SET_SELECTED_JOB_TARGET_PC_SUCCESS",
SET_SETTINGS: "SET_SETTINGS",
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE",
SET_UPDATE_PROGRESS: "SET_UPDATE_PROGRESS",
};
export default ApplicationActionTypes;

View File

@@ -128,6 +128,7 @@ export function* signInSuccessSaga({ payload }) {
LogRocket.identify(payload.email, {
email: payload.email,
});
ipcRenderer.send(ipcTypes.default.app.toMain.checkForUpdates);
ipcRenderer.send(ipcTypes.default.app.toMain.track, {
event: "SIGN_IN_SUCCESS",