diff --git a/package.json b/package.json index 3615b32ae4a3bbdd7f7a59871b2cf0b9a74feacf..10c2e5667a85eaa80731b08961d16a840fc2a4fa 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "arraybuffer-loader": "^1.0.6", - "autoprefixer": "^8.1.0", + "autoprefixer": "^9.0.1", "babel-core": "^6.23.1", "babel-eslint": "^8.0.1", "babel-loader": "^7.1.0", @@ -40,12 +40,12 @@ "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.22.0", "base64-loader": "1.0.0", - "bowser": "1.9.3", + "bowser": "1.9.4", "chromedriver": "2.40.0", "classnames": "2.2.6", "copy-webpack-plugin": "^4.5.1", "core-js": "2.5.7", - "css-loader": "^0.28.11", + "css-loader": "^1.0.0", "enzyme": "^3.1.0", "enzyme-adapter-react-16": "1.1.1", "es6-object-assign": "1.1.0", @@ -82,27 +82,27 @@ "react-draggable": "3.0.5", "react-ga": "2.5.3", "react-intl": "2.4.0", - "react-modal": "3.4.4", + "react-modal": "3.5.1", "react-popover": "0.5.7", "react-redux": "5.0.7", - "react-responsive": "4.1.0", + "react-responsive": "5.0.0", "react-style-proptype": "3.2.1", "react-tabs": "2.2.2", "react-test-renderer": "16.2.0", "react-tooltip": "3.6.1", - "react-virtualized": "9.20.0", + "react-virtualized": "9.20.1", "redux": "3.7.2", "redux-mock-store": "^1.2.3", "redux-throttle": "0.1.1", "rimraf": "^2.6.1", "scratch-audio": "0.1.0-prerelease.20180625202813", - "scratch-blocks": "0.1.0-prerelease.1532024291", + "scratch-blocks": "0.1.0-prerelease.1532446271", "scratch-l10n": "3.0.20180719145856", "scratch-paint": "0.2.0-prerelease.20180718183615", - "scratch-render": "0.1.0-prerelease.20180618173030", + "scratch-render": "0.1.0-prerelease.20180724152606", "scratch-storage": "0.5.1", "scratch-svg-renderer": "0.2.0-prerelease.20180712223402", - "scratch-vm": "0.2.0-prerelease.20180719205147", + "scratch-vm": "0.2.0-prerelease.20180724192502", "selenium-webdriver": "3.6.0", "startaudiocontext": "1.2.1", "style-loader": "^0.21.0", diff --git a/src/components/asset-panel/selector.css b/src/components/asset-panel/selector.css index 3dc4e803d9e9d7f9c26c2c8c5a1da69b388bd943..df47d41de1ec424da7a8006d35754bc92f61559d 100644 --- a/src/components/asset-panel/selector.css +++ b/src/components/asset-panel/selector.css @@ -70,5 +70,5 @@ $fade-out-distance: 100px; .list-item.placeholder { background: black; - filter: opacity(15%) brightness(20%); + filter: opacity(15%) brightness(0%); } diff --git a/src/components/language-selector/language-selector.jsx b/src/components/language-selector/language-selector.jsx index ad7a9aa90f96aac8e27e7c97994f29049d98edcf..a6707bbced246129ee8d464694b6a117ec833555 100644 --- a/src/components/language-selector/language-selector.jsx +++ b/src/components/language-selector/language-selector.jsx @@ -5,6 +5,9 @@ import Box from '../box/box.jsx'; import locales from 'scratch-l10n'; import styles from './language-selector.css'; +// supported languages to exclude from the menu, but allow as a URL option +const ignore = ['he']; + class LanguageSelector extends React.Component { render () { const { @@ -26,14 +29,18 @@ class LanguageSelector extends React.Component { value={currentLocale} onChange={onChange} > - {Object.keys(locales).map(locale => ( - <option - key={locale} - value={locale} - > - {locales[locale].name} - </option> - ))} + { + Object.keys(locales) + .filter(l => !ignore.includes(l)) + .map(locale => ( + <option + key={locale} + value={locale} + > + {locales[locale].name} + </option> + )) + } </select> </div> </Box> diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx index 2da09f2720deed4e72e02943665175af3cdbe46b..9d63fc3bfad63cab11cf3f8df27bec40d7f9c13e 100644 --- a/src/components/library/library.jsx +++ b/src/components/library/library.jsx @@ -62,12 +62,8 @@ class LibraryComponent extends React.Component { this.props.onItemSelected(this.getFilteredData()[id]); } handleClose () { - analytics.event({ - category: 'library', - action: `${this.props.id}: close with search`, - label: this.state.filterQuery || '(empty)' - }); this.props.onRequestClose(); + analytics.pageview(`/${this.props.id}/search?q=${this.state.filterQuery}`); } handleTagClick (tag) { this.setState({ diff --git a/src/components/modal/modal.css b/src/components/modal/modal.css index 8bf2b6cb8fab403f28a867468b7d437c5f4de684..3b318f40ddd7b0697e33d90aa31b505c519a0394 100644 --- a/src/components/modal/modal.css +++ b/src/components/modal/modal.css @@ -126,6 +126,7 @@ $sides: 20rem; .header-item-help { padding: 0; margin-right: -4.75rem; + z-index: 1; } .help-button { diff --git a/src/components/monitor/list-monitor.jsx b/src/components/monitor/list-monitor.jsx index 7ebeb0b5a1e21ca15cabd96d44c56bf60caaf8f0..daa9f33eb47f83ca56e6af080582d9c0f3234221 100644 --- a/src/components/monitor/list-monitor.jsx +++ b/src/components/monitor/list-monitor.jsx @@ -26,7 +26,7 @@ const ListMonitor = ({draggable, label, width, height, value, onResizeMouseDown, </div> <div className={styles.listFooter}> <div - className={classNames(styles.addButton, 'no-drag')} + className={classNames(draggable ? styles.addButton : null, 'no-drag')} onClick={draggable ? onAdd : null} > {'+' /* TODO waiting on asset */} @@ -35,7 +35,7 @@ const ListMonitor = ({draggable, label, width, height, value, onResizeMouseDown, {`length ${value.length}`} </div> <div - className={classNames(styles.resizeHandle, 'no-drag')} + className={classNames(draggable ? styles.resizeHandle : null, 'no-drag')} onMouseDown={draggable ? onResizeMouseDown : null} > {'=' /* TODO waiting on asset */} diff --git a/src/components/sprite-selector/sprite-selector.css b/src/components/sprite-selector/sprite-selector.css index ef19439855ab37c64259af3465f5ea9789df9242..70895211757bba3a752569a9969aaf21c783cc8e 100644 --- a/src/components/sprite-selector/sprite-selector.css +++ b/src/components/sprite-selector/sprite-selector.css @@ -110,5 +110,5 @@ .placeholder > .sprite { background: black; - filter: opacity(15%) brightness(20%); + filter: opacity(15%) brightness(0%); } diff --git a/src/components/sprite-selector/sprite-selector.jsx b/src/components/sprite-selector/sprite-selector.jsx index da09bf9ca00c4e66fb702fc71232a682fde5fafc..e6948c5b7d85c08720a24625425e560c345811aa 100644 --- a/src/components/sprite-selector/sprite-selector.jsx +++ b/src/components/sprite-selector/sprite-selector.jsx @@ -36,7 +36,7 @@ const messages = defineMessages({ addSpriteFromFile: { id: 'gui.spriteSelector.addSpriteFromFile', description: 'Button to add a sprite in the target pane from file', - defaultMessage: 'Upload' + defaultMessage: 'Upload Sprite' } }); diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx index cd3d4ff5383e60427b86bd11cf4137b93b6b5ee9..3862fa653fbe239a2db9d6e29175bcca64f508b4 100644 --- a/src/containers/blocks.jsx +++ b/src/containers/blocks.jsx @@ -310,6 +310,11 @@ class Blocks extends React.Component { this.workspace.scale = scale; this.workspace.resize(); } + + // Clear the undo state of the workspace since this is a + // fresh workspace and we don't want any changes made to another sprites + // workspace to be 'undone' here. + this.workspace.clearUndo(); } handleExtensionAdded (blocksInfo) { // select JSON from each block info object then reject the pseudo-blocks which don't have JSON, like separators diff --git a/src/containers/stage.jsx b/src/containers/stage.jsx index 0ff48ef0216f2482d0d01e340340b95c274be0f0..1ab84412eed16a676b3e9e8fcf04d2b9cd0c6f78 100644 --- a/src/containers/stage.jsx +++ b/src/containers/stage.jsx @@ -309,11 +309,13 @@ class Stage extends React.Component { const targetId = this.props.vm.getTargetIdForDrawableId(drawableId); if (targetId === null) return; - // Only start drags on non-draggable targets in editor drag mode - if (!this.props.useEditorDragStyle) { - const target = this.props.vm.runtime.getTargetById(targetId); - if (!target.draggable) return; - } + const target = this.props.vm.runtime.getTargetById(targetId); + + // Do not start drag unless in editor drag mode or target is draggable + if (!(this.props.useEditorDragStyle || target.draggable)) return; + + // Dragging always brings the target to the front + target.goToFront(); this.props.vm.startDrag(targetId); this.setState({ diff --git a/src/lib/vm-listener-hoc.jsx b/src/lib/vm-listener-hoc.jsx index 3fd9e2096f1f0c3de8b6b843ff75dba696d52af3..28f578b371b89bb717cf8dffa01c4a752530d464 100644 --- a/src/lib/vm-listener-hoc.jsx +++ b/src/lib/vm-listener-hoc.jsx @@ -37,6 +37,12 @@ const vmListenerHOC = function (WrappedComponent) { document.addEventListener('keydown', this.handleKeyDown); document.addEventListener('keyup', this.handleKeyUp); } + this.props.vm.postIOData('userData', {username: this.props.username}); + } + componentWillReceiveProps (newProps) { + if (newProps.username !== this.props.username) { + this.props.vm.postIOData('userData', {username: newProps.username}); + } } componentWillUnmount () { if (this.props.attachKeyboardEvents) { @@ -72,6 +78,7 @@ const vmListenerHOC = function (WrappedComponent) { const { /* eslint-disable no-unused-vars */ attachKeyboardEvents, + username, onBlockDragUpdate, onKeyDown, onKeyUp, @@ -90,13 +97,16 @@ const vmListenerHOC = function (WrappedComponent) { onKeyUp: PropTypes.func, onMonitorsUpdate: PropTypes.func.isRequired, onTargetsUpdate: PropTypes.func.isRequired, + username: PropTypes.string, vm: PropTypes.instanceOf(VM).isRequired }; VMListener.defaultProps = { attachKeyboardEvents: true }; const mapStateToProps = state => ({ - vm: state.scratchGui.vm + vm: state.scratchGui.vm, + username: state.session && state.session.session ? + state.session.session.username : '' }); const mapDispatchToProps = dispatch => ({ onTargetsUpdate: data => {