[partial] #30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades
This commit is contained in:
@@ -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');
|
||||
|
||||
11
src/App.js
11
src/App.js
@@ -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,
|
||||
|
||||
@@ -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)}/>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
11
src/components/Reboot/Reboot.css
Normal file
11
src/components/Reboot/Reboot.css
Normal 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;
|
||||
}
|
||||
24
src/components/Reboot/Reboot.js
Normal file
24
src/components/Reboot/Reboot.js
Normal 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>
|
||||
);
|
||||
});
|
||||
@@ -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';
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 = ()=> {
|
||||
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,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user