From e6f4c637ed21a0747f915c37b487eb1a88fa5a8d Mon Sep 17 00:00:00 2001 From: Billy Date: Tue, 18 Jun 2019 19:58:47 -0700 Subject: [PATCH 1/6] add logic to requestBurst action creator --- src/actions/index.js | 31 +++++++++++++++++++++++++++++-- src/components/Burst.js | 15 ++++++++++++--- src/containers/BurstContainer.js | 7 +++++-- src/lib/calc-helpers.js | 10 ++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 4e6e298..87bb786 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -27,7 +27,12 @@ */ import * as types from '../constants/action-types'; -import { setSliderByIndex, getImageData } from '../lib/calc-helpers'; +import { + setSliderByIndex, + getImageData, + getCalcState, + setCalcState +} from '../lib/calc-helpers'; import { startTimer, clearTimer } from '../lib/timer'; import { gifCreationProblem, @@ -140,13 +145,28 @@ 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, targetPixelRatio: oversample ? 2 : 1 }; + // grab calculator state prior to capture + const prevFrames = { ...frames }; + const prevFrameIDs = [...frameIDs]; + const prevCalcState = getCalcState(); + // Check for errors in the current pane first. const burstErrors = getBurstErrors({ idx, min, max, step }); if (Object.keys(burstErrors).length) { @@ -173,6 +193,13 @@ export const requestBurst = opts => async (dispatch, getState) => { imageData = await getImageData(imageOpts); dispatch(addFrame(imageData)); } + + // return data prior to burst capture for undo + return { + prevFrames, + prevFrameIDs, + prevCalcState + }; }; export const startAnimation = () => (dispatch, getState) => { diff --git a/src/components/Burst.js b/src/components/Burst.js index 4b3a7fe..4682eaf 100644 --- a/src/components/Burst.js +++ b/src/components/Burst.js @@ -32,9 +32,18 @@ class Burst extends Component { this.setState(newState); } - handleRequestBurst() { - const { requestBurst, expanded, ...imgOpts } = this.props; - requestBurst({ ...this.state, ...imgOpts }); + async handleRequestBurst() { + const { requestBurst, expanded, frames, frameIDs, ...imgOpts } = this.props; + // pass frames and frameIDs + const dataForUndo = await requestBurst({ + ...this.state, + frames, + frameIDs, + ...imgOpts + }); + // save undo data to state + // if undo data in state, show undo button + console.log(dataForUndo); } render() { diff --git a/src/containers/BurstContainer.js b/src/containers/BurstContainer.js index d091fb5..d0ba11c 100644 --- a/src/containers/BurstContainer.js +++ b/src/containers/BurstContainer.js @@ -4,14 +4,17 @@ import { requestBurst } from '../actions'; import panes from '../constants/pane-types'; const mapStateToProps = (state, ownProps) => { - const { settings, ui } = state; + const { settings, ui, images } = state; const { width, height, oversample } = settings.image; + const { frames, frameIDs } = images; return { expanded: ui.expandedPane === panes.BURST, width, height, - oversample + oversample, + frames, + frameIDs }; }; diff --git a/src/lib/calc-helpers.js b/src/lib/calc-helpers.js index 57cda8c..b1d3294 100644 --- a/src/lib/calc-helpers.js +++ b/src/lib/calc-helpers.js @@ -39,3 +39,13 @@ export const setSliderByIndex = (idx, val) => { const identifier = match[1]; calculator.setExpression({ id, latex: `${identifier}=${val}` }); }; + +// gets current state of calculator instance +export const getCalcState = () => { + return calculator.getState(); +}; + +// accepts some calculator state and updates calculator instance +export const setCalcState = state => { + return calculator.setState(state); +}; From 41c2b1828361ed30b9783bb9a63ba93e1ba55c64 Mon Sep 17 00:00:00 2001 From: Billy Date: Tue, 18 Jun 2019 21:29:46 -0700 Subject: [PATCH 2/6] finish up adding undo burst functionality --- src/actions/index.js | 29 ++++++-------- src/components/Burst.css | 5 +++ src/components/Burst.js | 66 +++++++++++++++++++++++++++----- src/constants/action-types.js | 1 + src/containers/BurstContainer.js | 4 +- src/reducers/images.js | 8 ++++ 6 files changed, 85 insertions(+), 28 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 87bb786..1471a51 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -27,12 +27,7 @@ */ import * as types from '../constants/action-types'; -import { - setSliderByIndex, - getImageData, - getCalcState, - setCalcState -} from '../lib/calc-helpers'; +import { setSliderByIndex, getImageData } from '../lib/calc-helpers'; import { startTimer, clearTimer } from '../lib/timer'; import { gifCreationProblem, @@ -63,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 { @@ -162,11 +162,6 @@ export const requestBurst = opts => async (dispatch, getState) => { targetPixelRatio: oversample ? 2 : 1 }; - // grab calculator state prior to capture - const prevFrames = { ...frames }; - const prevFrameIDs = [...frameIDs]; - const prevCalcState = getCalcState(); - // Check for errors in the current pane first. const burstErrors = getBurstErrors({ idx, min, max, step }); if (Object.keys(burstErrors).length) { @@ -181,6 +176,10 @@ 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) { @@ -194,12 +193,8 @@ export const requestBurst = opts => async (dispatch, getState) => { dispatch(addFrame(imageData)); } - // return data prior to burst capture for undo - return { - prevFrames, - prevFrameIDs, - prevCalcState - }; + // + 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 4682eaf..2542503 100644 --- a/src/components/Burst.js +++ b/src/components/Burst.js @@ -1,5 +1,6 @@ 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'; @@ -12,11 +13,16 @@ class Burst extends Component { min: -10, max: 10, step: 1, + isCapturing: false, + prevFrames: {}, + prevFrameIDs: [], + prevCalcState: {}, errors: {} }; this.handleInputUpdate = this.handleInputUpdate.bind(this); this.handleRequestBurst = this.handleRequestBurst.bind(this); + this.handleUndoBurst = this.handleUndoBurst.bind(this); } handleInputUpdate(evt) { @@ -33,17 +39,46 @@ class Burst extends Component { } async handleRequestBurst() { + this.setState({ isCapturing: true }); const { requestBurst, expanded, frames, frameIDs, ...imgOpts } = this.props; - // pass frames and frameIDs - const dataForUndo = await requestBurst({ + // grab calculator state prior to capture + const prevCalcState = getCalcState(); + // capture + const undoData = await requestBurst({ ...this.state, + ...imgOpts, frames, - frameIDs, - ...imgOpts + frameIDs + }); + // if capture was successful, update state accordingly + if (undoData) { + const { prevFrames, prevFrameIDs } = undoData; + this.setState({ + isCapturing: false, + prevFrames, + prevFrameIDs, + prevCalcState + }); + } + // update isCapturing regardless + else { + this.setState({ isCapturing: false }); + } + } + + handleUndoBurst() { + const { undoBurst } = this.props; + const { prevFrames, prevFrameIDs, prevCalcState } = this.state; + // dispatch action to change frames, frameIDs in state + undoBurst(prevFrames, prevFrameIDs); + // revert calculator state + setCalcState(prevCalcState); + // clear out undo data in local state + this.setState({ + prevFrames: {}, + prevFrameIDs: [], + prevCalcState: {} }); - // save undo data to state - // if undo data in state, show undo button - console.log(dataForUndo); } render() { @@ -100,13 +135,26 @@ class Burst extends Component { />
+ {this.state.prevFrameIDs.length ? ( +
+ +
+ ) : null} ); } diff --git a/src/constants/action-types.js b/src/constants/action-types.js index 950302c..cf78a22 100644 --- a/src/constants/action-types.js +++ b/src/constants/action-types.js @@ -11,6 +11,7 @@ export const ADD_FRAME = 'ADD_FRAME'; export const UPDATE_GIF_PROGRESS = 'UPDATE_GIF_PROGRESS'; export const ADD_GIF = 'ADD_GIF'; +export const UNDO_BURST = 'UNDO_BURST'; // UI export const UPDATE_PREVIEW_IDX = 'UPDATE_PREVIEW_IDX'; diff --git a/src/containers/BurstContainer.js b/src/containers/BurstContainer.js index d0ba11c..4744f3b 100644 --- a/src/containers/BurstContainer.js +++ b/src/containers/BurstContainer.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import Burst from '../components/Burst'; -import { requestBurst } from '../actions'; +import { requestBurst, undoBurst } from '../actions'; import panes from '../constants/pane-types'; const mapStateToProps = (state, ownProps) => { @@ -20,7 +20,7 @@ const mapStateToProps = (state, ownProps) => { const BurstContainer = connect( mapStateToProps, - { requestBurst } + { requestBurst, undoBurst } )(Burst); export default BurstContainer; diff --git a/src/reducers/images.js b/src/reducers/images.js index fef790c..170dfb7 100644 --- a/src/reducers/images.js +++ b/src/reducers/images.js @@ -12,6 +12,7 @@ import { ADD_FRAME, UPDATE_GIF_PROGRESS, ADD_GIF, + UNDO_BURST, UPDATE_IMAGE_SETTING, UPDATE_BOUNDS_SETTING, UPDATE_STRATEGY, @@ -53,6 +54,13 @@ const images = (state = initialState, { type, payload }) => { gifData: payload.imageData }; + case UNDO_BURST: + return { + ...state, + frames: payload.frames, + frameIDs: payload.frameIDs + }; + case UPDATE_IMAGE_SETTING: case UPDATE_BOUNDS_SETTING: case UPDATE_STRATEGY: From 7e27197984529c44e0ca12cf51743ec53b19ab4c Mon Sep 17 00:00:00 2001 From: Billy Date: Wed, 19 Jun 2019 10:40:44 -0700 Subject: [PATCH 3/6] bug fix: add canUndo to Burst local state --- src/components/Burst.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Burst.js b/src/components/Burst.js index 2542503..590baf6 100644 --- a/src/components/Burst.js +++ b/src/components/Burst.js @@ -14,6 +14,7 @@ class Burst extends Component { max: 10, step: 1, isCapturing: false, + canUndo: false, prevFrames: {}, prevFrameIDs: [], prevCalcState: {}, @@ -55,6 +56,7 @@ class Burst extends Component { const { prevFrames, prevFrameIDs } = undoData; this.setState({ isCapturing: false, + canUndo: true, prevFrames, prevFrameIDs, prevCalcState @@ -75,6 +77,7 @@ class Burst extends Component { setCalcState(prevCalcState); // clear out undo data in local state this.setState({ + canUndo: false, prevFrames: {}, prevFrameIDs: [], prevCalcState: {} @@ -144,7 +147,7 @@ class Burst extends Component { {this.state.isCapturing ? 'Capturing...' : 'Capture'} - {this.state.prevFrameIDs.length ? ( + {this.state.canUndo ? (