Merge branch 'develop' into greenkeeper/scratch-l10n-3.0.20181024221158

This commit is contained in:
Andrew Sliwinski authored and GitHub committed 2018-10-25 09:41:48 -04:00
commit bf5f30de4a
15 files changed
+54 -50

No files matched your search

+4 -3
View File
@@ -29,6 +29,7 @@
"react-dom": "^16.0.0"
},
"devDependencies": {
"@babel/cli": "^7.1.2",
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
@@ -98,13 +99,13 @@
"redux-throttle": "0.1.1",
"rimraf": "^2.6.1",
"scratch-audio": "0.1.0-prerelease.20181023202904",
"scratch-blocks": "0.1.0-prerelease.1540403722",
"scratch-blocks": "0.1.0-prerelease.1540417094",
"scratch-l10n": "3.0.20181024221158",
"scratch-paint": "0.2.0-prerelease.20181024214759",
"scratch-render": "0.1.0-prerelease.20181023192935",
"scratch-render": "0.1.0-prerelease.20181024220305",
"scratch-storage": "1.1.0",
"scratch-svg-renderer": "0.2.0-prerelease.20181024192149",
"scratch-vm": "0.2.0-prerelease.20181023192708",
"scratch-vm": "0.2.0-prerelease.20181025092837",
"selenium-webdriver": "3.6.0",
"startaudiocontext": "1.2.1",
"style-loader": "^0.23.0",
+1 -1
View File
@@ -64,7 +64,7 @@ const Selector = props => {
onRemoveSortable={onRemoveSortable}
>
<SpriteSelectorItem
assetId={item.assetId}
asset={item.asset}
className={classNames(styles.listItem, {
[styles.placeholder]: isRelevantDrag && index === draggingIndex
})}
@@ -69,7 +69,7 @@ const SpriteList = function (props) {
onRemoveSortable={onRemoveSortable}
>
<SpriteSelectorItem
assetId={sprite.costume && sprite.costume.assetId}
asset={sprite.costume && sprite.costume.asset}
className={classNames(styles.sprite, {
[styles.raised]: isRaised,
[styles.receivedBlocks]: receivedBlocks
+2 -2
View File
@@ -79,9 +79,9 @@ const TargetPane = ({
/>
<div className={styles.stageSelectorWrapper}>
{stage.id && <StageSelector
assetId={
asset={
stage.costume &&
stage.costume.assetId
stage.costume.asset
}
backdropCount={stage.costumeCount}
id={stage.id}
+1 -1
View File
@@ -259,7 +259,7 @@ class CostumeTab extends React.Component {
const costumeData = target.costumes ? target.costumes.map(costume => ({
name: costume.name,
assetId: costume.assetId,
asset: costume.asset,
details: costume.size ? this.formatCostumeDetails(costume.size, costume.bitmapResolution) : null,
dragPayload: costume
})) : [];
+7 -5
View File
@@ -80,17 +80,19 @@ class RecordModal extends React.Component {
sampleCount: clippedSamples.length
};
// Load the encoded .wav into the storage cache and get resulting
// md5 from storage
const storage = this.props.vm.runtime.storage;
const md5 = storage.builtinHelper.cache(
// Create an asset from the encoded .wav and get resulting md5
const storage = this.props.vm.storage;
vmSound.asset = storage.createAsset(
storage.AssetType.Sound,
storage.DataFormat.WAV,
new Uint8Array(wavBuffer),
null,
true // generate md5
);
vmSound.assetId = vmSound.asset.assetId;
// update vmSound object with md5 property
vmSound.md5 = `${md5}.${vmSound.dataFormat}`;
vmSound.md5 = `${vmSound.assetId}.${vmSound.dataFormat}`;
// The VM will update the sound name to a fresh name
// if the following is already taken
vmSound.name = 'recording1';
+4 -3
View File
@@ -5,6 +5,7 @@ import {connect} from 'react-redux';
import {setHoveredSprite} from '../reducers/hovered-target';
import {updateAssetDrag} from '../reducers/asset-drag';
import storage from '../lib/storage';
import {getEventXY} from '../lib/touch-utils';
import VM from 'scratch-vm';
import getCostumeUrl from '../lib/get-costume-url';
@@ -44,9 +45,9 @@ class SpriteSelectorItem extends React.Component {
}
getCostumeData () {
if (this.props.costumeURL) return this.props.costumeURL;
if (!this.props.assetId) return null;
if (!this.props.asset) return null;
return getCostumeUrl(this.props.assetId, this.props.vm);
return getCostumeUrl(this.props.asset);
}
handleMouseUp () {
this.initialOffset = null;
@@ -147,7 +148,7 @@ class SpriteSelectorItem extends React.Component {
}
SpriteSelectorItem.propTypes = {
assetId: PropTypes.string,
asset: PropTypes.instanceOf(storage.Asset),
costumeURL: PropTypes.string,
dispatchSetHoveredSprite: PropTypes.func.isRequired,
dragPayload: PropTypes.shape({
+3 -3
View File
@@ -106,7 +106,7 @@ class StageSelector extends React.Component {
}
render () {
const componentProps = omit(this.props, [
'assetId', 'dispatchSetHoveredSprite', 'id', 'intl', 'onActivateTab', 'onSelect']);
'asset', 'dispatchSetHoveredSprite', 'id', 'intl', 'onActivateTab', 'onSelect']);
return (
<DroppableStage
fileInputRef={this.setFileInput}
@@ -130,8 +130,8 @@ StageSelector.propTypes = {
onSelect: PropTypes.func
};
const mapStateToProps = (state, {assetId, id}) => ({
url: assetId && state.scratchGui.vm.runtime.storage.get(assetId).encodeDataURI(),
const mapStateToProps = (state, {asset, id}) => ({
url: asset && asset.encodeDataURI(),
vm: state.scratchGui.vm,
receivedBlocks: state.scratchGui.hoveredTarget.receivedBlocks &&
state.scratchGui.hoveredTarget.sprite === id,
+9 -8
View File
@@ -5,6 +5,7 @@ import React from 'react';
import {connect} from 'react-redux';
import VM from 'scratch-vm';
import storage from '../lib/storage';
import getCostumeUrl from '../lib/get-costume-url';
import WatermarkComponent from '../components/watermark/watermark.jsx';
@@ -20,13 +21,13 @@ class Watermark extends React.Component {
}
getCostumeData () {
if (!this.props.assetId) return null;
if (!this.props.asset) return null;
return getCostumeUrl(this.props.assetId, this.props.vm);
return getCostumeUrl(this.props.asset);
}
render () {
const componentProps = omit(this.props, ['assetId', 'vm']);
const componentProps = omit(this.props, ['asset', 'vm']);
return (
<WatermarkComponent
costumeURL={this.getCostumeData()}
@@ -37,7 +38,7 @@ class Watermark extends React.Component {
}
Watermark.propTypes = {
assetId: PropTypes.string,
asset: PropTypes.instanceOf(storage.Asset),
vm: PropTypes.instanceOf(VM).isRequired
};
@@ -45,19 +46,19 @@ const mapStateToProps = state => {
const targets = state.scratchGui.targets;
const currentTargetId = targets.editingTarget;
let assetId;
let asset;
if (currentTargetId) {
if (targets.stage.id === currentTargetId) {
assetId = targets.stage.costume.assetId;
asset = targets.stage.costume.asset;
} else if (targets.sprites.hasOwnProperty(currentTargetId)) {
const currentSprite = targets.sprites[currentTargetId];
assetId = currentSprite.costume.assetId;
asset = currentSprite.costume.asset;
}
}
return {
vm: state.scratchGui.vm,
assetId: assetId
asset: asset
};
};
+1 -2
View File
@@ -1,9 +1,8 @@
import jpegThumbnail from './jpeg-thumbnail';
import storage from '../storage';
const costumePayload = costume => {
// TODO is it ok to base64 encode SVGs? What about unicode text inside them?
const assetDataUrl = storage.get(costume.assetId).encodeDataURI();
const assetDataUrl = costume.asset.encodeDataURI();
const assetDataFormat = costume.dataFormat;
const payload = {
type: 'costume',
+1 -2
View File
@@ -1,9 +1,8 @@
// eslint-disable-next-line import/no-unresolved
import soundThumbnail from '!base64-loader!./sound-thumbnail.jpg';
import storage from '../storage';
const soundPayload = sound => {
const assetDataUrl = storage.get(sound.assetId).encodeDataURI();
const assetDataUrl = sound.asset.encodeDataURI();
const assetDataFormat = sound.dataFormat;
const payload = {
type: 'sound',
+1 -2
View File
@@ -1,5 +1,4 @@
import jpegThumbnail from './jpeg-thumbnail';
import storage from '../storage';
const spritePayload = (sprite, vm) => vm.exportSprite(
sprite.id,
@@ -14,7 +13,7 @@ const spritePayload = (sprite, vm) => vm.exportSprite(
thumbnail: ''
};
const costumeDataUrl = storage.get(sprite.costume.assetId).encodeDataURI();
const costumeDataUrl = sprite.costume.asset.encodeDataURI();
return jpegThumbnail(costumeDataUrl).then(thumbnail => {
payload.thumbnail = thumbnail.replace('data:image/jpeg;base64,', '');
return payload;
+11 -8
View File
@@ -51,7 +51,7 @@ const handleFileUpload = function (fileInput, onload) {
*/
/**
* Cache an asset (costume, sound) in storage and return an object representation
* Create an asset (costume, sound) with storage and return an object representation
* of the asset to track in the VM.
* @param {ScratchStorage} storage The storage to cache the asset in
* @param {string} fileName The name of the asset
@@ -62,18 +62,21 @@ const handleFileUpload = function (fileInput, onload) {
* @return {VMAsset} An object representing this asset and relevant information
* which can be used to look up the data in storage
*/
const cacheAsset = function (storage, fileName, assetType, dataFormat, data) {
const md5 = storage.builtinHelper.cache(
const createVMAsset = function (storage, fileName, assetType, dataFormat, data) {
const asset = storage.createAsset(
assetType,
dataFormat,
data
data,
null,
true // generate md5
);
return {
name: fileName,
dataFormat: dataFormat,
md5: `${md5}.${dataFormat}`,
assetId: md5
asset: asset,
md5: `${asset.assetId}.${dataFormat}`,
assetId: asset.assetId
};
};
@@ -114,7 +117,7 @@ const costumeUpload = function (fileData, fileType, costumeName, storage, handle
const bitmapAdapter = new BitmapAdapter();
const addCostumeFromBuffer = function (dataBuffer) {
const vmCostume = cacheAsset(
const vmCostume = createVMAsset(
storage,
costumeName,
assetType,
@@ -170,7 +173,7 @@ const soundUpload = function (fileData, fileType, soundName, storage, handleSoun
return;
}
const vmSound = cacheAsset(
const vmSound = createVMAsset(
storage,
soundName,
storage.AssetType.Sound,
+7 -8
View File
@@ -1,3 +1,4 @@
import storage from './storage';
import {SVGRenderer} from 'scratch-svg-renderer';
// Contains 'font-family', but doesn't only contain 'font-family="none"'
@@ -7,30 +8,28 @@ const getCostumeUrl = (function () {
let cachedAssetId;
let cachedUrl;
return function (assetId, vm) {
return function (asset) {
if (cachedAssetId === assetId) {
if (cachedAssetId === asset.assetId) {
return cachedUrl;
}
cachedAssetId = assetId;
cachedAssetId = asset.assetId;
const storage = vm.runtime.storage;
const asset = storage.get(assetId);
// If the SVG refers to fonts, they must be inlined in order to display correctly in the img tag.
// Avoid parsing the SVG when possible, since it's expensive.
if (asset.assetType === storage.AssetType.ImageVector) {
const svgString = vm.runtime.storage.get(assetId).decodeText();
const svgString = asset.decodeText();
if (svgString.match(HAS_FONT_REGEXP)) {
const svgRenderer = new SVGRenderer();
svgRenderer.loadString(svgString);
const svgText = svgRenderer.toString(true /* shouldInjectFonts */);
cachedUrl = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
} else {
cachedUrl = vm.runtime.storage.get(assetId).encodeDataURI();
cachedUrl = asset.encodeDataURI();
}
} else {
cachedUrl = vm.runtime.storage.get(assetId).encodeDataURI();
cachedUrl = asset.encodeDataURI();
}
return cachedUrl;
+1 -1
View File
@@ -55,7 +55,7 @@ class Storage extends ScratchStorage {
}
cacheDefaultProject () {
const defaultProjectAssets = defaultProject(this.translator);
defaultProjectAssets.forEach(asset => this.cache(
defaultProjectAssets.forEach(asset => this.builtinHelper._store(
this.AssetType[asset.assetType],
this.DataFormat[asset.dataFormat],
asset.data,