diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx index eda8dd1b766993929e6dc2b5c6c21267bc8367fe..bbd78f4463919a920cb9cdd822b3b8ad8a9a87c5 100644 --- a/src/lib/project-saver-hoc.jsx +++ b/src/lib/project-saver-hoc.jsx @@ -10,6 +10,7 @@ import { showAlertWithTimeout, showStandardAlert } from '../reducers/alerts'; +import {setAutoSaveTimeoutId} from '../reducers/timeout'; import {setProjectUnchanged} from '../reducers/project-changed'; import { LoadingStates, @@ -43,9 +44,6 @@ const ProjectSaverHOC = function (WrappedComponent) { bindAll(this, [ 'tryToAutoSave' ]); - this.state = { - autoSaveTimeoutId: null - }; } componentDidUpdate (prevProps) { if (this.props.projectChanged && !prevProps.projectChanged) { @@ -88,16 +86,16 @@ const ProjectSaverHOC = function (WrappedComponent) { this.clearAutoSaveTimeout(); } clearAutoSaveTimeout () { - if (this.state.autoSaveTimeoutId !== null) { - clearTimeout(this.state.autoSaveTimeoutId); - this.setState({autoSaveTimeoutId: null}); + if (this.props.autoSaveTimeoutId !== null) { + clearTimeout(this.props.autoSaveTimeoutId); + this.props.setAutoSaveTimeoutId(null); } } scheduleAutoSave () { - if (this.props.isShowingSaveable && this.state.autoSaveTimeoutId === null) { + if (this.props.isShowingSaveable && this.props.autoSaveTimeoutId === null) { const timeoutId = setTimeout(this.tryToAutoSave, this.props.autosaveIntervalSecs * 1000); - this.setState({autoSaveTimeoutId: timeoutId}); + this.props.setAutoSaveTimeoutId(timeoutId); } } tryToAutoSave () { @@ -237,6 +235,7 @@ const ProjectSaverHOC = function (WrappedComponent) { onUpdatedProject, reduxProjectId, reduxProjectTitle, + setAutoSaveTimeoutId: setAutoSaveTimeoutIdProp, /* eslint-enable no-unused-vars */ ...componentProps } = this.props; @@ -249,6 +248,7 @@ const ProjectSaverHOC = function (WrappedComponent) { } ProjectSaverComponent.propTypes = { + autoSaveTimeoutId: PropTypes.number, canCreateNew: PropTypes.bool, canSave: PropTypes.bool, isCreatingCopy: PropTypes.bool, @@ -283,6 +283,7 @@ const ProjectSaverHOC = function (WrappedComponent) { const loadingState = state.scratchGui.projectState.loadingState; const isShowingWithId = getIsShowingWithId(loadingState); return { + autoSaveTimeoutId: state.scratchGui.timeout.autoSaveTimeoutId, isCreatingCopy: getIsCreatingCopy(loadingState), isCreatingNew: getIsCreatingNew(loadingState), isRemixing: getIsRemixing(loadingState), @@ -309,7 +310,8 @@ const ProjectSaverHOC = function (WrappedComponent) { onShowCreatingAlert: () => showAlertWithTimeout(dispatch, 'creating'), onShowSaveSuccessAlert: () => showAlertWithTimeout(dispatch, 'saveSuccess'), onShowSavingAlert: () => showAlertWithTimeout(dispatch, 'saving'), - onUpdatedProject: (projectId, loadingState) => dispatch(doneUpdatingProject(projectId, loadingState)) + onUpdatedProject: (projectId, loadingState) => dispatch(doneUpdatingProject(projectId, loadingState)), + setAutoSaveTimeoutId: id => dispatch(setAutoSaveTimeoutId(id)) }); // Allow incoming props to override redux-provided props. Used to mock in tests. const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign( diff --git a/src/reducers/gui.js b/src/reducers/gui.js index edffa1cf363316d0a38a705eb20edc2f064b9566..a1978d6d6d77eb3c3f7633bc6268aed195208944 100644 --- a/src/reducers/gui.js +++ b/src/reducers/gui.js @@ -20,6 +20,7 @@ import projectTitleReducer, {projectTitleInitialState} from './project-title'; import restoreDeletionReducer, {restoreDeletionInitialState} from './restore-deletion'; import stageSizeReducer, {stageSizeInitialState} from './stage-size'; import targetReducer, {targetsInitialState} from './targets'; +import timeoutReducer, {timeoutInitialState} from './timeout'; import toolboxReducer, {toolboxInitialState} from './toolbox'; import vmReducer, {vmInitialState} from './vm'; import vmStatusReducer, {vmStatusInitialState} from './vm-status'; @@ -51,6 +52,7 @@ const guiInitialState = { projectTitle: projectTitleInitialState, restoreDeletion: restoreDeletionInitialState, targets: targetsInitialState, + timeout: timeoutInitialState, toolbox: toolboxInitialState, vm: vmInitialState, vmStatus: vmStatusInitialState @@ -129,6 +131,7 @@ const guiReducer = combineReducers({ projectTitle: projectTitleReducer, restoreDeletion: restoreDeletionReducer, targets: targetReducer, + timeout: timeoutReducer, toolbox: toolboxReducer, vm: vmReducer, vmStatus: vmStatusReducer diff --git a/src/reducers/timeout.js b/src/reducers/timeout.js new file mode 100644 index 0000000000000000000000000000000000000000..958352c64bfc0a6cd533cc3ac851b646a0a232c9 --- /dev/null +++ b/src/reducers/timeout.js @@ -0,0 +1,27 @@ +const SET_AUTOSAVE_TIMEOUT_ID = 'projectTitle/SET_AUTOSAVE_TIMEOUT_ID'; + +const initialState = { + autoSaveTimeoutId: null +}; + +const reducer = function (state, action) { + if (typeof state === 'undefined') state = initialState; + switch (action.type) { + case SET_AUTOSAVE_TIMEOUT_ID: + return Object.assign({}, state, { + autoSaveTimeoutId: action.id + }); + default: + return state; + } +}; +const setAutoSaveTimeoutId = id => ({ + type: SET_AUTOSAVE_TIMEOUT_ID, + id +}); + +export { + reducer as default, + initialState as timeoutInitialState, + setAutoSaveTimeoutId +};