Add sprite saving to the backpack with dragging back out
This commit is contained in:
1 parent
5b082e29ec
commit
6d185ccc9f
5 files changed
+49
-6
No files matched your search
@@ -71,6 +71,7 @@ const SpriteList = function (props) {
|
||||
[styles.raised]: isRaised,
|
||||
[styles.receivedBlocks]: receivedBlocks
|
||||
})}
|
||||
dragPayload={sprite}
|
||||
dragType={DragConstants.SPRITE}
|
||||
id={sprite.id}
|
||||
index={index}
|
||||
|
||||
@@ -7,12 +7,14 @@ import {
|
||||
saveBackpackObject,
|
||||
deleteBackpackObject,
|
||||
soundPayload,
|
||||
costumePayload
|
||||
costumePayload,
|
||||
spritePayload
|
||||
} from '../lib/backpack-api';
|
||||
import DragConstants from '../lib/drag-constants';
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import storage from '../lib/storage';
|
||||
import VM from 'scratch-vm';
|
||||
|
||||
class Backpack extends React.Component {
|
||||
constructor (props) {
|
||||
@@ -45,7 +47,7 @@ class Backpack extends React.Component {
|
||||
}
|
||||
}
|
||||
componentWillReceiveProps (newProps) {
|
||||
const dragTypes = [DragConstants.COSTUME, DragConstants.SOUND];
|
||||
const dragTypes = [DragConstants.COSTUME, DragConstants.SOUND, DragConstants.SPRITE];
|
||||
// If `dragging` becomes true, record the drop area rectangle
|
||||
if (newProps.dragInfo.dragging && !this.props.dragInfo.dragging) {
|
||||
this.dropAreaRect = this.ref && this.ref.getBoundingClientRect();
|
||||
@@ -83,10 +85,13 @@ class Backpack extends React.Component {
|
||||
case DragConstants.SOUND:
|
||||
payloader = soundPayload;
|
||||
break;
|
||||
case DragConstants.SPRITE:
|
||||
payloader = spritePayload;
|
||||
break;
|
||||
}
|
||||
if (!payloader) return;
|
||||
|
||||
payloader(dragInfo.payload)
|
||||
payloader(dragInfo.payload, this.props.vm)
|
||||
.then(payload => saveBackpackObject({
|
||||
host: this.props.host,
|
||||
token: this.props.token,
|
||||
@@ -152,7 +157,8 @@ Backpack.propTypes = {
|
||||
}),
|
||||
host: PropTypes.string,
|
||||
token: PropTypes.string,
|
||||
username: PropTypes.string
|
||||
username: PropTypes.string,
|
||||
vm: PropTypes.instanceOf(VM)
|
||||
};
|
||||
|
||||
const getTokenAndUsername = state => {
|
||||
|
||||
@@ -135,6 +135,12 @@ class TargetPane extends React.Component {
|
||||
if (dragInfo.dragType === DragConstants.SPRITE) {
|
||||
// Add one to both new and target index because we are not counting/moving the stage
|
||||
this.props.vm.reorderTarget(dragInfo.index + 1, dragInfo.newIndex + 1);
|
||||
} else if (dragInfo.dragType === DragConstants.BACKPACK_SPRITE) {
|
||||
// TODO storage does not have a way of loading zips right now, and may never need it.
|
||||
// So for now just grab the zip manually.
|
||||
fetch(dragInfo.payload.bodyUrl)
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(zip => this.props.vm.addSprite(zip));
|
||||
} else if (targetId) {
|
||||
// Something is being dragged over one of the sprite tiles or the backdrop.
|
||||
// Dropping assets like sounds and costumes duplicate the asset on the
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import xhr from 'xhr';
|
||||
import costumePayload from './backpack/costume-payload';
|
||||
import soundPayload from './backpack/sound-payload';
|
||||
import spritePayload from './backpack/sprite-payload';
|
||||
|
||||
const getBackpackContents = ({
|
||||
host,
|
||||
@@ -19,9 +20,13 @@ const getBackpackContents = ({
|
||||
return reject();
|
||||
}
|
||||
// Add a new property for the full thumbnail url, which includes the host.
|
||||
// Also include a full body url for loading sprite zips
|
||||
// TODO retreiving the images through storage would allow us to remove this.
|
||||
return resolve(response.body.map(item => (
|
||||
Object.assign({}, item, {thumbnailUrl: `${host}/${item.thumbnail}`})
|
||||
Object.assign({}, item, {
|
||||
thumbnailUrl: `${host}/${item.thumbnail}`,
|
||||
bodyUrl: `${host}/${item.body}`
|
||||
})
|
||||
)));
|
||||
});
|
||||
});
|
||||
@@ -72,5 +77,6 @@ export {
|
||||
saveBackpackObject,
|
||||
deleteBackpackObject,
|
||||
costumePayload,
|
||||
soundPayload
|
||||
soundPayload,
|
||||
spritePayload
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import jpegThumbnail from './jpeg-thumbnail';
|
||||
import storage from '../storage';
|
||||
|
||||
const spritePayload = (sprite, vm) => vm.exportSprite(
|
||||
sprite.id,
|
||||
'base64'
|
||||
).then(zippedSprite => {
|
||||
const payload = {
|
||||
type: 'sprite',
|
||||
name: sprite.name,
|
||||
mime: 'application/zip',
|
||||
body: zippedSprite,
|
||||
// Filled in below
|
||||
thumbnail: ''
|
||||
};
|
||||
|
||||
const costumeDataUrl = storage.get(sprite.costume.assetId).encodeDataURI();
|
||||
return jpegThumbnail(costumeDataUrl).then(thumbnail => {
|
||||
payload.thumbnail = thumbnail.replace('data:image/jpeg;base64,', '');
|
||||
return payload;
|
||||
});
|
||||
});
|
||||
|
||||
export default spritePayload;
|
||||
Reference in new issue
Block a user