Redux changes and refactoring

This commit is contained in:
Scott E. Graves
2019-06-07 16:32:18 -05:00
parent 5c931bb66d
commit 7f3e90773e
9 changed files with 158 additions and 69 deletions

View File

@@ -19,6 +19,7 @@ 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'; import {installDependency, installRelease, installUpgrade} from './redux/actions/install_actions';
import {notifyError} from './redux/actions/error_actions';
const Constants = require('./constants'); const Constants = require('./constants');
const Scheduler = require('node-schedule'); const Scheduler = require('node-schedule');
@@ -32,10 +33,6 @@ class App extends IPCContainer {
} }
state = { state = {
DisplayError: false,
Error: null,
ErrorAction: null,
ErrorCritical: false,
MissingDependencies: [], MissingDependencies: [],
InstalledVersion: 'none', InstalledVersion: 'none',
}; };
@@ -56,21 +53,6 @@ class App extends IPCContainer {
} }
}; };
closeErrorDisplay = () => {
if (this.state.ErrorAction) {
this.state.ErrorAction();
}
if (this.state.ErrorCritical) {
this.sendRequest(Constants.IPC_Shutdown);
} else {
this.setState({
DisplayError: false,
Error: null,
});
}
};
componentDidMount() { componentDidMount() {
this.sendRequest(Constants.IPC_Get_State); this.sendRequest(Constants.IPC_Get_State);
this.scheduledUpdateJob = Scheduler.scheduleJob('23 11 * * *', this.updateCheckScheduledJob); this.scheduledUpdateJob = Scheduler.scheduleJob('23 11 * * *', this.updateCheckScheduledJob);
@@ -180,7 +162,7 @@ class App extends IPCContainer {
if (arg.data.Success) { if (arg.data.Success) {
action(); action();
} else { } else {
this.setErrorState(arg.data.Error, action); this.props.notifyError(arg.data.Error, false, action);
} }
}; };
@@ -197,7 +179,7 @@ class App extends IPCContainer {
this.installUpgrade(result); this.installUpgrade(result);
break; break;
default: default:
this.setErrorState('Unknown download type: ' + type, null, false); this.props.notifyError('Unknown download type: ' + type);
break; break;
} }
} }
@@ -237,15 +219,17 @@ class App extends IPCContainer {
onInstallUpgradeComplete = (source, result) => { onInstallUpgradeComplete = (source, result) => {
if (this.isMounted() && !result.Success) { if (this.isMounted() && !result.Success) {
this.setErrorState(result.Error, () => { this.props.notifyError(result.Error, false,() => {
if (this.isMounted()) {
// TODO Prompt to verify // TODO Prompt to verify
if (result.AllowSkipVerification) { if (result.AllowSkipVerification) {
this.installUpgrade( { this.installUpgrade({
SkipVerification: true, SkipVerification: true,
Source: source, Source: source,
Success: true, Success: true,
}); });
} }
}
}, false); }, false);
} }
}; };
@@ -267,17 +251,6 @@ class App extends IPCContainer {
} }
}; };
setErrorState = (error, action, critical) => {
this.setState({
DisplayError: true,
Error: error,
ErrorAction: action,
ErrorCritical: critical,
}, () => {
this.sendRequest(Constants.IPC_Show_Window);
});
};
updateCheckScheduledJob = () => { updateCheckScheduledJob = () => {
if (this.props.AppPlatform !== 'unknown') { if (this.props.AppPlatform !== 'unknown') {
this.detectUpgrades(); this.detectUpgrades();
@@ -333,7 +306,7 @@ class App extends IPCContainer {
allowConfig; allowConfig;
const showUpgrade = this.props.UpgradeAvailable && const showUpgrade = this.props.UpgradeAvailable &&
!this.state.DisplayError && !this.props.DisplayError &&
!showConfig && !showConfig &&
!this.props.DownloadActive && !this.props.DownloadActive &&
!this.props.UpgradeDismissed; !this.props.UpgradeDismissed;
@@ -343,12 +316,10 @@ class App extends IPCContainer {
!this.props.DownloadActive; !this.props.DownloadActive;
let errorDisplay = null; let errorDisplay = null;
if (this.state.DisplayError) { if (this.props.DisplayError) {
errorDisplay = ( errorDisplay = (
<Modal critical> <Modal critical>
<ErrorDetails closed={this.closeErrorDisplay} <ErrorDetails/>
critical={this.state.ErrorCritical}
error={this.state.Error}/>
</Modal> </Modal>
); );
} }
@@ -357,8 +328,7 @@ class App extends IPCContainer {
if (showConfig) { if (showConfig) {
configDisplay = ( configDisplay = (
<Modal> <Modal>
<Configuration errorHandler={this.setErrorState} <Configuration version={selectedVersion} />
version={selectedVersion} />
</Modal> </Modal>
); );
} }
@@ -412,7 +382,6 @@ class App extends IPCContainer {
<MountItems allowConfig={allowConfig} <MountItems allowConfig={allowConfig}
allowSiaPrime={allowSiaPrime} allowSiaPrime={allowSiaPrime}
noConsoleSupported={noConsoleSupported} noConsoleSupported={noConsoleSupported}
errorHandler={this.setErrorState}
version={this.state.InstalledVersion}/> version={this.state.InstalledVersion}/>
</div> </div>
)); ));
@@ -466,6 +435,7 @@ const mapStateToProps = state => {
AppPlatform: state.common.AppPlatform, AppPlatform: state.common.AppPlatform,
AppReady: state.common.AppReady, AppReady: state.common.AppReady,
DisplayConfiguration: state.mounts.DisplayConfiguration, DisplayConfiguration: state.mounts.DisplayConfiguration,
DisplayError: state.error.DisplayError,
DownloadActive: state.download.DownloadActive, DownloadActive: state.download.DownloadActive,
DownloadType: state.download.DownloadType, DownloadType: state.download.DownloadType,
InstallActive: state.install.InstallActive, InstallActive: state.install.InstallActive,
@@ -492,6 +462,7 @@ const mapDispatchToProps = dispatch => {
installRelease: (source, version, completedCallback) => dispatch(installRelease(source, version, completedCallback)), installRelease: (source, version, completedCallback) => dispatch(installRelease(source, version, completedCallback)),
installUpgrade: (source, sha256, signature, skipVerification, completedCallback) => dispatch(installUpgrade(source, sha256, signature, skipVerification, completedCallback)), installUpgrade: (source, sha256, signature, skipVerification, completedCallback) => dispatch(installUpgrade(source, sha256, signature, skipVerification, completedCallback)),
loadReleases: ()=> dispatch(loadReleases()), loadReleases: ()=> dispatch(loadReleases()),
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
setActiveRelease: (release, version) => dispatch(setActiveRelease(release, version)), setActiveRelease: (release, version) => dispatch(setActiveRelease(release, version)),
setAllowDownload: allow => dispatch(setAllowDownload(allow)), setAllowDownload: allow => dispatch(setAllowDownload(allow)),
setDismissUIUpgrade: dismiss => dispatch(setDismissUIUpgrade(dismiss)), setDismissUIUpgrade: dismiss => dispatch(setDismissUIUpgrade(dismiss)),

View File

@@ -1,16 +1,30 @@
import React from 'react'; import React from 'react';
import {dismissError} from '../../redux/actions/error_actions';
import {connect} from 'react-redux';
import Box from '../UI/Box/Box'; import Box from '../UI/Box/Box';
import Button from '../UI/Button/Button'; import Button from '../UI/Button/Button';
import './ErrorDetails.css'; import './ErrorDetails.css';
export default props => { const mapStateToProps = state => {
return {
ErrorMessage: state.error.ErrorStack.length > 0 ? state.error.ErrorStack[0] : '',
};
};
const mapDispatchToProps = dispatch => {
return {
dismissError: () => dispatch(dismissError()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(props => {
return ( return (
<Box dxStyle={{padding: '8px'}}> <Box dxStyle={{padding: '8px'}}>
<h1 className={'ErrorDetailsHeading'}>Application Error</h1> <h1 className={'ErrorDetailsHeading'}>Application Error</h1>
<div className={'ErrorDetailsContent'}> <div className={'ErrorDetailsContent'}>
<p>{props.error.toString()}</p> <p>{props.ErrorMessage}</p>
</div> </div>
<Button clicked={props.closed}>Dismiss</Button> <Button clicked={props.dismissError}>Dismiss</Button>
</Box> </Box>
); );
}; });

View File

@@ -7,20 +7,17 @@ import ConfigurationItem from '../../components/ConfigurationItem/ConfigurationI
import Modal from '../../components/UI/Modal/Modal'; import Modal from '../../components/UI/Modal/Modal';
import IPCContainer from '../IPCContainer/IPCContainer'; import IPCContainer from '../IPCContainer/IPCContainer';
import {displayConfiguration} from '../../redux/actions/mount_actions'; import {displayConfiguration} from '../../redux/actions/mount_actions';
import {notifyError} from '../../redux/actions/error_actions';
const Constants = require('../../constants'); const Constants = require('../../constants');
class Configuration extends IPCContainer { class Configuration extends IPCContainer {
constructor(props) { constructor(props) {
super(props); super(props);
this.setRequestHandler(Constants.IPC_Get_Config_Template_Reply, this.onGetConfigTemplateReply); this.setRequestHandler(Constants.IPC_Get_Config_Template_Reply, this.onGetConfigTemplateReply);
this.setRequestHandler(Constants.IPC_Get_Config_Reply, this.onGetConfigReply); this.setRequestHandler(Constants.IPC_Get_Config_Reply, this.onGetConfigReply);
this.setRequestHandler(Constants.IPC_Set_Config_Values_Reply, this.onSetConfigValuesReply); this.setRequestHandler(Constants.IPC_Set_Config_Values_Reply, this.onSetConfigValuesReply);
this.sendRequest(Constants.IPC_Get_Config_Template, {
Provider: this.props.DisplayConfiguration,
Version: this.props.version,
});
} }
state = { state = {
@@ -72,6 +69,13 @@ class Configuration extends IPCContainer {
} }
}; };
componentDidMount() {
this.sendRequest(Constants.IPC_Get_Config_Template, {
Provider: this.props.DisplayConfiguration,
Version: this.props.version,
});
}
createItemList = (config, template) => { createItemList = (config, template) => {
const objectList = []; const objectList = [];
const itemList = Object const itemList = Object
@@ -142,7 +146,7 @@ class Configuration extends IPCContainer {
OriginalObjectLookup: objectLookupCopy, OriginalObjectLookup: objectLookupCopy,
}); });
} else { } else {
this.props.errorHandler(arg.data.Error); this.props.notifyError(arg.data.Error);
} }
}; };
@@ -157,8 +161,10 @@ class Configuration extends IPCContainer {
}); });
}); });
} else { } else {
this.props.errorHandler(arg.data.Error, () => { this.props.notifyError(arg.data.Error, false, () => {
if (this.isMounted()) {
this.props.hideConfiguration(); this.props.hideConfiguration();
}
}); });
} }
}; };
@@ -283,6 +289,7 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
hideConfiguration: () => dispatch(displayConfiguration(null)), hideConfiguration: () => dispatch(displayConfiguration(null)),
} }
}; };

View File

@@ -14,6 +14,7 @@ import {
setMountState, setMountState,
setProviderState setProviderState
} from '../../redux/actions/mount_actions'; } from '../../redux/actions/mount_actions';
import {notifyError} from '../../redux/actions/error_actions';
const Constants = require('../../constants'); const Constants = require('../../constants');
@@ -101,7 +102,7 @@ class MountItems extends IPCContainer {
handleMountUnMount = (provider, mount, location) => { handleMountUnMount = (provider, mount, location) => {
if (!location || (location.trim().length === 0)) { if (!location || (location.trim().length === 0)) {
this.props.errorHandler('Mount location is not set'); this.props.notifyError('Mount location is not set');
} else { } else {
let allowAction = true; let allowAction = true;
if (mount) { if (mount) {
@@ -117,22 +118,22 @@ class MountItems extends IPCContainer {
}); });
if (!result.Success) { if (!result.Success) {
allowAction = false; allowAction = false;
this.props.errorHandler(result.Error.toString()); this.props.notifyError(result.Error.toString());
} }
} }
} else { } else {
allowAction = false; allowAction = false;
if (result.Code === (new Uint32Array([-1]))[0]) { if (result.Code === (new Uint32Array([-1]))[0]) {
this.props.errorHandler('Failed to connect to ' + provider + ' daemon'); this.props.notifyError('Failed to connect to ' + provider + ' daemon');
} else if (result.Code === (new Uint32Array([-3]))[0]) { } else if (result.Code === (new Uint32Array([-3]))[0]) {
this.props.errorHandler('Incompatible ' + provider + ' daemon. Please upgrade ' + provider); this.props.notifyError('Incompatible ' + provider + ' daemon. Please upgrade ' + provider);
} else { } else {
this.props.errorHandler('Version check failed: ' + result.Error); this.props.notifyError('Version check failed: ' + result.Error);
} }
} }
} else { } else {
allowAction = false; allowAction = false;
this.props.errorHandler(result.Error.toString()); this.props.notifyError(result.Error.toString());
} }
} }
@@ -201,7 +202,7 @@ class MountItems extends IPCContainer {
this.props.setAutoMountProcessed(true); this.props.setAutoMountProcessed(true);
} else { } else {
this.props.errorHandler(arg.data.Error); this.props.notifyError(arg.data.Error);
} }
}; };
@@ -316,6 +317,7 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
setAllowMount: (provider, allow) => dispatch(setAllowMount(provider, allow)), setAllowMount: (provider, allow) => dispatch(setAllowMount(provider, allow)),
setAutoMountProcessed: processed => dispatch(setAutoMountProcessed(processed)), setAutoMountProcessed: processed => dispatch(setAutoMountProcessed(processed)),
setMounted: (provider, mounted) => dispatch(setMounted(provider, mounted)), setMounted: (provider, mounted) => dispatch(setMounted(provider, mounted)),

View File

@@ -1,3 +1,26 @@
import * as Constants from '../../constants';
import {createAction} from 'redux-starter-kit'; import {createAction} from 'redux-starter-kit';
let ipcRenderer;
if (!process.versions.hasOwnProperty('electron')) {
ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null);
}
export const setApplicationReady = createAction('common/setApplicationReady'); export const setApplicationReady = createAction('common/setApplicationReady');
export const showWindow = () => {
return dispatch => {
if (ipcRenderer) {
ipcRenderer.send(Constants.IPC_Show_Window);
}
};
};
export const shutdownApplication = () => {
return dispatch => {
dispatch(setApplicationReady(false));
if (ipcRenderer) {
ipcRenderer.send(Constants.IPC_Shutdown);
}
};
};

View File

@@ -0,0 +1,45 @@
import {showWindow, shutdownApplication} from './common_actions';
let ErrorActions = [];
export const CLEAR_ERROR = 'error/clearError';
export const clearError = () => {
return {
type: CLEAR_ERROR,
payload: null,
};
};
export const dismissError = () => {
return (dispatch, getState) => {
dispatch(clearError());
const errorAction = ErrorActions[0];
ErrorActions = ErrorActions.splice(1);
if (errorAction) {
errorAction();
}
if (getState().error.ErrorCritical) {
dispatch(shutdownApplication());
}
};
};
export const notifyError = (msg, critical, callback) => {
return dispatch => {
ErrorActions = [callback, ...ErrorActions];
msg = msg.toString();
dispatch(setErrorInfo(msg, critical));
dispatch(showWindow());
};
};
export const SET_ERROR_INFO = 'error/setErrorInfo';
export const setErrorInfo = (msg, critical) => {
return {
type: SET_ERROR_INFO,
payload: {
msg,
critical
}
}
};

View File

@@ -76,6 +76,5 @@ export const installUpgrade = (source, sha256, signature, skipVerification, comp
}; };
}; };
export const setInstallActive = createAction('install/setInstallActive'); export const setInstallActive = createAction('install/setInstallActive');
export const setInstallComplete = createAction('install/setInstallComplete'); export const setInstallComplete = createAction('install/setInstallComplete');

View File

@@ -0,0 +1,26 @@
import {createReducer} from 'redux-starter-kit';
import {CLEAR_ERROR, SET_ERROR_INFO} from '../actions/error_actions';
export const errorReducer = createReducer({
DisplayError: false,
ErrorCritical: false,
ErrorStack: [],
}, {
[CLEAR_ERROR]: state => {
const errorStack = (state.ErrorStack.length > 0) ? state.ErrorStack.slice(1) : [];
return {
...state,
DisplayError: (errorStack.length > 0),
ErrorStack: errorStack,
}
},
[SET_ERROR_INFO]: (state, action) => {
const errorStack = [action.payload.msg, ...state.ErrorStack];
return {
...state,
DisplayError: true,
ErrorCritical: state.ErrorCritical || action.payload.critical,
ErrorStack: errorStack,
}
}
});

View File

@@ -1,6 +1,7 @@
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 {downloadReducer} from '../reducers/download_reducer';
import {errorReducer} from '../reducers/error_reducer';
import {installReducer} from '../reducers/install_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';
@@ -9,6 +10,7 @@ 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,
error: errorReducer,
install: installReducer, install: installReducer,
mounts: mountReducer, mounts: mountReducer,
relver: releaseVersionReducer, relver: releaseVersionReducer,