UNPKG

@wordpress/editor

Version:
121 lines (119 loc) 3.97 kB
/** * WordPress dependencies */ import { Component } from '@wordpress/element'; import { compose } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ import { store as editorStore } from '../../store'; export class AutosaveMonitor extends Component { constructor(props) { super(props); this.needsAutosave = !!(props.isDirty && props.isAutosaveable); } componentDidMount() { if (!this.props.disableIntervalChecks) { this.setAutosaveTimer(); } } componentDidUpdate(prevProps) { if (this.props.disableIntervalChecks) { if (this.props.editsReference !== prevProps.editsReference) { this.props.autosave(); } return; } if (this.props.interval !== prevProps.interval) { clearTimeout(this.timerId); this.setAutosaveTimer(); } if (!this.props.isDirty) { this.needsAutosave = false; return; } if (this.props.isAutosaving && !prevProps.isAutosaving) { this.needsAutosave = false; return; } if (this.props.editsReference !== prevProps.editsReference) { this.needsAutosave = true; } } componentWillUnmount() { clearTimeout(this.timerId); } setAutosaveTimer(timeout = this.props.interval * 1000) { this.timerId = setTimeout(() => { this.autosaveTimerHandler(); }, timeout); } autosaveTimerHandler() { if (!this.props.isAutosaveable) { this.setAutosaveTimer(1000); return; } if (this.needsAutosave) { this.needsAutosave = false; this.props.autosave(); } this.setAutosaveTimer(); } render() { return null; } } /** * Monitors the changes made to the edited post and triggers autosave if necessary. * * The logic is straightforward: a check is performed every `props.interval` seconds. If any changes are detected, `props.autosave()` is called. * The time between the change and the autosave varies but is no larger than `props.interval` seconds. Refer to the code below for more details, such as * the specific way of detecting changes. * * There are two caveats: * * If `props.isAutosaveable` happens to be false at a time of checking for changes, the check is retried every second. * * The timer may be disabled by setting `props.disableIntervalChecks` to `true`. In that mode, any change will immediately trigger `props.autosave()`. * * @param {Object} props - The properties passed to the component. * @param {Function} props.autosave - The function to call when changes need to be saved. * @param {number} props.interval - The maximum time in seconds between an unsaved change and an autosave. * @param {boolean} props.isAutosaveable - If false, the check for changes is retried every second. * @param {boolean} props.disableIntervalChecks - If true, disables the timer and any change will immediately trigger `props.autosave()`. * @param {boolean} props.isDirty - Indicates if there are unsaved changes. * * @example * ```jsx * <AutosaveMonitor interval={30000} /> * ``` */ export default compose([withSelect((select, ownProps) => { const { getReferenceByDistinctEdits } = select(coreStore); const { isEditedPostDirty, isEditedPostAutosaveable, isAutosavingPost, getEditorSettings } = select(editorStore); const { interval = getEditorSettings().autosaveInterval } = ownProps; return { editsReference: getReferenceByDistinctEdits(), isDirty: isEditedPostDirty(), isAutosaveable: isEditedPostAutosaveable(), isAutosaving: isAutosavingPost(), interval }; }), withDispatch((dispatch, ownProps) => ({ autosave() { const { autosave = dispatch(editorStore).autosave } = ownProps; autosave(); } }))])(AutosaveMonitor); //# sourceMappingURL=index.js.map