From dadef73bfa050b4b00f3f2c4ff8c0c54e6b8ae65 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Mar 2019 14:12:41 -0500 Subject: [PATCH 01/10] Testing two icons side by side to see how the padding is currently working. --- src/components/library-item/library-item.jsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx index 3880a4cf6..0fa462311 100644 --- a/src/components/library-item/library-item.jsx +++ b/src/components/library-item/library-item.jsx @@ -78,6 +78,12 @@ class LibraryItemComponent extends React.PureComponent { internetConnectionIconURL } /> + ) : null} From 31625d68070ece780678a1b87663b7116d7147a0 Mon Sep 17 00:00:00 2001 From: Evelyn Eastmond Date: Tue, 12 Mar 2019 10:10:59 -0400 Subject: [PATCH 02/10] Adding ability to show both bluetooth and internet icons in extension library item tiles. --- src/components/library-item/library-item.jsx | 18 ++++++------------ src/lib/libraries/extensions/index.jsx | 6 +++++- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx index 0fa462311..5af6fb159 100644 --- a/src/components/library-item/library-item.jsx +++ b/src/components/library-item/library-item.jsx @@ -72,18 +72,12 @@ class LibraryItemComponent extends React.PureComponent {
- - + {this.props.bluetoothRequired ? ( + + ) : null} + {this.props.internetConnectionRequired ? ( + + ) : null}
) : null} diff --git a/src/lib/libraries/extensions/index.jsx b/src/lib/libraries/extensions/index.jsx index 9bc3bc3d2..3d1dd6658 100644 --- a/src/lib/libraries/extensions/index.jsx +++ b/src/lib/libraries/extensions/index.jsx @@ -163,6 +163,7 @@ export default [ featured: true, disabled: false, bluetoothRequired: true, + internetConnectionRequired: true, launchPeripheralConnectionFlow: true, useAutoScan: false, peripheralImage: microbitPeripheralImage, @@ -192,6 +193,7 @@ export default [ featured: true, disabled: false, bluetoothRequired: true, + internetConnectionRequired: true, launchPeripheralConnectionFlow: true, useAutoScan: false, peripheralImage: ev3PeripheralImage, @@ -221,6 +223,7 @@ export default [ featured: true, disabled: false, bluetoothRequired: true, + internetConnectionRequired: true, launchPeripheralConnectionFlow: true, useAutoScan: true, peripheralImage: wedoPeripheralImage, @@ -250,6 +253,7 @@ export default [ ), featured: true, disabled: true, - bluetoothRequired: true + bluetoothRequired: true, + internetConnectionRequired: true } ]; From f29b82b63608999a088908944460c630bcc2f7ad Mon Sep 17 00:00:00 2001 From: Evelyn Eastmond Date: Tue, 12 Mar 2019 10:39:27 -0400 Subject: [PATCH 03/10] Adding right padding to icons. --- src/components/library-item/library-item.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/library-item/library-item.css b/src/components/library-item/library-item.css index 692e1b612..5e726a363 100644 --- a/src/components/library-item/library-item.css +++ b/src/components/library-item/library-item.css @@ -178,6 +178,10 @@ font-weight: bold; } +.featured-extension-metadata-detail img{ + margin-right: 0.25rem; +} + .coming-soon-text { position: absolute; background-color: $data-primary; From 5f2f95a6dbce939024ff882f1101f8fd9bde0150 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Fri, 21 Dec 2018 01:46:25 -0800 Subject: [PATCH 04/10] HACK: report telemetry events if telemetry is active --- src/lib/project-saver-hoc.jsx | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx index 6e6848e92..f57c1039b 100644 --- a/src/lib/project-saver-hoc.jsx +++ b/src/lib/project-saver-hoc.jsx @@ -25,6 +25,7 @@ import { getIsAnyCreatingNewState, getIsCreatingCopy, getIsCreatingNew, + getIsLoading, getIsManualUpdating, getIsRemixing, getIsShowingWithId, @@ -59,6 +60,13 @@ const ProjectSaverHOC = function (WrappedComponent) { } } componentDidUpdate (prevProps) { + if (!this.props.isAnyCreatingNewState && prevProps.isAnyCreatingNewState) { + this.reportTelemetryEvent('projectWasCreated'); + } + if (!this.props.isLoading && prevProps.isLoading) { + this.reportTelemetryEvent('projectDidLoad'); + } + if (this.props.projectChanged && !prevProps.projectChanged) { this.scheduleAutoSave(); } @@ -289,6 +297,46 @@ const ProjectSaverHOC = function (WrappedComponent) { } } + /** + * Report a telemetry event. + * @param {string} event - one of `projectWasCreated`, `projectDidLoad`, `projectDidSave`, `projectWasUploaded` + */ + //TODO make a telemetry HOC and move this stuff there + reportTelemetryEvent (event) { + if (this.props.onProjectTelemetryEvent) { + //TODO move most or all of this into a collectMetadata() method on the VM/Runtime + const metadata = { + projectName: this.props.reduxProjectTitle, + language: this.props.locale, + spriteCount: 0, + blocksCount: 0, + costumesCount: 0, + listsCount: 0, + scriptCount: 0, + soundsCount: 0, + variablesCount: 0 + }; + + for (const target of this.props.vm.runtime.targets) { + ++metadata.spriteCount; + metadata.blocksCount += Object.keys(target.sprite.blocks._blocks).length; + metadata.costumesCount += target.sprite.costumes_.length; + metadata.scriptCount += target.sprite.blocks._scripts.length; + metadata.soundsCount += target.sprite.sounds.length; + for (const variableName in target.variables) { + const variable = target.variables[variableName]; + if (variable.type === 'list') { + ++metadata.listsCount; + } else { + ++metadata.variablesCount; + } + } + } + + this.props.onProjectTelemetryEvent(event, metadata); + } + } + render () { const { /* eslint-disable no-unused-vars */ @@ -298,6 +346,7 @@ const ProjectSaverHOC = function (WrappedComponent) { isCreatingNew, projectChanged, isAnyCreatingNewState, + isLoading, isManualUpdating, isRemixing, isShowingSaveable, @@ -342,6 +391,7 @@ const ProjectSaverHOC = function (WrappedComponent) { isAnyCreatingNewState: PropTypes.bool, isCreatingCopy: PropTypes.bool, isCreatingNew: PropTypes.bool, + isLoading: PropTypes.bool, isManualUpdating: PropTypes.bool, isRemixing: PropTypes.bool, isShared: PropTypes.bool, @@ -354,6 +404,7 @@ const ProjectSaverHOC = function (WrappedComponent) { onCreateProject: PropTypes.func, onCreatedProject: PropTypes.func, onProjectError: PropTypes.func, + onProjectTelemetryEvent: PropTypes.func, onRemixing: PropTypes.func, onShowAlert: PropTypes.func, onShowCopySuccessAlert: PropTypes.func, @@ -379,6 +430,7 @@ const ProjectSaverHOC = function (WrappedComponent) { return { autoSaveTimeoutId: state.scratchGui.timeout.autoSaveTimeoutId, isAnyCreatingNewState: getIsAnyCreatingNewState(loadingState), + isLoading: getIsLoading(loadingState), isCreatingCopy: getIsCreatingCopy(loadingState), isCreatingNew: getIsCreatingNew(loadingState), isRemixing: getIsRemixing(loadingState), @@ -388,6 +440,7 @@ const ProjectSaverHOC = function (WrappedComponent) { isUpdating: getIsUpdating(loadingState), isManualUpdating: getIsManualUpdating(loadingState), loadingState: loadingState, + locale: state.locales.locale, projectChanged: state.scratchGui.projectChanged, reduxProjectId: state.scratchGui.projectState.projectId, reduxProjectTitle: state.scratchGui.projectTitle, From f6dc2726b559098dc25db28922d73001a57d5ade Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Fri, 28 Dec 2018 03:36:30 -0800 Subject: [PATCH 05/10] Implement projectDidSave telemetry event --- src/components/gui/gui.jsx | 2 ++ src/components/menu-bar/menu-bar.jsx | 25 +++++++++++++++--- src/lib/collect-metadata.js | 39 ++++++++++++++++++++++++++++ src/lib/project-saver-hoc.jsx | 31 ++-------------------- 4 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 src/lib/collect-metadata.js diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index a203310b1..829215b39 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -99,6 +99,7 @@ const GUIComponent = props => { onActivateTab, onClickLogo, onExtensionButtonClick, + onProjectTelemetryEvent, onRequestCloseBackdropLibrary, onRequestCloseCostumeLibrary, onRequestCloseTelemetryModal, @@ -225,6 +226,7 @@ const GUIComponent = props => { onCloseAccountNav={onCloseAccountNav} onLogOut={onLogOut} onOpenRegistration={onOpenRegistration} + onProjectTelemetryEvent={onProjectTelemetryEvent} onSeeCommunity={onSeeCommunity} onShare={onShare} onToggleLoginOpen={onToggleLoginOpen} diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx index 825f6096f..671f94b8e 100644 --- a/src/components/menu-bar/menu-bar.jsx +++ b/src/components/menu-bar/menu-bar.jsx @@ -5,6 +5,8 @@ import PropTypes from 'prop-types'; import bindAll from 'lodash.bindall'; import React from 'react'; +import VM from 'scratch-vm'; + import Box from '../box/box.jsx'; import Button from '../button/button.jsx'; import CommunityButton from './community-button.jsx'; @@ -54,6 +56,8 @@ import { loginMenuOpen } from '../../reducers/menus'; +import collectMetadata from '../../lib/collect-metadata'; + import styles from './menu-bar.css'; import helpIcon from '../../lib/assets/icon--tutorials.svg'; @@ -153,6 +157,7 @@ class MenuBar extends React.Component { 'handleCloseFileMenuAndThen', 'handleLanguageMouseUp', 'handleRestoreOption', + 'handleSaveToComputer', 'restoreOptionMessage' ]); } @@ -219,6 +224,16 @@ class MenuBar extends React.Component { fn(); }; } + handleSaveToComputer (downloadProject) { + return () => { + this.props.onRequestCloseFile(); + downloadProject(); + if (this.props.onProjectTelemetryEvent) { + const metadata = collectMetadata(this.props.vm, this.props.projectTitle, this.props.locale); + this.props.onProjectTelemetryEvent('projectDidSave', metadata); + } + }; + } handleLanguageMouseUp (e) { if (!this.props.languageMenuOpen) { this.props.onClickLanguage(e); @@ -395,7 +410,7 @@ class MenuBar extends React.Component { {(className, downloadProject) => ( { isUpdating: getIsUpdating(loadingState), isShowingProject: getIsShowingProject(loadingState), languageMenuOpen: languageMenuOpen(state), + locale: state.locales.locale, loginMenuOpen: loginMenuOpen(state), projectChanged: state.scratchGui.projectChanged, projectTitle: state.scratchGui.projectTitle, sessionExists: state.session && typeof state.session.session !== 'undefined', - username: user ? user.username : null + username: user ? user.username : null, + vm: state.scratchGui.vm }; }; diff --git a/src/lib/collect-metadata.js b/src/lib/collect-metadata.js new file mode 100644 index 000000000..0623aa96d --- /dev/null +++ b/src/lib/collect-metadata.js @@ -0,0 +1,39 @@ +/** + * Report a telemetry event. + * @param {string} event - one of `projectWasCreated`, `projectDidLoad`, `projectDidSave`, `projectWasUploaded` + */ +//TODO make a telemetry HOC and move this stuff there +const collectMetadata = function (vm, projectName = '', locale = '') { + //TODO move most or all of this into a collectMetadata() method on the VM/Runtime + const metadata = { + projectName: projectName, + language: locale, + spriteCount: 0, + blocksCount: 0, + costumesCount: 0, + listsCount: 0, + scriptCount: 0, + soundsCount: 0, + variablesCount: 0 + }; + + for (const target of vm.runtime.targets) { + ++metadata.spriteCount; + metadata.blocksCount += Object.keys(target.sprite.blocks._blocks).length; + metadata.costumesCount += target.sprite.costumes_.length; + metadata.scriptCount += target.sprite.blocks._scripts.length; + metadata.soundsCount += target.sprite.sounds.length; + for (const variableName in target.variables) { + const variable = target.variables[variableName]; + if (variable.type === 'list') { + ++metadata.listsCount; + } else { + ++metadata.variablesCount; + } + } + } + + return metadata; +}; + +export default collectMetadata; diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx index f57c1039b..addfd6eb0 100644 --- a/src/lib/project-saver-hoc.jsx +++ b/src/lib/project-saver-hoc.jsx @@ -6,6 +6,7 @@ import {connect} from 'react-redux'; import VM from 'scratch-vm'; import xhr from 'xhr'; +import collectMetadata from '../lib/collect-metadata'; import log from '../lib/log'; import storage from '../lib/storage'; import dataURItoBlob from '../lib/data-uri-to-blob'; @@ -304,35 +305,7 @@ const ProjectSaverHOC = function (WrappedComponent) { //TODO make a telemetry HOC and move this stuff there reportTelemetryEvent (event) { if (this.props.onProjectTelemetryEvent) { - //TODO move most or all of this into a collectMetadata() method on the VM/Runtime - const metadata = { - projectName: this.props.reduxProjectTitle, - language: this.props.locale, - spriteCount: 0, - blocksCount: 0, - costumesCount: 0, - listsCount: 0, - scriptCount: 0, - soundsCount: 0, - variablesCount: 0 - }; - - for (const target of this.props.vm.runtime.targets) { - ++metadata.spriteCount; - metadata.blocksCount += Object.keys(target.sprite.blocks._blocks).length; - metadata.costumesCount += target.sprite.costumes_.length; - metadata.scriptCount += target.sprite.blocks._scripts.length; - metadata.soundsCount += target.sprite.sounds.length; - for (const variableName in target.variables) { - const variable = target.variables[variableName]; - if (variable.type === 'list') { - ++metadata.listsCount; - } else { - ++metadata.variablesCount; - } - } - } - + const metadata = collectMetadata(this.props.vm, this.props.reduxProjectTitle, this.props.locale); this.props.onProjectTelemetryEvent(event, metadata); } } From f0ba4180c739fb8a862c4741690ebe22c2797887 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Mon, 4 Mar 2019 16:33:27 -0800 Subject: [PATCH 06/10] Fix spacing in comments --- src/lib/collect-metadata.js | 4 ++-- src/lib/project-saver-hoc.jsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/collect-metadata.js b/src/lib/collect-metadata.js index 0623aa96d..d71b4448b 100644 --- a/src/lib/collect-metadata.js +++ b/src/lib/collect-metadata.js @@ -2,9 +2,9 @@ * Report a telemetry event. * @param {string} event - one of `projectWasCreated`, `projectDidLoad`, `projectDidSave`, `projectWasUploaded` */ -//TODO make a telemetry HOC and move this stuff there +// TODO make a telemetry HOC and move this stuff there const collectMetadata = function (vm, projectName = '', locale = '') { - //TODO move most or all of this into a collectMetadata() method on the VM/Runtime + // TODO move most or all of this into a collectMetadata() method on the VM/Runtime const metadata = { projectName: projectName, language: locale, diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx index 2eb837963..2cee625ec 100644 --- a/src/lib/project-saver-hoc.jsx +++ b/src/lib/project-saver-hoc.jsx @@ -318,7 +318,7 @@ const ProjectSaverHOC = function (WrappedComponent) { * Report a telemetry event. * @param {string} event - one of `projectWasCreated`, `projectDidLoad`, `projectDidSave`, `projectWasUploaded` */ - //TODO make a telemetry HOC and move this stuff there + // TODO make a telemetry HOC and move this stuff there reportTelemetryEvent (event) { if (this.props.onProjectTelemetryEvent) { const metadata = collectMetadata(this.props.vm, this.props.reduxProjectTitle, this.props.locale); From 3e33c10b04e7d314c49a5e9af36ad0d9c3473a94 Mon Sep 17 00:00:00 2001 From: chrisgarrity Date: Thu, 7 Mar 2019 14:12:20 +0100 Subject: [PATCH 07/10] Fix mock store for project-saver-hoc test Account for the addition of locale prop expected in mapStateToProps. Note: if/when the telemetry code gets moved into its own hoc, the prop should get removed, and the test should get updated as well. --- test/unit/util/project-saver-hoc.test.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/unit/util/project-saver-hoc.test.jsx b/test/unit/util/project-saver-hoc.test.jsx index 62176a7c5..1336daef0 100644 --- a/test/unit/util/project-saver-hoc.test.jsx +++ b/test/unit/util/project-saver-hoc.test.jsx @@ -22,6 +22,9 @@ describe('projectSaverHOC', () => { timeout: { autoSaveTimeoutId: null } + }, + locales: { + locale: 'en' } }); vm = new VM(); From 3adacd3f2afa3cc76fde9bbf02451d1d05453a66 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Wed, 13 Mar 2019 22:48:55 +0000 Subject: [PATCH 08/10] chore(package): update scratch-blocks to version 0.1.0-prerelease.1552509492 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc91a9c81..4af6fcb04 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "redux-throttle": "0.1.1", "rimraf": "^2.6.1", "scratch-audio": "0.1.0-prerelease.20190114210212", - "scratch-blocks": "0.1.0-prerelease.1551865183", + "scratch-blocks": "0.1.0-prerelease.1552509492", "scratch-l10n": "3.1.20190220143732", "scratch-paint": "0.2.0-prerelease.20190311150519", "scratch-render": "0.1.0-prerelease.20190312125229", From bb0e1e54cd7f692330643d70dfdc0f9169a234d6 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Thu, 14 Mar 2019 02:46:54 +0000 Subject: [PATCH 09/10] chore(package): update scratch-vm to version 0.2.0-prerelease.20190314020908 Closes #4650 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc91a9c81..41bab06c9 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "scratch-render": "0.1.0-prerelease.20190312125229", "scratch-storage": "1.2.2", "scratch-svg-renderer": "0.2.0-prerelease.20190304180800", - "scratch-vm": "0.2.0-prerelease.20190312212117", + "scratch-vm": "0.2.0-prerelease.20190314020908", "selenium-webdriver": "3.6.0", "startaudiocontext": "1.2.1", "style-loader": "^0.23.0", From 5051ba2105b58b5f4789b35ca62c5bfebd54b24b Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Thu, 14 Mar 2019 10:35:39 -0700 Subject: [PATCH 10/10] Code review: remove dead code, clarify arg name --- src/components/menu-bar/menu-bar.jsx | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx index 966aa5271..972809d2d 100644 --- a/src/components/menu-bar/menu-bar.jsx +++ b/src/components/menu-bar/menu-bar.jsx @@ -150,7 +150,6 @@ class MenuBar extends React.Component { 'handleClickSaveAsCopy', 'handleClickSeeCommunity', 'handleClickShare', - 'handleCloseFileMenuAndThen', 'handleKeyPress', 'handleLanguageMouseUp', 'handleRestoreOption', @@ -221,12 +220,6 @@ class MenuBar extends React.Component { this.props.onRequestCloseEdit(); }; } - handleCloseFileMenuAndThen (fn) { - return () => { - this.props.onRequestCloseFile(); - fn(); - }; - } handleKeyPress (event) { const modifier = bowser.mac ? event.metaKey : event.ctrlKey; if (modifier && event.key === 's') { @@ -234,10 +227,10 @@ class MenuBar extends React.Component { event.preventDefault(); } } - handleSaveToComputer (downloadProject) { + handleSaveToComputer (downloadProjectCallback) { return () => { this.props.onRequestCloseFile(); - downloadProject(); + downloadProjectCallback(); if (this.props.onProjectTelemetryEvent) { const metadata = collectMetadata(this.props.vm, this.props.projectTitle, this.props.locale); this.props.onProjectTelemetryEvent('projectDidSave', metadata); @@ -417,10 +410,10 @@ class MenuBar extends React.Component { )} - {(className, downloadProject) => ( + {(className, downloadProjectCallback) => (