Merge pull request #366 from paulkaplan/feature/click-to-add

Single-click to add from libraries + hover sounds
This commit is contained in:
Paul Kaplan authored and GitHub committed 2017-05-24 09:26:38 -04:00
commit 488ba96a18
7 files changed
+56 -41

No files matched your search

+2 -8
View File
@@ -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;
}
+17 -8
View File
@@ -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;
+17 -14
View File
@@ -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,
+2 -2
View File
@@ -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}
+2 -2
View File
@@ -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}
+14 -5
View File
@@ -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}
/>
+2 -2
View File
@@ -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}