diff --git a/src/import/load-costume.js b/src/import/load-costume.js index 31eac9dbc..648a82a1c 100644 --- a/src/import/load-costume.js +++ b/src/import/load-costume.js @@ -152,21 +152,31 @@ const loadCostumeFromAsset = function (costume, costumeAsset, runtime, optVersio * @returns {?Promise} - a promise which will resolve after skinId is set, or null on error. */ const loadCostume = function (md5ext, costume, runtime, optVersion) { - if (!runtime.storage) { - log.error('No storage module present; cannot load costume asset: ', md5ext); - return Promise.resolve(costume); + let costumePromise; + if (costume.asset) { + // Costume comes with asset. It could be coming from camera, image upload, drag and drop, or sb file + costumePromise = Promise.resolve(costume.asset); + } else { + // Need to load the costume from storage. The server should have a reference to this md5. + if (!runtime.storage) { + log.error('No storage module present; cannot load costume asset: ', md5ext); + return Promise.resolve(costume); + } + + const AssetType = runtime.storage.AssetType; + const idParts = StringUtil.splitFirst(md5ext, '.'); + const md5 = idParts[0]; + const ext = idParts[1].toLowerCase(); + const assetType = (ext === 'svg') ? AssetType.ImageVector : AssetType.ImageBitmap; + costume.dataFormat = ext; + costumePromise = runtime.storage.load(assetType, md5, ext); + if (!costumePromise) { + log.error(`Couldn't fetch costume asset: ${md5ext}`); + return; + } } - const AssetType = runtime.storage.AssetType; - const idParts = StringUtil.splitFirst(md5ext, '.'); - const md5 = idParts[0]; - const ext = idParts[1].toLowerCase(); - const assetType = (ext === 'svg') ? AssetType.ImageVector : AssetType.ImageBitmap; - costume.dataFormat = ext; - return ( - (costume.asset && Promise.resolve(costume.asset)) || - runtime.storage.load(assetType, md5, ext) - ).then(costumeAsset => { + return costumePromise.then(costumeAsset => { costume.asset = costumeAsset; return loadCostumeFromAsset(costume, costumeAsset, runtime, optVersion); }) diff --git a/src/serialization/deserialize-assets.js b/src/serialization/deserialize-assets.js index cc787b9c6..603a1b8e2 100644 --- a/src/serialization/deserialize-assets.js +++ b/src/serialization/deserialize-assets.js @@ -79,7 +79,10 @@ const deserializeCostume = function (costume, runtime, zip, assetFileName) { costume.asset.dataFormat, new Uint8Array(Object.keys(costume.asset.data).map(key => costume.asset.data[key])), costume.asset.assetId - )); + )) + .then(asset => { + costume.asset = asset; + }); } if (!zip) { @@ -112,7 +115,10 @@ const deserializeCostume = function (costume, runtime, zip, assetFileName) { costumeFormat, data, assetId - )); + )) + .then(asset => { + costume.asset = asset; + }); }; module.exports = { diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index d30ef7bd6..b0c4bae4f 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -413,10 +413,7 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip) // the file name of the costume should be the baseLayerID followed by the file ext const assetFileName = `${costumeSource.baseLayerID}.${ext}`; costumePromises.push(deserializeCostume(costume, runtime, zip, assetFileName) - .then(asset => { - costume.asset = asset; - return loadCostume(costume.md5, costume, runtime, 2 /* optVersion */); - }) + .then(() => loadCostume(costume.md5, costume, runtime, 2 /* optVersion */)) ); } } diff --git a/src/serialization/sb3.js b/src/serialization/sb3.js index e3433258b..98c24be48 100644 --- a/src/serialization/sb3.js +++ b/src/serialization/sb3.js @@ -847,10 +847,7 @@ const parseScratchObject = function (object, runtime, extensions, zip) { // any translation that needs to happen will happen in the process // of building up the costume object into an sb3 format return deserializeCostume(costume, runtime, zip) - .then(asset => { - costume.asset = asset; - return loadCostume(costumeMd5Ext, costume, runtime); - }); + .then(() => loadCostume(costumeMd5Ext, costume, runtime)); // Only attempt to load the costume after the deserialization // process has been completed });