[partial] #30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades

This commit is contained in:
2019-08-13 14:06:50 -05:00
parent 9f45b0f03f
commit fa130c7dd1
10 changed files with 98 additions and 14 deletions

View File

@@ -886,6 +886,13 @@ ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => {
}
});
ipcMain.on(Constants.IPC_Reboot_System, () => {
if (os.platform() === 'win32') {
helpers.executeAsync('shutdown.exe', ['/r', '/t', '30']);
}
closeApplication();
});
ipcMain.on(Constants.IPC_Save_State, (event, data) => {
helpers.mkDirByPathSync(helpers.getDataDirectory());
const configFile = path.join(helpers.getDataDirectory(), 'settings.json');

View File

@@ -13,6 +13,7 @@ import Loading from './components/UI/Loading/Loading';
import Modal from './components/UI/Modal/Modal';
import MountItems from './containers/MountItems/MountItems';
import {notifyError} from './redux/actions/error_actions';
import Reboot from './components/Reboot/Reboot';
import ReleaseVersionDisplay from './components/ReleaseVersionDisplay/ReleaseVersionDisplay';
import {saveState} from './redux/actions/common_actions';
import Text from './components/UI/Text/Text';
@@ -93,6 +94,7 @@ class App extends IPCContainer {
const showConfig = !missingDependencies &&
this.props.DisplayConfiguration &&
!this.props.RebootRequired &&
allowConfig;
const showUpgrade = this.props.UpgradeAvailable &&
@@ -100,12 +102,15 @@ class App extends IPCContainer {
!showConfig &&
!this.props.DownloadActive &&
!this.props.UpgradeDismissed &&
!this.props.InstallActive;
!this.props.InstallActive &&
!this.props.RebootRequired;
const showDependencies = !showUpgrade &&
missingDependencies &&
!this.props.DownloadActive;
!this.props.DownloadActive &&
!this.props.RebootRequired;
const rebootDisplay = this.createModalConditionally(this.props.RebootRequired, <Reboot />);
const configDisplay = this.createModalConditionally(showConfig, <Configuration version={selectedVersion} />);
const dependencyDisplay = this.createModalConditionally(showDependencies, <DependencyList/>);
const downloadDisplay = this.createModalConditionally(this.props.DownloadActive, <DownloadProgress/>);
@@ -143,6 +148,7 @@ class App extends IPCContainer {
{upgradeDisplay}
{downloadDisplay}
{configDisplay}
{rebootDisplay}
<div className={'AppContainer'}>
<div className={'AppHeader'}>
<Box>
@@ -189,6 +195,7 @@ const mapStateToProps = state => {
MissingDependencies: state.install.MissingDependencies,
MountsBusy: state.mounts.MountsBusy,
ProviderState: state.mounts.ProviderState,
RebootRequired: state.common.RebootRequired,
Release: state.relver.Release,
ReleaseVersion: state.relver.Version,
UpgradeAvailable: state.relver.UpgradeAvailable,

View File

@@ -15,7 +15,7 @@ const mapStateToProps = state => {
const mapDispatchToProps = (dispatch) => {
return {
downloadItem: (name, type, url) => dispatch(downloadItem(name, type, url))
downloadItem: (name, type, url, isWinFSP) => dispatch(downloadItem(name, type, url, isWinFSP))
};
};
@@ -24,7 +24,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
return (
<Dependency key={i}
name={k.display}
onDownload={()=>props.downloadItem(extractFileNameFromURL(k.download), Constants.INSTALL_TYPES.Dependency, k.download)}/>
onDownload={()=>props.downloadItem(extractFileNameFromURL(k.download), Constants.INSTALL_TYPES.Dependency, k.download, k.is_winfsp)}/>
);
});

View File

@@ -0,0 +1,11 @@
.RebootHeading {
color: var(--text_color_error);
text-align: center;
margin-bottom: 4px;
}
.RebootContent {
max-height: 60vh;
overflow-y: auto;
margin-bottom: 8px;
}

View File

@@ -0,0 +1,24 @@
import React from 'react';
import './Reboot.css';
import {connect} from 'react-redux';
import Box from '../UI/Box/Box';
import Button from '../UI/Button/Button';
import {rebootSystem} from '../../redux/actions/common_actions';
const mapDispatchToProps = dispatch => {
return {
rebootSystem: () => dispatch(rebootSystem()),
};
};
export default connect(null, mapDispatchToProps)(props => {
return (
<Box dxDark dxStyle={{padding: '8px'}}>
<h1 className={'RebootHeading'}>Reboot System</h1>
<div className={'RebootContent'}>
<p>Repertory requires a system reboot to continue.</p>
</div>
<Button clicked={()=>props.rebootSystem()}>Reboot Now</Button>
</Box>
);
});

View File

@@ -111,6 +111,8 @@ exports.IPC_Install_Upgrade_Reply = 'install_upgrade_reply';
exports.IPC_Mount_Drive = 'mount_drive';
exports.IPC_Mount_Drive_Reply = 'mount_drive_reply';
exports.IPC_Reboot_System = 'reboot_system';
exports.IPC_Save_State = 'save_state';
exports.IPC_Show_Window = 'show_window';

View File

@@ -4,7 +4,24 @@ import {getIPCRenderer} from '../../utils';
const ipcRenderer = getIPCRenderer();
export const notifyRebootRequired = createAction('common/notifyRebootRequired');
export const rebootSystem = () => {
return dispatch => {
dispatch(setApplicationReady(false));
if (ipcRenderer) {
ipcRenderer.send(Constants.IPC_Reboot_System);
}
}
};
export const setApplicationReady = createAction('common/setApplicationReady');
export const setRebootRequired = () => {
return dispatch => {
dispatch(showWindow());
dispatch(notifyRebootRequired(true));
};
};
export const showWindow = () => {
return dispatch => {

View File

@@ -25,7 +25,7 @@ export const setDownloadBegin = (name, type, url) => {
export const setDownloadEnd = createAction('download/setDownloadEnd');
export const setDownloadProgress = createAction('download/setDownloadProgress');
export const downloadItem = (name, type, urls) => {
export const downloadItem = (name, type, urls, isWinFSP) => {
return (dispatch, getState) => {
if (!Array.isArray(urls)) {
urls = [urls];
@@ -35,7 +35,7 @@ export const downloadItem = (name, type, urls) => {
if (result.Success) {
switch (type) {
case Constants.INSTALL_TYPES.Dependency:
dispatch(installDependency(result.Destination, result.URL));
dispatch(installDependency(result.Destination, result.URL, isWinFSP));
break;
case Constants.INSTALL_TYPES.Release:
dispatch(installRelease(result.Destination));

View File

@@ -13,6 +13,7 @@ import {
} from './release_version_actions';
import {
setApplicationReady,
setRebootRequired,
showWindow,
shutdownApplication
} from './common_actions';
@@ -81,7 +82,7 @@ export const checkVersionInstalled = () => {
};
};
export const installDependency = (source, url) => {
export const installDependency = (source, url, isWinFSP) => {
return (dispatch, getState) => {
if (ipcRenderer && !getState().install.InstallActive) {
dispatch(setInstallActive(Constants.INSTALL_TYPES.Dependency));
@@ -89,11 +90,15 @@ export const installDependency = (source, url) => {
const installDependencyComplete = (event, arg) => {
const result = arg.data;
const handleCompleted = ()=> {
ipcRenderer.send(Constants.IPC_Delete_File, {
FilePath: source,
});
dispatch(setInstallComplete(result));
dispatch(checkVersionInstalled());
if (result.RebootRequired) {
dispatch(setRebootRequired());
} else {
ipcRenderer.send(Constants.IPC_Delete_File, {
FilePath: source,
});
dispatch(setInstallComplete(result));
dispatch(checkVersionInstalled());
}
};
if (result.Success && source.toLowerCase().endsWith('.dmg')) {
@@ -121,6 +126,7 @@ export const installDependency = (source, url) => {
ipcRenderer.send(Constants.IPC_Install_Dependency, {
Source: source,
URL: url,
IsWinFSP: isWinFSP,
});
}
};

View File

@@ -1,11 +1,15 @@
import {createReducer} from 'redux-starter-kit';
import {setApplicationReady} from '../actions/common_actions';
import {
notifyRebootRequired,
setApplicationReady,
} from '../actions/common_actions';
export const createCommonReducer = (platform, appPlatform, version) => {
return createReducer({
AppPlatform: appPlatform,
AppReady: false,
Platform: platform,
RebootRequired: false,
Version: version,
}, {
[setApplicationReady]: (state, action) => {
@@ -13,6 +17,12 @@ export const createCommonReducer = (platform, appPlatform, version) => {
...state,
AppReady: action.payload,
};
}
},
[notifyRebootRequired]: (state, action) => {
return {
...state,
RebootRequired: action.payload,
};
},
});
};