From 86b6e12453e120a838d66bf8ab12fea16dae990d Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Tue, 16 Oct 2018 17:31:10 -0700 Subject: [PATCH] WIP: Load media libs with scratch-storage The basics work but hover animations are broken --- src/components/library-item/library-item.jsx | 16 +++++++-- src/components/library/library.jsx | 34 +++++++++++++++++--- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx index 03a9d6b78..48d117d96 100644 --- a/src/components/library-item/library-item.jsx +++ b/src/components/library-item/library-item.jsx @@ -13,6 +13,13 @@ import internetConnectionIconURL from './internet-connection.svg'; class LibraryItem extends React.PureComponent { constructor (props) { super(props); + this.state = { + iconURL: null + }; + Promise.resolve(props.iconURL) + .then(url => this.setState({ + iconURL: url + })); bindAll(this, [ 'handleBlur', 'handleClick', @@ -72,7 +79,7 @@ class LibraryItem extends React.PureComponent { ) : null} {this.props.insetIconURL ? ( @@ -158,7 +165,7 @@ class LibraryItem extends React.PureComponent { @@ -179,7 +186,10 @@ LibraryItem.propTypes = { extensionId: PropTypes.string, featured: PropTypes.bool, hidden: PropTypes.bool, - iconURL: PropTypes.string, + iconURL: PropTypes.oneOfType([ + PropTypes.string, // URL + PropTypes.instanceOf(Promise) // Promise for URL + ]), id: PropTypes.number.isRequired, insetIconURL: PropTypes.string, internetConnectionRequired: PropTypes.bool, diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx index 8ecb76181..f1eceb806 100644 --- a/src/components/library/library.jsx +++ b/src/components/library/library.jsx @@ -10,6 +10,7 @@ import Divider from '../divider/divider.jsx'; import Filter from '../filter/filter.jsx'; import TagButton from '../../containers/tag-button.jsx'; import analytics from '../../lib/analytics'; +import storage from '../../lib/storage'; import styles from './library.css'; @@ -29,6 +30,23 @@ const messages = defineMessages({ const ALL_TAG = {tag: 'all', intlLabel: messages.allTag}; const tagListPrefix = [ALL_TAG]; +/** + * @param {string} extension - the extension to look up. + * @returns {AssetType} - the AssetType corresponding to the extension, if any. + */ +const getAssetTypeForExtension = function (extension) { + const compareOptions = { + sensitivity: 'accent', + usage: 'search' + }; + for (const assetTypeId of Object.keys(storage.AssetType)) { + const assetType = storage.AssetType[assetTypeId]; + if (extension.localeCompare(assetType.runtimeFormat, compareOptions) === 0) { + return assetType; + } + } +}; + class LibraryComponent extends React.Component { constructor (props) { super(props); @@ -173,9 +191,17 @@ class LibraryComponent extends React.Component { ref={this.setFilteredDataRef} > {this.getFilteredData().map((dataItem, index) => { - const scratchURL = dataItem.md5 ? - `https://cdn.assets.scratch.mit.edu/internalapi/asset/${dataItem.md5}/get/` : - dataItem.rawURL; + let iconURL; + if (dataItem.md5) { + // TODO: adjust libraries to be more storage-friendly; don't use split() here. + const [md5, ext] = dataItem.md5.split('.'); + const assetType = getAssetTypeForExtension(ext); + iconURL = storage.load(assetType, md5) + .then(asset => asset.encodeDataURI()); + } else { + iconURL = dataItem.rawURL; + } + return (