Restore deleted sprite.
This commit is contained in:
1 parent
976e3b9b4a
commit
b17f6e8533
6 files changed
+136
-9
No files matched your search
@@ -172,3 +172,7 @@
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
@@ -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}
|
||||
>
|
||||
<MenuItemTooltip id="undo">
|
||||
<MenuItem>
|
||||
<FormattedMessage
|
||||
defaultMessage="Undo"
|
||||
description="Menu bar item for undoing"
|
||||
id="gui.menuBar.undo"
|
||||
/>
|
||||
<DeletionRestorer>{(handleRestore, {restorable, deletedItem}) => (
|
||||
<MenuItem
|
||||
className={classNames({[styles.disabled]:!restorable})}
|
||||
onClick={handleRestore}
|
||||
>
|
||||
{deletedItem === 'Sprite' ?
|
||||
<FormattedMessage
|
||||
defaultMessage="Restore Sprite"
|
||||
description="Menu bar item for restoring the last deleted sprite."
|
||||
id="gui.menuBar.restoreSprite"
|
||||
/> :
|
||||
<FormattedMessage
|
||||
defaultMessage="Restore"
|
||||
description="Menu bar item for restoring the last deleted item in its disabled state."
|
||||
id="gui.menuBar.restore"
|
||||
/>
|
||||
}
|
||||
</MenuItem>
|
||||
</MenuItemTooltip>
|
||||
)}</DeletionRestorer>
|
||||
<MenuItemTooltip id="redo">
|
||||
<MenuItem>
|
||||
<FormattedMessage
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import bindAll from 'lodash.bindall';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {setRestore} from '../reducers/restore-deletion';
|
||||
|
||||
/**
|
||||
* DeletionRestorer component passes a restoreDeletion function to its child.
|
||||
* It expects this child to be a function with the signature
|
||||
* function (restoreDeletion, props) {}
|
||||
* The component can then be used to attach deletion restoring functionality
|
||||
* to any other component:
|
||||
*
|
||||
* <DeletionRestorer>{(restoreDeletion, props) => (
|
||||
* <MyCoolComponent
|
||||
* onClick={restoreDeletion}
|
||||
* {...props}
|
||||
* />
|
||||
* )}</DeletionRestorer>
|
||||
*/
|
||||
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);
|
||||
@@ -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));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
};
|
||||
Reference in new issue
Block a user