Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/components/library/library.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,33 @@ const getAssetTypeForFileExtension = function (fileExtension) {
};

/**
* Figure out an `imageSource` (URI or asset ID & type) for a library item's icon.
* Figure out one or more icon(s) for a library item.
* If it's an animated thumbnail, this will return an array of `imageSource`.
* Otherwise it'll return just one `imageSource`.
* @param {object} item - either a library item or one of a library item's costumes.
* @returns {object} - an `imageSource` ready to be passed to a `ScratchImage`.
* The latter is used internally as part of processing an animated thumbnail.
* @returns {LibraryItem.PropTypes.icons} - an `imageSource` or array of them, ready for `LibraryItem` & `ScratchImage`
*/
const getItemImageSource = function (item) {
const getItemIcons = function (item) {
const costumes = (item.json && item.json.costumes) || item.costumes;
if (costumes) {
return costumes.map(getItemIcons);
}

if (item.rawURL) {
return {
uri: item.rawURL
};
}

// TODO: adjust libraries to be more storage-friendly; don't use split() here.
const md5ext = item.md5 || item.baseLayerMD5;
if (item.assetId && item.dataFormat) {
return {
assetId: item.assetId,
assetType: getAssetTypeForFileExtension(item.dataFormat)
};
}

const md5ext = item.md5ext || item.md5 || item.baseLayerMD5;
if (md5ext) {
const [assetId, fileExtension] = md5ext.split('.');
return {
Expand Down Expand Up @@ -251,8 +265,7 @@ class LibraryComponent extends React.Component {
ref={this.setFilteredDataRef}
>
{this.state.loaded ? this.getFilteredData().map((dataItem, index) => {
const iconSource = getItemImageSource(dataItem);
const icons = dataItem.json && dataItem.json.costumes.map(getItemImageSource);
const icons = getItemIcons(dataItem);
return (<LibraryItem
bluetoothRequired={dataItem.bluetoothRequired}
collaborator={dataItem.collaborator}
Expand All @@ -261,7 +274,6 @@ class LibraryComponent extends React.Component {
extensionId={dataItem.extensionId}
featured={dataItem.featured}
hidden={dataItem.hidden}
iconSource={iconSource}
icons={icons}
id={index}
insetIconURL={dataItem.insetIconURL}
Expand Down
5 changes: 2 additions & 3 deletions src/components/scratch-image/scratch-image.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ class ScratchImage extends React.PureComponent {
}
render () {
const {
src: _src,
imageSource: _imageSource,
...imgProps
} = this.props;
Expand All @@ -109,8 +108,8 @@ class ScratchImage extends React.PureComponent {
ScratchImage.loadPendingImages();
return (
<img
src={this.state.imageURI}
{...imgProps}
{...imgProps} // do this first in case it contains `src`
src={this.state.imageURI} // overrides imgProps.src if present
/>
);
}
Expand Down
28 changes: 18 additions & 10 deletions src/containers/library-item.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class LibraryItem extends React.PureComponent {
'startRotatingIcons',
'stopRotatingIcons'
]);
this.hasIconsArray = Array.isArray(props.icons);
this.state = {
iconIndex: 0,
isRotatingIcon: false
Expand Down Expand Up @@ -53,7 +54,7 @@ class LibraryItem extends React.PureComponent {
// only show hover effects on the item if not showing a play button
if (!this.props.showPlayButton) {
this.props.onMouseEnter(this.props.id);
if (this.props.icons && this.props.icons.length) {
if (this.hasIconsArray) {
this.stopRotatingIcons();
this.setState({
isRotatingIcon: true
Expand All @@ -65,7 +66,7 @@ class LibraryItem extends React.PureComponent {
// only show hover effects on the item if not showing a play button
if (!this.props.showPlayButton) {
this.props.onMouseLeave(this.props.id);
if (this.props.icons && this.props.icons.length) {
if (this.hasIconsArray) {
this.setState({
isRotatingIcon: false
}, this.stopRotatingIcons);
Expand All @@ -92,13 +93,18 @@ class LibraryItem extends React.PureComponent {
this.setState({iconIndex: nextIconIndex});
}
curIconSource () {
if (this.props.icons &&
this.state.isRotatingIcon &&
this.state.iconIndex < this.props.icons.length &&
this.props.icons[this.state.iconIndex]) {
return this.props.icons[this.state.iconIndex];
if (this.hasIconsArray) {
if (this.state.isRotatingIcon &&
this.state.iconIndex < this.props.icons.length &&
this.props.icons[this.state.iconIndex]) {
// multiple icons, currently animating: show current frame
return this.props.icons[this.state.iconIndex];
}
// multiple icons, not currently animating: show first frame
return this.props.icons[0];
}
return this.props.iconSource;
// single icon
return this.props.icons;
}
render () {
const iconSource = this.curIconSource();
Expand Down Expand Up @@ -142,8 +148,10 @@ LibraryItem.propTypes = {
extensionId: PropTypes.string,
featured: PropTypes.bool,
hidden: PropTypes.bool,
iconSource: LibraryItemComponent.propTypes.iconSource, // single icon
icons: PropTypes.arrayOf(LibraryItemComponent.propTypes.iconSource), // rotating icons
icons: PropTypes.oneOfType([
LibraryItemComponent.propTypes.iconSource, // single icon
PropTypes.arrayOf(LibraryItemComponent.propTypes.iconSource) // rotating icons
]),
id: PropTypes.number.isRequired,
insetIconURL: PropTypes.string,
internetConnectionRequired: PropTypes.bool,
Expand Down