Redux changes and refactoring

This commit is contained in:
Scott E. Graves
2019-06-07 15:34:09 -05:00
parent a326d7762f
commit 704a357dd0
5 changed files with 177 additions and 75 deletions

View File

@@ -18,25 +18,17 @@ import UpgradeUI from './components/UpgradeUI/UpgradeUI';
import {setProviderState} from './redux/actions/mount_actions'; import {setProviderState} from './redux/actions/mount_actions';
import {detectUIUpgrade, loadReleases, setActiveRelease, setDismissUIUpgrade, setReleaseUpgradeAvailable} from './redux/actions/release_version_actions'; import {detectUIUpgrade, loadReleases, setActiveRelease, setDismissUIUpgrade, setReleaseUpgradeAvailable} from './redux/actions/release_version_actions';
import {downloadItem, setAllowDownload} from './redux/actions/download_actions'; import {downloadItem, setAllowDownload} from './redux/actions/download_actions';
import {installDependency, installRelease, installUpgrade} from './redux/actions/install_actions';
const Constants = require('./constants'); const Constants = require('./constants');
const Scheduler = require('node-schedule'); const Scheduler = require('node-schedule');
const DownloadTypes = {
Dependency: 'dependency',
Release: 'release',
Upgrade: 'upgrade',
};
class App extends IPCContainer { class App extends IPCContainer {
constructor(props) { constructor(props) {
super(props); super(props);
this.setRequestHandler(Constants.IPC_Check_Installed_Reply, this.onCheckInstalledReply); this.setRequestHandler(Constants.IPC_Check_Installed_Reply, this.onCheckInstalledReply);
this.setRequestHandler(Constants.IPC_Extract_Release_Complete, this.onExtractReleaseComplete);
this.setRequestHandler(Constants.IPC_Get_State_Reply, this.onGetStateReply); this.setRequestHandler(Constants.IPC_Get_State_Reply, this.onGetStateReply);
this.setRequestHandler(Constants.IPC_Install_Dependency_Reply, this.onInstallDependencyReply);
this.setRequestHandler(Constants.IPC_Install_Upgrade_Reply, this.onInstallUpgradeReply);
} }
state = { state = {
@@ -44,7 +36,6 @@ class App extends IPCContainer {
Error: null, Error: null,
ErrorAction: null, ErrorAction: null,
ErrorCritical: false, ErrorCritical: false,
ExtractActive: false,
MissingDependencies: [], MissingDependencies: [],
InstalledVersion: 'none', InstalledVersion: 'none',
}; };
@@ -108,16 +99,6 @@ class App extends IPCContainer {
return parts[parts.length - 1]; return parts[parts.length - 1];
}; };
extractRelease = (data) => {
if (data.Success) {
const selectedVersion = this.getSelectedVersion();
this.sendRequest(Constants.IPC_Extract_Release, {
Source: data.Destination,
Version: selectedVersion,
});
}
};
detectUpgrades = () => { detectUpgrades = () => {
if (this.props.AppPlatform !== 'unknown') { if (this.props.AppPlatform !== 'unknown') {
this.props.loadReleases(); this.props.loadReleases();
@@ -132,26 +113,34 @@ class App extends IPCContainer {
}; };
handleDownloadDependency = url => { handleDownloadDependency = url => {
this.props.downloadItem(this.extractFileNameFromURL(url), DownloadTypes.Dependency, url, this.onDownloadFileComplete); this.props.downloadItem(this.extractFileNameFromURL(url), Constants.INSTALL_TYPES.Dependency, url, this.onDownloadFileComplete);
}; };
handleDownloadRelease = () => { handleDownloadRelease = () => {
const selectedVersion = this.getSelectedVersion(); const selectedVersion = this.getSelectedVersion();
const fileName = selectedVersion + '.zip'; const fileName = selectedVersion + '.zip';
this.props.downloadItem(fileName, DownloadTypes.Release, this.props.LocationsLookup[selectedVersion].urls[0], this.onDownloadFileComplete); this.props.downloadItem(fileName, Constants.INSTALL_TYPES.Release, this.props.LocationsLookup[selectedVersion].urls[0], this.onDownloadFileComplete);
}; };
handleDownloadUpgrade = () => { handleDownloadUpgrade = () => {
const url = this.props.UpgradeData.urls[0]; const url = this.props.UpgradeData.urls[0];
const name = this.props.Platform === 'win32' ? 'upgrade.exe' : this.extractFileNameFromURL(url); const name = this.props.Platform === 'win32' ? 'upgrade.exe' : this.extractFileNameFromURL(url);
this.props.downloadItem(name, DownloadTypes.Upgrade, url, this.onDownloadFileComplete); this.props.downloadItem(name, Constants.INSTALL_TYPES.Upgrade, url, this.onDownloadFileComplete);
}; };
installDependency = data => { installDependency = data => {
if (data.Success) { if (data.Success) {
this.sendRequest(Constants.IPC_Install_Dependency, { this.props.installDependency(data.Destination, data.URL, this.onInstallDependencyComplete);
Source: data.Destination, }
URL: data.URL, };
installRelease = data => {
if (data.Success) {
const selectedVersion = this.getSelectedVersion();
this.props.installRelease(data.Destination, selectedVersion, () => {
if (this.isMounted()) {
this.checkVersionInstalled();
}
}); });
} }
}; };
@@ -160,12 +149,7 @@ class App extends IPCContainer {
if (data.Success) { if (data.Success) {
const sha256 = this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]].sha256; const sha256 = this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]].sha256;
const signature = this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]].sig; const signature = this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]].sig;
this.sendRequest(Constants.IPC_Install_Upgrade, { this.props.installUpgrade(data.Destination, sha256, signature, !!data.SkipVerification, this.onInstallUpgradeComplete);
Sha256: sha256,
Signature: signature,
SkipVerification: !!data.SkipVerification,
Source: data.Destination,
});
} }
}; };
@@ -201,26 +185,22 @@ class App extends IPCContainer {
}; };
onDownloadFileComplete = (name, type, url, result) => { onDownloadFileComplete = (name, type, url, result) => {
if (this.isMounted()) {
switch (type) { switch (type) {
case DownloadTypes.Dependency: this.installDependency(result); break; case Constants.INSTALL_TYPES.Dependency:
case DownloadTypes.Release: this.extractRelease(result); break; this.installDependency(result);
case DownloadTypes.Upgrade: this.installUpgrade(result); break; break;
case Constants.INSTALL_TYPES.Release:
this.installRelease(result);
break;
case Constants.INSTALL_TYPES.Upgrade:
this.installUpgrade(result);
break;
default: default:
this.setErrorState('Unknown download type: ' + type, null, false); this.setErrorState('Unknown download type: ' + type, null, false);
break; break;
} }
}; }
onExtractReleaseComplete = (event, arg) => {
this.sendRequest(Constants.IPC_Delete_File, {
FilePath: arg.data.Source,
});
this.setState({
ExtractActive: false,
}, ()=> {
this.checkVersionInstalled( );
});
}; };
onGetStateReply = (event, arg) => { onGetStateReply = (event, arg) => {
@@ -242,29 +222,27 @@ class App extends IPCContainer {
this.detectUpgrades(); this.detectUpgrades();
}; };
onInstallDependencyReply = (event, arg) => { onInstallDependencyComplete = (source, url, result) => {
if (arg.data.Success && arg.data.Source.toLowerCase().endsWith('.dmg')) { if (this.isMounted()) {
this.waitForDependencyInstall(arg.data.URL); if (result.Success && source.toLowerCase().endsWith('.dmg')) {
this.waitForDependencyInstall(source, url);
} else { } else {
this.sendRequest(Constants.IPC_Delete_File, { this.sendRequest(Constants.IPC_Delete_File, {
FilePath: arg.data.Source, FilePath: source,
}); });
this.checkVersionInstalled(); this.checkVersionInstalled();
} }
}
}; };
onInstallUpgradeReply = (event, arg) => { onInstallUpgradeComplete = (source, result) => {
this.sendSyncRequest(Constants.IPC_Delete_File, { if (this.isMounted() && !result.Success) {
FilePath: arg.data.Source, this.setErrorState(result.Error, () => {
});
if (!arg.data.Success) {
this.setErrorState(arg.data.Error, () => {
// TODO Prompt to verify // TODO Prompt to verify
if (arg.data.AllowSkipVerification) { if (result.AllowSkipVerification) {
this.installUpgrade( { this.installUpgrade( {
SkipVerification: true, SkipVerification: true,
Source: arg.data.Source, Source: source,
Success: true, Success: true,
}); });
} }
@@ -306,7 +284,7 @@ class App extends IPCContainer {
} }
}; };
waitForDependencyInstall = (url) => { waitForDependencyInstall = (source, url) => {
const dep = this.state.MissingDependencies.find(d => { const dep = this.state.MissingDependencies.find(d => {
return d.download === url; return d.download === url;
}); });
@@ -318,6 +296,9 @@ class App extends IPCContainer {
if (ret.data.Exists) { if (ret.data.Exists) {
clearInterval(i); clearInterval(i);
setTimeout(() => { setTimeout(() => {
this.sendRequest(Constants.IPC_Delete_File, {
FilePath: source,
});
this.checkVersionInstalled(); this.checkVersionInstalled();
}, 10000); }, 10000);
} }
@@ -334,7 +315,9 @@ class App extends IPCContainer {
(selectedVersion !== this.state.InstalledVersion); (selectedVersion !== this.state.InstalledVersion);
const missingDependencies = (this.state.MissingDependencies.length > 0); const missingDependencies = (this.state.MissingDependencies.length > 0);
const allowMount = this.state.InstalledVersion !== 'none' && !missingDependencies; const allowMount = this.state.InstalledVersion !== 'none' &&
!missingDependencies &&
!this.props.InstallActive;
const allowConfig = this.props.LocationsLookup[selectedVersion] && const allowConfig = this.props.LocationsLookup[selectedVersion] &&
this.props.LocationsLookup[selectedVersion].config_support; this.props.LocationsLookup[selectedVersion].config_support;
@@ -384,7 +367,7 @@ class App extends IPCContainer {
if (showDependencies) { if (showDependencies) {
dependencyDisplay = ( dependencyDisplay = (
<Modal> <Modal>
<DependencyList allowDownload={this.props.DownloadType !== DownloadTypes.Dependency} <DependencyList allowDownload={this.props.DownloadType !== Constants.INSTALL_TYPES.Dependency}
dependencies={this.state.MissingDependencies} dependencies={this.state.MissingDependencies}
onDownload={this.handleDownloadDependency}/> onDownload={this.handleDownloadDependency}/>
</Modal> </Modal>
@@ -415,10 +398,10 @@ class App extends IPCContainer {
mainContent.push(( mainContent.push((
<div key={'rvd_' + key++} <div key={'rvd_' + key++}
style={{height: '32%'}}> style={{height: '32%'}}>
<ReleaseVersionDisplay disabled={this.props.DownloadActive || this.state.ExtractActive || this.props.MountsBusy} <ReleaseVersionDisplay disabled={this.props.DownloadActive || this.props.InstallActive || this.props.MountsBusy}
downloadClicked={this.handleDownloadRelease} downloadClicked={this.handleDownloadRelease}
downloadDisabled={!downloadEnabled} downloadDisabled={!downloadEnabled}
releaseExtracting={this.state.ExtractActive} releaseExtracting={this.props.InstallType === Constants.INSTALL_TYPES.Release}
text={this.state.InstalledVersion + ' [' + this.props.AppPlatform + ']'}/> text={this.state.InstalledVersion + ' [' + this.props.AppPlatform + ']'}/>
</div> </div>
)); ));
@@ -485,6 +468,8 @@ const mapStateToProps = state => {
DisplayConfiguration: state.mounts.DisplayConfiguration, DisplayConfiguration: state.mounts.DisplayConfiguration,
DownloadActive: state.download.DownloadActive, DownloadActive: state.download.DownloadActive,
DownloadType: state.download.DownloadType, DownloadType: state.download.DownloadType,
InstallActive: state.install.InstallActive,
InstallType: state.install.InstallType,
LocationsLookup: state.relver.LocationsLookup, LocationsLookup: state.relver.LocationsLookup,
MountsBusy: state.mounts.MountsBusy, MountsBusy: state.mounts.MountsBusy,
Platform: state.common.Platform, Platform: state.common.Platform,
@@ -502,7 +487,10 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
detectUIUpgrade: () => dispatch(detectUIUpgrade()), detectUIUpgrade: () => dispatch(detectUIUpgrade()),
downloadItem: (name, type, url, callback) => dispatch(downloadItem(name, type, url, callback)), downloadItem: (name, type, url, completedCallback) => dispatch(downloadItem(name, type, url, completedCallback)),
installDependency: (source, url, completedCallback) => dispatch(installDependency(source, url, completedCallback)),
installRelease: (source, version, completedCallback) => dispatch(installRelease(source, version, completedCallback)),
installUpgrade: (source, sha256, signature, skipVerification, completedCallback) => dispatch(installUpgrade(source, sha256, signature, skipVerification, completedCallback)),
loadReleases: ()=> dispatch(loadReleases()), loadReleases: ()=> dispatch(loadReleases()),
setActiveRelease: (release, version) => dispatch(setActiveRelease(release, version)), setActiveRelease: (release, version) => dispatch(setActiveRelease(release, version)),
setAllowDownload: allow => dispatch(setAllowDownload(allow)), setAllowDownload: allow => dispatch(setAllowDownload(allow)),

View File

@@ -65,6 +65,12 @@ exports.RELEASE_TYPES = [
'Alpha', 'Alpha',
]; ];
exports.INSTALL_TYPES = {
Dependency: 'dependency',
Release: 'release',
Upgrade: 'upgrade',
};
exports.IPC_Browse_Directory = 'browse_directory'; exports.IPC_Browse_Directory = 'browse_directory';
exports.IPC_Check_Daemon_Version = 'check_daemon_version'; exports.IPC_Check_Daemon_Version = 'check_daemon_version';

View File

@@ -0,0 +1,81 @@
import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit';
let ipcRenderer;
if (!process.versions.hasOwnProperty('electron')) {
ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null);
}
export const installDependency = (source, url, completedCallback) => {
return (dispatch, getState) => {
if (ipcRenderer && !getState().install.InstallActive) {
dispatch(setInstallActive(Constants.INSTALL_TYPES.Dependency));
const installDependencyComplete = (event, arg) => {
ipcRenderer.removeListener(Constants.IPC_Install_Dependency_Reply, installDependencyComplete);
dispatch(setInstallComplete(arg.data));
completedCallback(source, url, arg.data);
};
ipcRenderer.on(Constants.IPC_Install_Dependency_Reply, installDependencyComplete);
ipcRenderer.send(Constants.IPC_Install_Dependency, {
Source: source,
URL: url,
});
}
};
};
export const installRelease = (source, version, completedCallback) => {
return (dispatch, getState) => {
if (ipcRenderer && !getState().install.InstallActive) {
dispatch(setInstallActive(Constants.INSTALL_TYPES.Release));
const extractReleaseComplete = (event, arg) => {
ipcRenderer.removeListener(Constants.IPC_Extract_Release_Complete, extractReleaseComplete);
ipcRenderer.sendSync(Constants.IPC_Delete_File, {
FilePath: source,
});
dispatch(setInstallComplete(arg.data));
completedCallback(source, version, arg.data);
};
ipcRenderer.on(Constants.IPC_Extract_Release_Complete, extractReleaseComplete);
ipcRenderer.send(Constants.IPC_Extract_Release, {
Source: source,
Version: version,
});
}
};
};
export const installUpgrade = (source, sha256, signature, skipVerification, completedCallback) => {
return (dispatch, getState) => {
if (ipcRenderer && !getState().install.InstallActive) {
dispatch(setInstallActive(Constants.INSTALL_TYPES.Dependency));
const installUpgradeComplete = (event, arg) => {
ipcRenderer.removeListener(Constants.IPC_Install_Upgrade_Reply, installUpgradeComplete);
ipcRenderer.sendSync(Constants.IPC_Delete_File, {
FilePath: source,
});
dispatch(setInstallComplete(arg.data));
completedCallback(source, arg.data);
};
ipcRenderer.on(Constants.IPC_Install_Upgrade_Reply, installUpgradeComplete);
ipcRenderer.send(Constants.IPC_Install_Upgrade, {
Sha256: sha256,
Signature: signature,
SkipVerification: skipVerification,
Source: source,
});
}
};
};
export const setInstallActive = createAction('install/setInstallActive');
export const setInstallComplete = createAction('install/setInstallComplete');

View File

@@ -0,0 +1,25 @@
import {createReducer} from 'redux-starter-kit';
import {setInstallActive, setInstallComplete} from '../actions/install_actions';
export const installReducer = createReducer({
InstallActive: false,
InstallResult: null,
InstallType: null,
}, {
[setInstallActive]: (state, action) => {
return {
...state,
InstallActive: true,
InstallResult: null,
InstallType: action.payload,
};
},
[setInstallComplete]: (state, action) => {
return {
...state,
InstallActive: false,
InstallResult: action.payload,
InstallType: null,
}
}
});

View File

@@ -1,13 +1,15 @@
import {configureStore, getDefaultMiddleware} from 'redux-starter-kit'; import {configureStore, getDefaultMiddleware} from 'redux-starter-kit';
import {createCommonReducer} from '../reducers/common_reducer'; import {createCommonReducer} from '../reducers/common_reducer';
import {downloadReducer} from '../reducers/download_reducer';
import {installReducer} from '../reducers/install_reducer';
import {mountReducer} from '../reducers/mount_reducer'; import {mountReducer} from '../reducers/mount_reducer';
import {releaseVersionReducer} from '../reducers/release_version_reducer'; import {releaseVersionReducer} from '../reducers/release_version_reducer';
import {downloadReducer} from '../reducers/download_reducer';
export default function createAppStore(platform, appPlatform, version) { export default function createAppStore(platform, appPlatform, version) {
const reducer = { const reducer = {
common: createCommonReducer(platform, appPlatform, version), common: createCommonReducer(platform, appPlatform, version),
download: downloadReducer, download: downloadReducer,
install: installReducer,
mounts: mountReducer, mounts: mountReducer,
relver: releaseVersionReducer, relver: releaseVersionReducer,
}; };