diff --git a/src/components/menu-bar/menu-bar.css b/src/components/menu-bar/menu-bar.css
index 45669f8d6..635b18012 100644
--- a/src/components/menu-bar/menu-bar.css
+++ b/src/components/menu-bar/menu-bar.css
@@ -172,3 +172,7 @@
width: 0.5rem;
height: 0.5rem;
}
+
+.disabled {
+ opacity: 0.5;
+}
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index 24117372b..96338b87d 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -14,6 +14,7 @@ import ProjectLoader from '../../containers/project-loader.jsx';
import Menu from '../../containers/menu.jsx';
import {MenuItem, MenuSection} from '../menu/menu.jsx';
import ProjectSaver from '../../containers/project-saver.jsx';
+import DeletionRestorer from '../../containers/deletion-restorer.jsx';
import TurboMode from '../../containers/turbo-mode.jsx';
import {openTipsLibrary} from '../../reducers/modals';
@@ -279,15 +280,25 @@ class MenuBar extends React.Component {
open={this.props.editMenuOpen}
onRequestClose={this.props.onRequestCloseEdit}
>
-
-
+ )}
{(restoreDeletion, props) => (
+ *
+ * )}
+ */
+class DeletionRestorer extends React.Component {
+ constructor (props) {
+ super(props);
+ bindAll(this, [
+ 'restoreDeletion'
+ ]);
+ }
+ restoreDeletion () {
+ if (typeof this.props.restore === 'function') {
+ this.props.restore();
+ this.props.dispatchUpdateRestore({restoreFun: null, deletedItem: ''});
+ }
+ }
+ render () {
+ const {
+ /* eslint-disable no-unused-vars */
+ children,
+ /* eslint-enable no-unused-vars */
+ ...props
+ } = this.props;
+ props.restorable = typeof this.props.restore === 'function';
+ props.deletedItem = this.props.deletedItem;
+ return this.props.children(this.restoreDeletion, props);
+ }
+}
+
+DeletionRestorer.propTypes = {
+ children: PropTypes.func,
+ deletedItem: PropTypes.string,
+ dispatchUpdateRestore: PropTypes.func,
+ restore: PropTypes.func
+};
+
+const mapStateToProps = state => ({
+ deletedItem: state.scratchGui.restoreDeletion.deletedItem,
+ restore: state.scratchGui.restoreDeletion.restoreFun
+});
+const mapDispatchToProps = dispatch => ({
+ dispatchUpdateRestore: updatedState => {
+ dispatch(setRestore(updatedState));
+ }
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(DeletionRestorer);
diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx
index 870b97164..2bfc77253 100644
--- a/src/containers/target-pane.jsx
+++ b/src/containers/target-pane.jsx
@@ -10,6 +10,7 @@ import {
import {activateTab, COSTUMES_TAB_INDEX} from '../reducers/editor-tab';
import {setReceivedBlocks} from '../reducers/hovered-target';
+import {setRestore} from '../reducers/restore-deletion';
import DragConstants from '../lib/drag-constants';
import TargetPaneComponent from '../components/target-pane/target-pane.jsx';
import spriteLibraryContent from '../lib/libraries/sprites.json';
@@ -68,7 +69,12 @@ class TargetPane extends React.Component {
this.props.vm.postSpriteInfo({y});
}
handleDeleteSprite (id) {
- this.props.vm.deleteSprite(id);
+ const restoreFun = this.props.vm.deleteSprite(id);
+ this.props.dispatchUpdateRestore({
+ restoreFun: restoreFun,
+ deletedItem: 'Sprite'
+ });
+
}
handleDuplicateSprite (id) {
this.props.vm.duplicateSprite(id);
@@ -240,6 +246,9 @@ const mapDispatchToProps = dispatch => ({
},
onReceivedBlocks: receivedBlocks => {
dispatch(setReceivedBlocks(receivedBlocks));
+ },
+ dispatchUpdateRestore: restoreState => {
+ dispatch(setRestore(restoreState));
}
});
diff --git a/src/reducers/gui.js b/src/reducers/gui.js
index 2c5642416..04b264468 100644
--- a/src/reducers/gui.js
+++ b/src/reducers/gui.js
@@ -11,6 +11,7 @@ import modalReducer, {modalsInitialState} from './modals';
import modeReducer, {modeInitialState} from './mode';
import monitorReducer, {monitorsInitialState} from './monitors';
import monitorLayoutReducer, {monitorLayoutInitialState} from './monitor-layout';
+import restoreDeletionReducer, {restoreDeletionInitialState} from './restore-deletion';
import stageSizeReducer, {stageSizeInitialState} from './stage-size';
import targetReducer, {targetsInitialState} from './targets';
import toolboxReducer, {toolboxInitialState} from './toolbox';
@@ -34,6 +35,7 @@ const guiInitialState = {
modals: modalsInitialState,
monitors: monitorsInitialState,
monitorLayout: monitorLayoutInitialState,
+ restoreDeletion: restoreDeletionInitialState,
targets: targetsInitialState,
toolbox: toolboxInitialState,
vm: vmInitialState,
@@ -75,6 +77,7 @@ const guiReducer = combineReducers({
modals: modalReducer,
monitors: monitorReducer,
monitorLayout: monitorLayoutReducer,
+ restoreDeletion: restoreDeletionReducer,
targets: targetReducer,
toolbox: toolboxReducer,
vm: vmReducer,
diff --git a/src/reducers/restore-deletion.js b/src/reducers/restore-deletion.js
new file mode 100644
index 000000000..0c723fc03
--- /dev/null
+++ b/src/reducers/restore-deletion.js
@@ -0,0 +1,33 @@
+const RESTORE_UPDATE = 'scratch-gui/restore-deletion/RESTORE_UPDATE';
+
+const initialState = {
+ restoreFun: null,
+ deletedItem: ''
+};
+
+const reducer = function (state, action) {
+ if (typeof state === 'undefined') state = initialState;
+
+ switch (action.type) {
+ case RESTORE_UPDATE:
+ return Object.assign({}, state, action.state);
+ default:
+ return state;
+ }
+};
+
+const setRestore = function (state) {
+ return {
+ type: RESTORE_UPDATE,
+ state: {
+ restoreFun: state.restoreFun,
+ deletedItem: state.deletedItem
+ }
+ };
+};
+
+export {
+ reducer as default,
+ initialState as restoreDeletionInitialState,
+ setRestore
+};