diff --git a/src/actions/index.js b/src/actions/index.js index 4e6e298..d2009b8 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -58,6 +58,11 @@ export const addGIF = imageData => ({ payload: { imageData } }); +export const undoBurst = (frames, frameIDs) => ({ + type: types.UNDO_BURST, + payload: { frames, frameIDs } +}); + export const togglePane = pane => { clearTimer(); return { @@ -140,7 +145,17 @@ export const requestFrame = opts => async dispatch => { }; export const requestBurst = opts => async (dispatch, getState) => { - const { idx, min, max, step, width, height, oversample } = opts; + const { + idx, + min, + max, + step, + width, + height, + oversample, + frames, + frameIDs + } = opts; const imageOpts = { width, height, @@ -161,6 +176,9 @@ export const requestBurst = opts => async (dispatch, getState) => { return; } + const prevFrames = { ...frames }; + const prevFrameIDs = [...frameIDs]; + let imageData; let sliderErrorMessage; for (let val = min; val <= max; val += step) { @@ -173,6 +191,8 @@ export const requestBurst = opts => async (dispatch, getState) => { imageData = await getImageData(imageOpts); dispatch(addFrame(imageData)); } + + return { prevFrames, prevFrameIDs }; }; export const startAnimation = () => (dispatch, getState) => { diff --git a/src/components/Burst.css b/src/components/Burst.css index 3e207e5..3dcbaf8 100644 --- a/src/components/Burst.css +++ b/src/components/Burst.css @@ -60,3 +60,8 @@ background: #484848; border-color: #e79600; } + +.capturing { + opacity: 0.5; + pointer-events: none; +} diff --git a/src/components/Burst.js b/src/components/Burst.js index 4b3a7fe..eabcb95 100644 --- a/src/components/Burst.js +++ b/src/components/Burst.js @@ -1,22 +1,34 @@ import React, { Component } from 'react'; import classNames from 'classnames'; +import { getCalcState, setCalcState } from '../lib/calc-helpers'; import { getBurstErrors } from '../lib/input-helpers'; import './Burst.css'; class Burst extends Component { constructor(props) { super(props); - this.state = { idx: 1, min: -10, max: 10, step: 1, + isCapturing: false, + canUndo: false, + prevFrames: {}, + prevFrameIDs: [], + prevCalcState: {}, errors: {} }; this.handleInputUpdate = this.handleInputUpdate.bind(this); this.handleRequestBurst = this.handleRequestBurst.bind(this); + this.handleUndoBurst = this.handleUndoBurst.bind(this); + } + + componentDidUpdate(prevProps) { + if (this.props.frameIDs.length !== prevProps.frameIDs.length) { + this.setState({ canUndo: false }); + } } handleInputUpdate(evt) { @@ -32,9 +44,41 @@ class Burst extends Component { this.setState(newState); } - handleRequestBurst() { - const { requestBurst, expanded, ...imgOpts } = this.props; - requestBurst({ ...this.state, ...imgOpts }); + async handleRequestBurst() { + this.setState({ isCapturing: true, canUndo: false }); + const { requestBurst, expanded, frames, frameIDs, ...imgOpts } = this.props; + const prevCalcState = getCalcState(); + const undoData = await requestBurst({ + ...this.state, + ...imgOpts, + frames, + frameIDs + }); + if (undoData) { + const { prevFrames, prevFrameIDs } = undoData; + this.setState({ + isCapturing: false, + canUndo: true, + prevFrames, + prevFrameIDs, + prevCalcState + }); + } else { + this.setState({ isCapturing: false }); + } + } + + handleUndoBurst() { + const { undoBurst } = this.props; + const { prevFrames, prevFrameIDs, prevCalcState } = this.state; + undoBurst(prevFrames, prevFrameIDs); + setCalcState(prevCalcState); + this.setState({ + canUndo: false, + prevFrames: {}, + prevFrameIDs: [], + prevCalcState: {} + }); } render() { @@ -91,13 +135,26 @@ class Burst extends Component { />