From 1f0d0e7e5a55a8c4de11bc935d4bb2a76c257925 Mon Sep 17 00:00:00 2001 From: Karishma Chadha <kchadha@scratch.mit.edu> Date: Fri, 20 Apr 2018 12:40:18 -0400 Subject: [PATCH] Backdrop WIP --- .../stage-selector/stage-selector.jsx | 14 +++- src/containers/costume-tab.jsx | 4 -- src/containers/stage-selector.jsx | 65 ++++++++++++++++++- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/components/stage-selector/stage-selector.jsx b/src/components/stage-selector/stage-selector.jsx index 8af363c09..d4b7e13ec 100644 --- a/src/components/stage-selector/stage-selector.jsx +++ b/src/components/stage-selector/stage-selector.jsx @@ -32,16 +32,19 @@ const messages = defineMessages({ addBackdropFromFile: { id: 'gui.stageSelector.addBackdropFromFile', description: 'Button to add a stage in the target pane from file', - defaultMessage: 'Coming Soon' + defaultMessage: 'Upload Backdrop' } }); const StageSelector = props => { const { backdropCount, + fileInputRef, intl, selected, url, + onBackdropFileUploadClick, + onBackdropFileUpload, onClick, onNewBackdropClick, onSurpriseBackdropClick, @@ -81,7 +84,11 @@ const StageSelector = props => { moreButtons={[ { title: intl.formatMessage(messages.addBackdropFromFile), - img: fileUploadIcon + img: fileUploadIcon, + onClick: onBackdropFileUploadClick, + fileAccept: '.svg', // Bitmap coming soon + fileChange: onBackdropFileUpload, + fileInput: fileInputRef }, { title: intl.formatMessage(messages.addBackdropFromSurprise), img: surpriseIcon, @@ -102,7 +109,10 @@ const StageSelector = props => { StageSelector.propTypes = { backdropCount: PropTypes.number.isRequired, + fileInputRef: PropTypes.func, intl: intlShape.isRequired, + onBackdropFileUpload: PropTypes.func, + onBackdropFileUploadClick: PropTypes.func, onClick: PropTypes.func, onEmptyBackdropClick: PropTypes.func, onNewBackdropClick: PropTypes.func, diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx index c0ed6a4ba..50a38844c 100644 --- a/src/containers/costume-tab.jsx +++ b/src/containers/costume-tab.jsx @@ -193,12 +193,8 @@ class CostumeTab extends React.Component { const md5Ext = `${md5}.${costumeFormat}`; - // We don't have info about bitmapResolution or rotationCenter... const vmCostume = { name: 'costume1', - // rotationCenterX: 0, - // rotationCenterY: 0, - // bitmapResolution: 1, dataFormat: costumeFormat, md5: `${md5Ext}` }; diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx index bf749c12a..998ceb89b 100644 --- a/src/containers/stage-selector.jsx +++ b/src/containers/stage-selector.jsx @@ -18,7 +18,10 @@ class StageSelector extends React.Component { 'handleClick', 'handleSurpriseBackdrop', 'handleEmptyBackdrop', - 'addBackdropFromLibraryItem' + 'addBackdropFromLibraryItem', + 'handleFileUploadClick', + 'handleBackdropUpload', + 'setFileInput' ]); } addBackdropFromLibraryItem (item) { @@ -32,7 +35,7 @@ class StageSelector extends React.Component { return this.props.vm.addBackdrop(item.md5, vmBackdrop); } handleClick (e) { - e.preventDefault(); + // if (!this.fileInput || e.target !== this.fileInput) e.preventDefault(); this.props.onSelect(this.props.id); } handleSurpriseBackdrop () { @@ -51,6 +54,60 @@ class StageSelector extends React.Component { }); } } + handleBackdropUpload (e) { + const thisFileInput = e.target; + let thisFile = null; + const reader = new FileReader(); + reader.onload = () => { + // Reset the file input value now that we have everything we need + // so that the user can upload the same image multiple times + // if they choose + thisFileInput.value = null; + // Cache the image in storage + const backdropBuffer = reader.result; + const storage = this.props.vm.runtime.storage; + const fileType = thisFile.type; // check what the browser thinks this is + // Only handling png and svg right now + let backdropFormat = null; + let assetType = null; + if (fileType === 'image/svg+xml') { + backdropFormat = storage.DataFormat.SVG; + assetType = storage.AssetType.ImageVector; + } else if (fileType === 'image/jpeg') { + backdropFormat = storage.DataFormat.JPG; + assetType = storage.AssetType.ImageBitmap; + } else { + backdropFormat = storage.DataFormat.PNG; + assetType = storage.AssetType.ImageBitmap; + } + + const md5 = storage.builtinHelper.cache( + assetType, backdropFormat, new Uint8Array(backdropBuffer)); + + const md5Ext = `${md5}.${backdropFormat}`; + + const vmBackdrop = { + name: 'backdrop1', + dataFormat: backdropFormat, + md5: `${md5Ext}` + }; + + this.props.vm.addBackdrop(md5Ext, vmBackdrop); + + this.props.onActivateTab(COSTUMES_TAB_INDEX); + + }; + if (thisFileInput.files) { + thisFile = thisFileInput.files[0]; + reader.readAsArrayBuffer(thisFile); + } + } + handleFileUploadClick () { + this.fileInput.click(); + } + setFileInput (input) { + this.fileInput = input; + } render () { const { /* eslint-disable no-unused-vars */ @@ -63,9 +120,13 @@ class StageSelector extends React.Component { } = this.props; return ( <StageSelectorComponent + fileInputRef={this.setFileInput} + onBackdropFileUpload={this.handleBackdropUpload} + onBackdropFileUploadClick={this.handleFileUploadClick} onClick={this.handleClick} onEmptyBackdropClick={this.handleEmptyBackdrop} onSurpriseBackdropClick={this.handleSurpriseBackdrop} + {...componentProps} /> ); -- GitLab