diff --git a/src/components/library-item/library-item.css b/src/components/library-item/library-item.css index e25c478d2af2147ee88ebccb472fa3d00fff69dc..c702492f8939412c2222f49bf0d99daa5076a33f 100644 --- a/src/components/library-item/library-item.css +++ b/src/components/library-item/library-item.css @@ -27,12 +27,6 @@ transform: scale(1.02, 1.02); } -.library-item.is-selected { - border-width: 2px; - border-color: #1dacf4; - transition: 0.25s ease-out; -} - .library-item-image-container { height: 100px; } @@ -47,12 +41,12 @@ margin: 0.25rem 0; text-align: center; - /* + /* For truncating overflowing text gracefully Min-width is for a bug: https://css-tricks.com/flexbox-truncated-text */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - min-width: 0; + min-width: 0; } diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx index 31e722b0e8fd6cc9bb7d76cd24bd8fdf12cfe9e5..8e113c9be08af583a36272da486fe8afe31e0367 100644 --- a/src/components/library-item/library-item.jsx +++ b/src/components/library-item/library-item.jsx @@ -1,4 +1,3 @@ -const classNames = require('classnames'); const bindAll = require('lodash.bindall'); const PropTypes = require('prop-types'); const React = require('react'); @@ -9,20 +8,29 @@ const styles = require('./library-item.css'); class LibraryItem extends React.Component { constructor (props) { super(props); - bindAll(this, ['handleClick']); + bindAll(this, [ + 'handleClick', + 'handleMouseEnter', + 'handleMouseLeave' + ]); } handleClick (e) { this.props.onSelect(this.props.id); e.preventDefault(); } + handleMouseEnter () { + this.props.onMouseEnter(this.props.id); + } + handleMouseLeave () { + this.props.onMouseLeave(this.props.id); + } render () { return ( <Box - className={classNames({ - [styles.libraryItem]: true, - [styles.isSelected]: this.props.selected - })} + className={styles.libraryItem} onClick={this.handleClick} + onMouseEnter={this.handleMouseEnter} + onMouseLeave={this.handleMouseLeave} > <Box className={styles.libraryItemImageContainer}> <img @@ -40,8 +48,9 @@ LibraryItem.propTypes = { iconURL: PropTypes.string.isRequired, id: PropTypes.number.isRequired, name: PropTypes.string.isRequired, - onSelect: PropTypes.func.isRequired, - selected: PropTypes.bool.isRequired + onMouseEnter: PropTypes.func.isRequired, + onMouseLeave: PropTypes.func.isRequired, + onSelect: PropTypes.func.isRequired }; module.exports = LibraryItem; diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx index 16327c10c80cb075658e28484465998bf1ce7c4c..71b29ff612ff1552eae7df150f2eaa9782a9120d 100644 --- a/src/components/library/library.jsx +++ b/src/components/library/library.jsx @@ -10,20 +10,21 @@ const styles = require('./library.css'); class LibraryComponent extends React.Component { constructor (props) { super(props); - bindAll(this, ['handleSelect']); - this.state = {selectedItem: null}; + bindAll(this, [ + 'handleSelect', + 'handleMouseEnter', + 'handleMouseLeave' + ]); } handleSelect (id) { - if (this.state.selectedItem === id) { - // Double select: select as the library's value. - this.props.onRequestClose(); - this.props.onItemSelected(this.props.data[id]); - } else { - if (this.props.onItemChosen) { - this.props.onItemChosen(this.props.data[id]); - } - } - this.setState({selectedItem: id}); + this.props.onRequestClose(); + this.props.onItemSelected(this.props.data[id]); + } + handleMouseEnter (id) { + if (this.props.onItemMouseEnter) this.props.onItemMouseEnter(this.props.data[id]); + } + handleMouseLeave (id) { + if (this.props.onItemMouseLeave) this.props.onItemMouseLeave(this.props.data[id]); } render () { if (!this.props.visible) return null; @@ -45,7 +46,8 @@ class LibraryComponent extends React.Component { id={itemId} key={`item_${itemId}`} name={dataItem.name} - selected={this.state.selectedItem === itemId} + onMouseEnter={this.handleMouseEnter} + onMouseLeave={this.handleMouseLeave} onSelect={this.handleSelect} /> ); @@ -67,7 +69,8 @@ LibraryComponent.propTypes = { }) /* eslint-enable react/no-unused-prop-types, lines-around-comment */ ), - onItemChosen: PropTypes.func, + onItemMouseEnter: PropTypes.func, + onItemMouseLeave: PropTypes.func, onItemSelected: PropTypes.func, onRequestClose: PropTypes.func, title: PropTypes.string.isRequired, diff --git a/src/containers/backdrop-library.jsx b/src/containers/backdrop-library.jsx index b19921b4c77605d0f1f8700d1e70e7e814aea283..62e9cd473a21a9db548868af3bd1d273bcc18359 100644 --- a/src/containers/backdrop-library.jsx +++ b/src/containers/backdrop-library.jsx @@ -4,7 +4,7 @@ const React = require('react'); const VM = require('scratch-vm'); const backdropLibraryContent = require('../lib/libraries/backdrops.json'); -const LibaryComponent = require('../components/library/library.jsx'); +const LibraryComponent = require('../components/library/library.jsx'); class BackdropLibrary extends React.Component { @@ -26,7 +26,7 @@ class BackdropLibrary extends React.Component { } render () { return ( - <LibaryComponent + <LibraryComponent data={backdropLibraryContent} title="Backdrop Library" visible={this.props.visible} diff --git a/src/containers/costume-library.jsx b/src/containers/costume-library.jsx index 1fea39a2dda106f7941084469c81fb0886f32130..d0a004ba674e37c4710c581ef1c72bd7658d798d 100644 --- a/src/containers/costume-library.jsx +++ b/src/containers/costume-library.jsx @@ -4,7 +4,7 @@ const React = require('react'); const VM = require('scratch-vm'); const costumeLibraryContent = require('../lib/libraries/costumes.json'); -const LibaryComponent = require('../components/library/library.jsx'); +const LibraryComponent = require('../components/library/library.jsx'); class CostumeLibrary extends React.Component { @@ -26,7 +26,7 @@ class CostumeLibrary extends React.Component { } render () { return ( - <LibaryComponent + <LibraryComponent data={costumeLibraryContent} title="Costume Library" visible={this.props.visible} diff --git a/src/containers/sound-library.jsx b/src/containers/sound-library.jsx index d478d141a7f6d8c538a03830b7583d4d39ad990c..53aa6bde02f9d54e0d394691549bd04416c7bce5 100644 --- a/src/containers/sound-library.jsx +++ b/src/containers/sound-library.jsx @@ -3,7 +3,7 @@ const PropTypes = require('prop-types'); const React = require('react'); const VM = require('scratch-vm'); const AudioEngine = require('scratch-audio'); -const LibaryComponent = require('../components/library/library.jsx'); +const LibraryComponent = require('../components/library/library.jsx'); const soundIcon = require('../components/asset-panel/icon--sound.svg'); @@ -14,14 +14,19 @@ class SoundLibrary extends React.Component { super(props); bindAll(this, [ 'handleItemSelected', - 'handleItemChosen' + 'handleItemMouseEnter', + 'handleItemMouseLeave' ]); } componentDidMount () { this.audioEngine = new AudioEngine(); this.player = this.audioEngine.createPlayer(); } - handleItemChosen (soundItem) { + componentWillReceiveProps (newProps) { + // Stop playing sounds if the library closes without a mouseleave (e.g. by using the escape key) + if (this.player && !newProps.visible) this.player.stopAllSounds(); + } + handleItemMouseEnter (soundItem) { const md5ext = soundItem._md5; const idParts = md5ext.split('.'); const md5 = idParts[0]; @@ -39,6 +44,9 @@ class SoundLibrary extends React.Component { this.player.playSound(soundItem._md5); }); } + handleItemMouseLeave () { + this.player.stopAllSounds(); + } handleItemSelected (soundItem) { const vmSound = { format: soundItem.format, @@ -64,11 +72,12 @@ class SoundLibrary extends React.Component { }); return ( - <LibaryComponent + <LibraryComponent data={soundLibraryThumbnailData} title="Sound Library" visible={this.props.visible} - onItemChosen={this.handleItemChosen} + onItemMouseEnter={this.handleItemMouseEnter} + onItemMouseLeave={this.handleItemMouseLeave} onItemSelected={this.handleItemSelected} onRequestClose={this.props.onRequestClose} /> diff --git a/src/containers/sprite-library.jsx b/src/containers/sprite-library.jsx index c08748eb2337728cd862fe051b78b0da03dfe22e..0a1bcaa3ebcad309733aa10c5f98faf25c68f56a 100644 --- a/src/containers/sprite-library.jsx +++ b/src/containers/sprite-library.jsx @@ -5,7 +5,7 @@ const VM = require('scratch-vm'); const spriteLibraryContent = require('../lib/libraries/sprites.json'); -const LibaryComponent = require('../components/library/library.jsx'); +const LibraryComponent = require('../components/library/library.jsx'); class SpriteLibrary extends React.Component { constructor (props) { @@ -19,7 +19,7 @@ class SpriteLibrary extends React.Component { } render () { return ( - <LibaryComponent + <LibraryComponent data={spriteLibraryContent} title="Sprite Library" visible={this.props.visible}