Make the backpack a drop area for workspace code
This commit is contained in:
1 parent
c973bf0e1a
commit
63ea5b4201
2 files changed
+92
-13
No files matched your search
@@ -17,7 +17,19 @@ const dragTypeMap = { // Keys correspond with the backpack-server item types
|
||||
sprite: DragConstants.BACKPACK_SPRITE
|
||||
};
|
||||
|
||||
const Backpack = ({containerRef, contents, dragOver, error, expanded, loading, onToggle, onDelete}) => (
|
||||
const Backpack = ({
|
||||
blockDragOver,
|
||||
containerRef,
|
||||
contents,
|
||||
dragOver,
|
||||
error,
|
||||
expanded,
|
||||
loading,
|
||||
onToggle,
|
||||
onDelete,
|
||||
onMouseEnter,
|
||||
onMouseLeave
|
||||
}) => (
|
||||
<div className={styles.backpackContainer}>
|
||||
<div
|
||||
className={styles.backpackHeader}
|
||||
@@ -44,8 +56,12 @@ const Backpack = ({containerRef, contents, dragOver, error, expanded, loading, o
|
||||
</div>
|
||||
{expanded ? (
|
||||
<div
|
||||
className={styles.backpackList}
|
||||
className={classNames(styles.backpackList, {
|
||||
[styles.dragOver]: dragOver || blockDragOver
|
||||
})}
|
||||
ref={containerRef}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
{error ? (
|
||||
<div className={styles.statusMessage}>
|
||||
@@ -66,11 +82,7 @@ const Backpack = ({containerRef, contents, dragOver, error, expanded, loading, o
|
||||
</div>
|
||||
) : (
|
||||
contents.length > 0 ? (
|
||||
<div
|
||||
className={classNames(styles.backpackListInner, {
|
||||
[styles.dragOver]: dragOver
|
||||
})}
|
||||
>
|
||||
<div className={styles.backpackListInner}>
|
||||
{contents.map(item => (
|
||||
<SpriteSelectorItem
|
||||
className={styles.backpackItem}
|
||||
@@ -104,6 +116,7 @@ const Backpack = ({containerRef, contents, dragOver, error, expanded, loading, o
|
||||
);
|
||||
|
||||
Backpack.propTypes = {
|
||||
blockDragOver: PropTypes.bool,
|
||||
containerRef: PropTypes.func,
|
||||
contents: PropTypes.arrayOf(PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
@@ -116,10 +129,13 @@ Backpack.propTypes = {
|
||||
expanded: PropTypes.bool,
|
||||
loading: PropTypes.bool,
|
||||
onDelete: PropTypes.func,
|
||||
onMouseEnter: PropTypes.func,
|
||||
onMouseLeave: PropTypes.func,
|
||||
onToggle: PropTypes.func
|
||||
};
|
||||
|
||||
Backpack.defaultProps = {
|
||||
blockDragOver: false,
|
||||
contents: [],
|
||||
dragOver: false,
|
||||
expanded: false,
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
deleteBackpackObject,
|
||||
soundPayload,
|
||||
costumePayload,
|
||||
spritePayload
|
||||
spritePayload,
|
||||
codePayload
|
||||
} from '../lib/backpack-api';
|
||||
import DragConstants from '../lib/drag-constants';
|
||||
import DropAreaHOC from '../lib/drop-area-hoc.jsx';
|
||||
@@ -28,10 +29,18 @@ class Backpack extends React.Component {
|
||||
'handleToggle',
|
||||
'handleDelete',
|
||||
'getBackpackAssetURL',
|
||||
'refreshContents'
|
||||
'refreshContents',
|
||||
'handleMouseEnter',
|
||||
'handleMouseLeave',
|
||||
'handleBlockDragEnd',
|
||||
'handleBlockDragUpdate'
|
||||
]);
|
||||
this.state = {
|
||||
dragOver: false,
|
||||
// While the DroppableHOC manages drop interactions for asset tiles,
|
||||
// we still need to micromanage drops coming from the block workspace.
|
||||
// TODO this may be refactorable with the share-the-love logic in SpriteSelectorItem
|
||||
blockDragOutsideWorkspace: false,
|
||||
blockDragOverBackpack: false,
|
||||
error: false,
|
||||
offset: 0,
|
||||
itemsPerPage: 20,
|
||||
@@ -50,12 +59,23 @@ class Backpack extends React.Component {
|
||||
storage._hasAddedBackpackSource = true;
|
||||
}
|
||||
}
|
||||
componentDidMount () {
|
||||
this.props.vm.addListener('BLOCK_DRAG_END', this.handleBlockDragEnd);
|
||||
this.props.vm.addListener('BLOCK_DRAG_UPDATE', this.handleBlockDragUpdate);
|
||||
}
|
||||
componentWillUnmount () {
|
||||
this.props.vm.removeListener('BLOCK_DRAG_END', this.handleBlockDragEnd);
|
||||
this.props.vm.removeListener('BLOCK_DRAG_UPDATE', this.handleBlockDragUpdate);
|
||||
}
|
||||
getBackpackAssetURL (asset) {
|
||||
return `${this.props.host}/${asset.assetId}.${asset.dataFormat}`;
|
||||
}
|
||||
handleToggle () {
|
||||
const newState = !this.state.expanded;
|
||||
this.setState({expanded: newState, offset: 0});
|
||||
this.setState({expanded: newState, offset: 0}, () => {
|
||||
// Emit resize on window to get blocks to resize
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
});
|
||||
if (newState) {
|
||||
this.refreshContents();
|
||||
}
|
||||
@@ -72,6 +92,9 @@ class Backpack extends React.Component {
|
||||
case DragConstants.SPRITE:
|
||||
payloader = spritePayload;
|
||||
break;
|
||||
case DragConstants.CODE:
|
||||
payloader = codePayload;
|
||||
break;
|
||||
}
|
||||
if (!payloader) return;
|
||||
|
||||
@@ -110,15 +133,47 @@ class Backpack extends React.Component {
|
||||
});
|
||||
}
|
||||
}
|
||||
handleBlockDragUpdate (isOutsideWorkspace) {
|
||||
this.setState({
|
||||
blockDragOutsideWorkspace: isOutsideWorkspace
|
||||
});
|
||||
}
|
||||
handleMouseEnter () {
|
||||
if (this.state.blockDragOutsideWorkspace) {
|
||||
this.setState({
|
||||
blockDragOverBackpack: true
|
||||
});
|
||||
}
|
||||
}
|
||||
handleMouseLeave () {
|
||||
this.setState({
|
||||
blockDragOverBackpack: false
|
||||
});
|
||||
}
|
||||
handleBlockDragEnd (blocks) {
|
||||
if (this.state.blockDragOverBackpack) {
|
||||
this.handleDrop({
|
||||
dragType: DragConstants.CODE,
|
||||
payload: blocks
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
blockDragOverBackpack: false,
|
||||
blockDragOutsideWorkspace: false
|
||||
});
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<DroppableBackpack
|
||||
blockDragOver={this.state.blockDragOverBackpack}
|
||||
contents={this.state.contents}
|
||||
error={this.state.error}
|
||||
expanded={this.state.expanded}
|
||||
loading={this.state.loading}
|
||||
onDelete={this.handleDelete}
|
||||
onDrop={this.handleDrop}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
onToggle={this.props.host ? this.handleToggle : null}
|
||||
/>
|
||||
);
|
||||
@@ -152,9 +207,17 @@ const getTokenAndUsername = state => {
|
||||
|
||||
const mapStateToProps = state => Object.assign(
|
||||
{
|
||||
vm: state.scratchGui.vm
|
||||
dragInfo: state.scratchGui.assetDrag,
|
||||
vm: state.scratchGui.vm,
|
||||
blockDrag: state.scratchGui.blockDrag
|
||||
},
|
||||
getTokenAndUsername(state)
|
||||
);
|
||||
|
||||
export default connect(mapStateToProps)(Backpack);
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
dispatchSetHoveredSprite: spriteId => {
|
||||
dispatch(setHoveredSprite(spriteId));
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Backpack);
|
||||
Reference in new issue
Block a user