From c91c0da8a7dbdeb00dc8789211192c3add51ee38 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sat, 22 Jul 2017 16:49:49 -0400 Subject: [PATCH 1/9] Update to React 15.6 Once we're upgraded to React 15.x and have no deprecation warnings, upgrading to React 16 should be painless. PureRenderMixin has been superceded by PureComponent. According to the docs PureComponent should only be used if all of it's children are also "pure". https://facebook.github.io/react/docs/react-api.html#react.purecomponent --- app/scripts/views/pie_chart.js | 6 ++---- app/scripts/views/rhythm_settings_view.js | 2 -- app/scripts/views/rhythm_statistic_view.js | 2 -- app/scripts/views/stave_renderer.js | 8 +++----- package.json | 5 ++--- 5 files changed, 7 insertions(+), 16 deletions(-) diff --git a/app/scripts/views/pie_chart.js b/app/scripts/views/pie_chart.js index 5f24d3e..fa06d0f 100644 --- a/app/scripts/views/pie_chart.js +++ b/app/scripts/views/pie_chart.js @@ -1,15 +1,13 @@ import Chartist from "Chartist"; -import React, { Component } from "react"; -import PureRenderMixin from "react-addons-pure-render-mixin"; +import React, { PureComponent } from "react"; -export default class LevelView extends Component { +export default class LevelView extends PureComponent { static propTypes = { pieParts: React.PropTypes.array.isRequired }; constructor(props, context) { super(props, context); - this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); } render() { diff --git a/app/scripts/views/rhythm_settings_view.js b/app/scripts/views/rhythm_settings_view.js index dfcac1a..6b8ee28 100644 --- a/app/scripts/views/rhythm_settings_view.js +++ b/app/scripts/views/rhythm_settings_view.js @@ -1,5 +1,4 @@ import React, { Component } from "react"; -import PureRenderMixin from "react-addons-pure-render-mixin"; import RangeSettingComponent from "./range_setting_component"; import SettingLine from "./setting_line"; import AnalyticsService from "../services/analytics_service.js"; @@ -12,7 +11,6 @@ export default class PitchSettingsView extends Component { constructor(props, context) { super(props, context); - this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); } buildStateChanger(stateKey) { diff --git a/app/scripts/views/rhythm_statistic_view.js b/app/scripts/views/rhythm_statistic_view.js index e6a71e9..d7c6d04 100644 --- a/app/scripts/views/rhythm_statistic_view.js +++ b/app/scripts/views/rhythm_statistic_view.js @@ -5,7 +5,6 @@ import _ from "lodash"; import AnimatedNumber from "./animated_number.js"; import StarAnimation from "./star_animation.js"; -import PureRenderMixin from "react-addons-pure-render-mixin"; export default class RhythmStatisticView extends Component { static propTypes = { @@ -14,7 +13,6 @@ export default class RhythmStatisticView extends Component { constructor(props) { super(props); - this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); } getHumanReadableTime(milliseconds) { diff --git a/app/scripts/views/stave_renderer.js b/app/scripts/views/stave_renderer.js index 36a2fc5..187f3ff 100644 --- a/app/scripts/views/stave_renderer.js +++ b/app/scripts/views/stave_renderer.js @@ -1,15 +1,14 @@ import Vex from "vexflow"; -import React, { Component } from "react"; +import React, { PureComponent } from "react"; import _ from "lodash"; -import PureRenderMixin from "react-addons-pure-render-mixin"; -class StaveRenderer extends Component { +class StaveRenderer extends PureComponent { static defaultProps = { staveCount: 2 }; static propTypes = { - keys: React.PropTypes.array, + keys: React.PropTypes.objectOf(React.PropTypes.array), chordIndex: React.PropTypes.number, keySignature: React.PropTypes.string, staveCount: React.PropTypes.number @@ -17,7 +16,6 @@ class StaveRenderer extends Component { constructor(props) { super(props); - this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); } render() { diff --git a/package.json b/package.json index 0bc0002..5115b8b 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,9 @@ "freezer-js": "git+https://github.com/philippotto/freezer.git#native-object-handling-build", "html-loader": "^0.4.3", "lodash": "^4.5.1", - "react": "^0.14.5", - "react-addons-pure-render-mixin": "^0.14.8", + "react": "^15.6.1", "react-bootstrap": "^0.28.3", - "react-dom": "^0.14.5", + "react-dom": "^15.6.1", "react-motion": "^0.4.2", "react-range-slider-bem": "^0.2.11", "vexflow": "^1.2.41" From eb1da1820ea55ff6a070df176ed0e8c998634e44 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sat, 22 Jul 2017 23:44:13 -0400 Subject: [PATCH 2/9] Update eslint-react-plugin for react 15.x Wanted to check for errors that may exist due to upgrading React. Fixed errors found: - PropTypes is now a separate module - string refs are now deprecated, see: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md - target="_blank" needs rel="noopener noreferrer" for security, see: https://mathiasbynens.github.io/rel-noopener/ --- app/scripts/App.js | 21 +++++++++++++++--- app/scripts/views/animated_number.js | 5 +++-- app/scripts/views/beat_visualization.js | 11 +++++----- app/scripts/views/claviature_view.js | 13 ++++++----- app/scripts/views/collapsable_container.js | 11 +++++----- app/scripts/views/game_button.js | 13 ++++++----- app/scripts/views/level_view.js | 3 ++- app/scripts/views/metronome_view.js | 7 +++--- app/scripts/views/newsletter_form.js | 6 +++-- app/scripts/views/pie_chart.js | 14 +++++++++--- app/scripts/views/pitch_reading_view.js | 22 ++++++++++++++----- app/scripts/views/pitch_settings_view.js | 9 +++++--- app/scripts/views/pitch_statistic_view.js | 16 +++++++++----- app/scripts/views/privacy_policy_modal.js | 3 ++- app/scripts/views/range_setting_component.js | 17 +++++++++------ app/scripts/views/rhythm_reading_view.js | 23 +++++++++++--------- app/scripts/views/rhythm_settings_view.js | 3 ++- app/scripts/views/rhythm_statistic_view.js | 14 ++++++++---- app/scripts/views/setting_line.js | 3 ++- app/scripts/views/star_animation.js | 3 ++- app/scripts/views/stave_renderer.js | 20 ++++++++++++----- package.json | 5 +++-- 22 files changed, 159 insertions(+), 83 deletions(-) diff --git a/app/scripts/App.js b/app/scripts/App.js index a3fdd68..0cf2415 100644 --- a/app/scripts/App.js +++ b/app/scripts/App.js @@ -105,13 +105,28 @@ export default class App extends Component {
- + - + - +
diff --git a/app/scripts/views/animated_number.js b/app/scripts/views/animated_number.js index 294ebc8..03269b6 100644 --- a/app/scripts/views/animated_number.js +++ b/app/scripts/views/animated_number.js @@ -1,10 +1,11 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Motion, spring } from "react-motion"; export default class AnimatedNumber extends Component { static propTypes = { - formatter: React.PropTypes.func, - number: React.PropTypes.number + formatter: PropTypes.func, + number: PropTypes.number }; render() { const formatter = this.props.formatter; diff --git a/app/scripts/views/beat_visualization.js b/app/scripts/views/beat_visualization.js index ce31ea2..bcb39c1 100644 --- a/app/scripts/views/beat_visualization.js +++ b/app/scripts/views/beat_visualization.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import classNames from "classnames"; import _ from "lodash"; @@ -6,11 +7,11 @@ import RhythmChecker from "../services/rhythm_checker.js"; export default class BeatVisualization extends Component { static propTypes = { - settings: React.PropTypes.object.isRequired, - barDuration: React.PropTypes.number.isRequired, - currentRhythm: React.PropTypes.object.isRequired, - beatHistory: React.PropTypes.object.isRequired, - result: React.PropTypes.object.isRequired + settings: PropTypes.object.isRequired, + barDuration: PropTypes.number.isRequired, + currentRhythm: PropTypes.object.isRequired, + beatHistory: PropTypes.object.isRequired, + result: PropTypes.object.isRequired }; convertTicksToBeatNames(tickTime, tickLength) { diff --git a/app/scripts/views/claviature_view.js b/app/scripts/views/claviature_view.js index f101a46..16eb8c7 100644 --- a/app/scripts/views/claviature_view.js +++ b/app/scripts/views/claviature_view.js @@ -1,14 +1,15 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import KeyConverter from "../services/key_converter.js"; import classNames from "classnames"; export default class ClaviatureView extends Component { static propTypes = { - desiredKeys: React.PropTypes.array, - keySignature: React.PropTypes.string, - successCallback: React.PropTypes.func, - failureCallback: React.PropTypes.func, - disabled: React.PropTypes.bool + desiredKeys: PropTypes.array, + keySignature: PropTypes.string, + successCallback: PropTypes.func, + failureCallback: PropTypes.func, + disabled: PropTypes.bool }; constructor(props, context) { @@ -20,7 +21,7 @@ export default class ClaviatureView extends Component { } static contextTypes = { - isInActiveView: React.PropTypes.bool + isInActiveView: PropTypes.bool }; isNoteCorrect(noteName) { diff --git a/app/scripts/views/collapsable_container.js b/app/scripts/views/collapsable_container.js index 5b022e1..ac4d9da 100644 --- a/app/scripts/views/collapsable_container.js +++ b/app/scripts/views/collapsable_container.js @@ -1,14 +1,15 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import classNames from "classnames"; import _ from "lodash"; export default class BeatVisualization extends Component { static propTypes = { - children: React.PropTypes.node, - collapsed: React.PropTypes.bool.isRequired, - maxHeight: React.PropTypes.number, - freeze: React.PropTypes.bool, - className: React.PropTypes.string + children: PropTypes.node, + collapsed: PropTypes.bool.isRequired, + maxHeight: PropTypes.number, + freeze: PropTypes.bool, + className: PropTypes.string }; componentWillReceiveProps(nextProps) { diff --git a/app/scripts/views/game_button.js b/app/scripts/views/game_button.js index b41bb44..bf69246 100644 --- a/app/scripts/views/game_button.js +++ b/app/scripts/views/game_button.js @@ -1,16 +1,17 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Button } from "react-bootstrap"; export default class GameButton extends Component { static propTypes = { - label: React.PropTypes.string.isRequired, - onClick: React.PropTypes.func.isRequired, - primary: React.PropTypes.bool, - shortcutLetter: React.PropTypes.string + label: PropTypes.string.isRequired, + onClick: PropTypes.func.isRequired, + primary: PropTypes.bool, + shortcutLetter: PropTypes.string }; static contextTypes = { - isInActiveView: React.PropTypes.bool + isInActiveView: PropTypes.bool }; componentDidMount() { @@ -41,7 +42,7 @@ export default class GameButton extends Component { const subtext = this.props.shortcutLetter ?
- Or press '{this.props.shortcutLetter}' + Or press ‘{this.props.shortcutLetter}’
: null; diff --git a/app/scripts/views/level_view.js b/app/scripts/views/level_view.js index b13eed3..7dd7555 100644 --- a/app/scripts/views/level_view.js +++ b/app/scripts/views/level_view.js @@ -1,11 +1,12 @@ import _ from "lodash"; import React, { Component } from "react"; +import PropTypes from "prop-types"; import LevelService from "../services/level_service.js"; import PieChart from "../views/pie_chart.js"; export default class LevelView extends Component { static propTypes = { - statisticService: React.PropTypes.object.isRequired + statisticService: PropTypes.object.isRequired }; render() { diff --git a/app/scripts/views/metronome_view.js b/app/scripts/views/metronome_view.js index 3adbf8b..4a06ab6 100644 --- a/app/scripts/views/metronome_view.js +++ b/app/scripts/views/metronome_view.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import classNames from "classnames"; import _ from "lodash"; @@ -7,9 +8,9 @@ import CollapsableContainer from "./collapsable_container.js"; export default class MetronomeView extends Component { static propTypes = { - onMetronomeEnded: React.PropTypes.func, - settings: React.PropTypes.object.isRequired, - statisticService: React.PropTypes.object.isRequired + onMetronomeEnded: PropTypes.func, + settings: PropTypes.object.isRequired, + statisticService: PropTypes.object.isRequired }; constructor(props, context) { diff --git a/app/scripts/views/newsletter_form.js b/app/scripts/views/newsletter_form.js index b741216..cb976a2 100644 --- a/app/scripts/views/newsletter_form.js +++ b/app/scripts/views/newsletter_form.js @@ -5,7 +5,7 @@ export default class NewsLetterForm extends Component { // This avoids that global keyhandlers for keyboard navigation are triggered // when email input is used. const dontPropagate = evt => evt.stopPropagation(); - const email = this.refs.email; + const email = this.email; email.addEventListener("keypress", dontPropagate); email.addEventListener("keyup", dontPropagate); email.addEventListener("keydown", dontPropagate); @@ -32,7 +32,9 @@ export default class NewsLetterForm extends Component { name="EMAIL" id="mce-EMAIL" placeholder="your@email.com" - ref="email" + ref={c => { + this.email = c; + }} className="form-control" groupClassName="group-class" labelClassName="label-class" diff --git a/app/scripts/views/pie_chart.js b/app/scripts/views/pie_chart.js index fa06d0f..8c67f23 100644 --- a/app/scripts/views/pie_chart.js +++ b/app/scripts/views/pie_chart.js @@ -1,9 +1,10 @@ import Chartist from "Chartist"; +import PropTypes from "prop-types"; import React, { PureComponent } from "react"; export default class LevelView extends PureComponent { static propTypes = { - pieParts: React.PropTypes.array.isRequired + pieParts: PropTypes.array.isRequired }; constructor(props, context) { @@ -11,12 +12,19 @@ export default class LevelView extends PureComponent { } render() { - return
; + return ( +
{ + this.chart = c; + }} + className="semi-transparent ct-chart ct-major-eleventh" + /> + ); } componentDidUpdate() { new Chartist.Pie( - this.refs.chart, + this.chart, { series: this.props.pieParts }, diff --git a/app/scripts/views/pitch_reading_view.js b/app/scripts/views/pitch_reading_view.js index e5f145e..29f9e75 100644 --- a/app/scripts/views/pitch_reading_view.js +++ b/app/scripts/views/pitch_reading_view.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import classNames from "classnames"; import _ from "lodash"; @@ -17,13 +18,13 @@ const successMp3Url = require("file!../../resources/success.mp3"); export default class PitchReadingView extends Component { static propTypes = { - statisticService: React.PropTypes.object.isRequired, - settings: React.PropTypes.object.isRequired, - isActive: React.PropTypes.bool.isRequired + statisticService: PropTypes.object.isRequired, + settings: PropTypes.object.isRequired, + isActive: PropTypes.bool.isRequired }; static childContextTypes = { - isInActiveView: React.PropTypes.bool + isInActiveView: PropTypes.bool }; getChildContext() { @@ -237,7 +238,16 @@ export default class PitchReadingView extends Component {
-
); @@ -297,7 +307,7 @@ export default class PitchReadingView extends Component { } playSuccessSound() { - this.refs.successPlayer.play(); + this.successPlayer.play(); } onFailure() { diff --git a/app/scripts/views/pitch_settings_view.js b/app/scripts/views/pitch_settings_view.js index 3043eb7..f8e809b 100644 --- a/app/scripts/views/pitch_settings_view.js +++ b/app/scripts/views/pitch_settings_view.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import RangeSettingComponent from "./range_setting_component"; import SettingLine from "./setting_line"; import KeyConverter from "../services/key_converter"; @@ -8,7 +9,7 @@ import AnalyticsService from "../services/analytics_service.js"; export default class PitchSettingsView extends Component { static propTypes = { - settings: React.PropTypes.object + settings: PropTypes.object }; constructor(props, context) { @@ -42,7 +43,7 @@ export default class PitchSettingsView extends Component { } onMidiSelectChange() { - AppFreezer.trigger("input:changed", parseInt(this.refs.midiSelect.value, 10)); + AppFreezer.trigger("input:changed", parseInt(this.midiSelect.value, 10)); } render() { @@ -56,7 +57,9 @@ export default class PitchSettingsView extends Component { name="select" onChange={this.onMidiSelectChange.bind(this)} defaultValue={midiSettings.currentInput} - ref="midiSelect" + ref={c => { + this.midiSelect = c; + }} > {midiInputs.map((el, index) => { return ( diff --git a/app/scripts/views/pitch_statistic_view.js b/app/scripts/views/pitch_statistic_view.js index 3d9618e..e120342 100644 --- a/app/scripts/views/pitch_statistic_view.js +++ b/app/scripts/views/pitch_statistic_view.js @@ -1,5 +1,6 @@ import Chartist from "Chartist"; import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Tooltip, OverlayTrigger } from "react-bootstrap"; import LevelView from "./level_view.js"; import CollapsableContainer from "./collapsable_container.js"; @@ -9,8 +10,8 @@ import StarAnimation from "./star_animation.js"; export default class PitchStatisticView extends Component { static propTypes = { - statisticService: React.PropTypes.object.isRequired, - settings: React.PropTypes.object.isRequired + statisticService: PropTypes.object.isRequired, + settings: PropTypes.object.isRequired }; render() { @@ -21,7 +22,12 @@ export default class PitchStatisticView extends Component { return (
-
+
{ + this.chart = c; + }} + className="semi-transparent ct-chart ct-major-eleventh" + />
@@ -90,8 +96,8 @@ export default class PitchStatisticView extends Component { } }; - if (statistics.getSuccessCount() > 1) { - Chartist.Line(this.refs.chart, data, options); + if (this.chart && statistics.getSuccessCount() > 1) { + Chartist.Line(this.chart, data, options); } } } diff --git a/app/scripts/views/privacy_policy_modal.js b/app/scripts/views/privacy_policy_modal.js index 6bb551e..586589d 100644 --- a/app/scripts/views/privacy_policy_modal.js +++ b/app/scripts/views/privacy_policy_modal.js @@ -1,9 +1,10 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Modal, Button } from "react-bootstrap"; export default class PrivacyPolicyModal extends Component { static propTypes = { - onHide: React.PropTypes.func.isRequired + onHide: PropTypes.func.isRequired }; render() { diff --git a/app/scripts/views/range_setting_component.js b/app/scripts/views/range_setting_component.js index 48794d7..627ce22 100644 --- a/app/scripts/views/range_setting_component.js +++ b/app/scripts/views/range_setting_component.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import RangeSlider from "react-range-slider-bem"; import SettingLine from "./setting_line"; import _ from "lodash"; @@ -23,18 +24,20 @@ export default class SettingsView extends Component { constructor(props, context) { super(props, context); - this.receiveValueAsProps(this.props); + this.state = { + values: this.valuesFromProps(this.props) + }; } - receiveValueAsProps(props) { + valuesFromProps(props) { let values = _.isArray(props.values) ? props.values : [props.values]; - this.state = { - values: values.map(el => el * multiplier) - }; + return values.map(el => el * multiplier); } componentWillReceiveProps(newProps) { - this.receiveValueAsProps(newProps); + this.setState = { + values: this.valuesFromProps(newProps) + }; } onChange(event, index, values) { diff --git a/app/scripts/views/rhythm_reading_view.js b/app/scripts/views/rhythm_reading_view.js index 536ba5b..1bf9b0b 100644 --- a/app/scripts/views/rhythm_reading_view.js +++ b/app/scripts/views/rhythm_reading_view.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import classNames from "classnames"; import BarGenerator from "../services/bar_generator.js"; @@ -24,9 +25,9 @@ const Phases = { export default class RhythmReadingView extends Component { static propTypes = { - settings: React.PropTypes.object.isRequired, - statisticService: React.PropTypes.object.isRequired, - isActive: React.PropTypes.bool.isRequired + settings: PropTypes.object.isRequired, + statisticService: PropTypes.object.isRequired, + isActive: PropTypes.bool.isRequired }; constructor(props, context) { @@ -42,7 +43,7 @@ export default class RhythmReadingView extends Component { } static childContextTypes = { - isInActiveView: React.PropTypes.bool + isInActiveView: PropTypes.bool }; getChildContext() { @@ -53,7 +54,7 @@ export default class RhythmReadingView extends Component { componentDidUpdate(prevProps, prevState) { if (this.state.phase === Phases.running && prevState.phase !== Phases.running) { - this.refs.metronome.playMetronome(); + this.metronome.playMetronome(); } else { console.log("not running"); } @@ -98,7 +99,7 @@ export default class RhythmReadingView extends Component { // we will add the up event to the beatHistory const lastBeat = this.beatHistory.slice(-1)[0]; if (lastBeat.length === 1) { - const firstBarBeatTime = this.refs.metronome.getFirstBarBeatTime(); + const firstBarBeatTime = this.metronome.getFirstBarBeatTime(); lastBeat.push(performance.now() - firstBarBeatTime); } } @@ -124,7 +125,7 @@ export default class RhythmReadingView extends Component { return; } // protocol beat - const firstBarBeatTime = this.refs.metronome.getFirstBarBeatTime(); + const firstBarBeatTime = this.metronome.getFirstBarBeatTime(); const newBeatTime = performance.now() - firstBarBeatTime; lastSpaceEvent = eventType; @@ -207,8 +208,8 @@ export default class RhythmReadingView extends Component {

Welcome to this rhythm training!

When you start the training, we will count in for 4 beats and afterwards you can tap the given rhythm (either - use your 'space' button or your touchscreen). Make sure your speakers are on so that you can hear the - metronome. + use your ‘space’ button or your touchscreen). Make sure your speakers are on so that you can hear + the metronome.

); @@ -253,7 +254,9 @@ export default class RhythmReadingView extends Component { const metronomeBeat = ( { + this.metronome = c; + }} onMetronomeEnded={this.onMetronomeEnded.bind(this)} /> ); diff --git a/app/scripts/views/rhythm_settings_view.js b/app/scripts/views/rhythm_settings_view.js index 6b8ee28..ed2f163 100644 --- a/app/scripts/views/rhythm_settings_view.js +++ b/app/scripts/views/rhythm_settings_view.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; import RangeSettingComponent from "./range_setting_component"; import SettingLine from "./setting_line"; import AnalyticsService from "../services/analytics_service.js"; @@ -6,7 +7,7 @@ import _ from "lodash"; export default class PitchSettingsView extends Component { static propTypes = { - settings: React.PropTypes.object + settings: PropTypes.object }; constructor(props, context) { diff --git a/app/scripts/views/rhythm_statistic_view.js b/app/scripts/views/rhythm_statistic_view.js index d7c6d04..23ce513 100644 --- a/app/scripts/views/rhythm_statistic_view.js +++ b/app/scripts/views/rhythm_statistic_view.js @@ -1,5 +1,6 @@ import Chartist from "Chartist"; import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Tooltip, OverlayTrigger } from "react-bootstrap"; import _ from "lodash"; @@ -8,7 +9,7 @@ import StarAnimation from "./star_animation.js"; export default class RhythmStatisticView extends Component { static propTypes = { - statisticService: React.PropTypes.object.isRequired + statisticService: PropTypes.object.isRequired }; constructor(props) { @@ -66,7 +67,12 @@ export default class RhythmStatisticView extends Component { return (
-
+
{ + this.chart = c; + }} + className="semi-transparent ct-chart ct-major-eleventh" + />
Your current score}> @@ -142,8 +148,8 @@ export default class RhythmStatisticView extends Component { } }; - if (scoreDevelopmentValues.length > 1) { - Chartist.Line(this.refs.chart, data, options); + if (this.chart && scoreDevelopmentValues.length > 1) { + Chartist.Line(this.chart, data, options); } } } diff --git a/app/scripts/views/setting_line.js b/app/scripts/views/setting_line.js index 16fc93c..f6545e6 100644 --- a/app/scripts/views/setting_line.js +++ b/app/scripts/views/setting_line.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; export default class SettingLine extends Component { static defaultProps = { diff --git a/app/scripts/views/star_animation.js b/app/scripts/views/star_animation.js index 2f678f4..8b49f5a 100644 --- a/app/scripts/views/star_animation.js +++ b/app/scripts/views/star_animation.js @@ -1,8 +1,9 @@ import React, { Component } from "react"; +import PropTypes from "prop-types"; export default class StarAnimation extends Component { static propTypes = { - number: React.PropTypes.number + number: PropTypes.number }; constructor() { diff --git a/app/scripts/views/stave_renderer.js b/app/scripts/views/stave_renderer.js index 187f3ff..0d81318 100644 --- a/app/scripts/views/stave_renderer.js +++ b/app/scripts/views/stave_renderer.js @@ -1,5 +1,6 @@ import Vex from "vexflow"; import React, { PureComponent } from "react"; +import PropTypes from "prop-types"; import _ from "lodash"; class StaveRenderer extends PureComponent { @@ -8,10 +9,10 @@ class StaveRenderer extends PureComponent { }; static propTypes = { - keys: React.PropTypes.objectOf(React.PropTypes.array), - chordIndex: React.PropTypes.number, - keySignature: React.PropTypes.string, - staveCount: React.PropTypes.number + keys: PropTypes.objectOf(PropTypes.array), + chordIndex: PropTypes.number, + keySignature: PropTypes.string, + staveCount: PropTypes.number }; constructor(props) { @@ -19,7 +20,14 @@ class StaveRenderer extends PureComponent { } render() { - return ; + return ( + { + this.canvas = c; + }} + id="canvas" + /> + ); } componentDidUpdate() { @@ -58,7 +66,7 @@ class StaveRenderer extends PureComponent { } draw() { - const canvas = this.refs.canvas; + const canvas = this.canvas; this.renderer = new Vex.Flow.Renderer(canvas, Vex.Flow.Renderer.Backends.CANVAS); this.ctx = this.renderer.getContext(); diff --git a/package.json b/package.json index 5115b8b..bd2ca33 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,11 @@ "freezer-js": "git+https://github.com/philippotto/freezer.git#native-object-handling-build", "html-loader": "^0.4.3", "lodash": "^4.5.1", + "prop-types": "^15.5.10", "react": "^15.6.1", "react-bootstrap": "^0.28.3", "react-dom": "^15.6.1", - "react-motion": "^0.4.2", + "react-motion": "^0.5.0", "react-range-slider-bem": "^0.2.11", "vexflow": "^1.2.41" }, @@ -40,7 +41,7 @@ "css-loader": "^0.23.1", "eslint": "^3.14.1", "eslint-plugin-prettier": "^2.1.2", - "eslint-plugin-react": "^4.1.0", + "eslint-plugin-react": "^7.1.0", "font-awesome-webpack": "0.0.4", "jasmine-core": "^2.4.1", "karma": "^0.13.21", From 4efb97a7efdb0d6c043f517bddf8bc3e535f1b65 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sun, 23 Jul 2017 00:23:37 -0400 Subject: [PATCH 3/9] autobuffer deprecated in favour of preload --- app/scripts/views/pitch_reading_view.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/scripts/views/pitch_reading_view.js b/app/scripts/views/pitch_reading_view.js index 29f9e75..5ba0db2 100644 --- a/app/scripts/views/pitch_reading_view.js +++ b/app/scripts/views/pitch_reading_view.js @@ -246,7 +246,6 @@ export default class PitchReadingView extends Component { src={successMp3Url} controls preload="auto" - autobuffer />
From b6f54844db1900aee709896ed7768b43e1b6ae28 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sun, 23 Jul 2017 00:24:10 -0400 Subject: [PATCH 4/9] Rename components to match file names --- app/scripts/views/collapsable_container.js | 2 +- app/scripts/views/pie_chart.js | 2 +- app/scripts/views/range_setting_component.js | 2 +- app/scripts/views/rhythm_settings_view.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/scripts/views/collapsable_container.js b/app/scripts/views/collapsable_container.js index ac4d9da..fc1e6ba 100644 --- a/app/scripts/views/collapsable_container.js +++ b/app/scripts/views/collapsable_container.js @@ -3,7 +3,7 @@ import PropTypes from "prop-types"; import classNames from "classnames"; import _ from "lodash"; -export default class BeatVisualization extends Component { +export default class CollapsableContainer extends Component { static propTypes = { children: PropTypes.node, collapsed: PropTypes.bool.isRequired, diff --git a/app/scripts/views/pie_chart.js b/app/scripts/views/pie_chart.js index 8c67f23..5650e82 100644 --- a/app/scripts/views/pie_chart.js +++ b/app/scripts/views/pie_chart.js @@ -2,7 +2,7 @@ import Chartist from "Chartist"; import PropTypes from "prop-types"; import React, { PureComponent } from "react"; -export default class LevelView extends PureComponent { +export default class PieChart extends PureComponent { static propTypes = { pieParts: PropTypes.array.isRequired }; diff --git a/app/scripts/views/range_setting_component.js b/app/scripts/views/range_setting_component.js index 627ce22..a8d6ab2 100644 --- a/app/scripts/views/range_setting_component.js +++ b/app/scripts/views/range_setting_component.js @@ -6,7 +6,7 @@ import _ from "lodash"; const multiplier = 10; -export default class SettingsView extends Component { +export default class RangeSettingComponent extends Component { static defaultProps = { valueToString: _.identity, label: "" diff --git a/app/scripts/views/rhythm_settings_view.js b/app/scripts/views/rhythm_settings_view.js index ed2f163..f6a3e0e 100644 --- a/app/scripts/views/rhythm_settings_view.js +++ b/app/scripts/views/rhythm_settings_view.js @@ -5,7 +5,7 @@ import SettingLine from "./setting_line"; import AnalyticsService from "../services/analytics_service.js"; import _ from "lodash"; -export default class PitchSettingsView extends Component { +export default class RythmSettingsView extends Component { static propTypes = { settings: PropTypes.object }; From e058c5a3db755b6367d5e83e4db525450fc0258d Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sun, 23 Jul 2017 00:24:26 -0400 Subject: [PATCH 5/9] Fix errors found at runtime due to updating React --- app/scripts/views/beat_visualization.js | 4 ++-- app/scripts/views/metronome_view.js | 3 +-- app/scripts/views/newsletter_form.js | 2 -- app/scripts/views/range_setting_component.js | 2 +- package.json | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/app/scripts/views/beat_visualization.js b/app/scripts/views/beat_visualization.js index bcb39c1..03bdfa3 100644 --- a/app/scripts/views/beat_visualization.js +++ b/app/scripts/views/beat_visualization.js @@ -10,8 +10,8 @@ export default class BeatVisualization extends Component { settings: PropTypes.object.isRequired, barDuration: PropTypes.number.isRequired, currentRhythm: PropTypes.object.isRequired, - beatHistory: PropTypes.object.isRequired, - result: PropTypes.object.isRequired + beatHistory: PropTypes.array.isRequired, + result: PropTypes.object }; convertTicksToBeatNames(tickTime, tickLength) { diff --git a/app/scripts/views/metronome_view.js b/app/scripts/views/metronome_view.js index 4a06ab6..aa1c818 100644 --- a/app/scripts/views/metronome_view.js +++ b/app/scripts/views/metronome_view.js @@ -9,8 +9,7 @@ import CollapsableContainer from "./collapsable_container.js"; export default class MetronomeView extends Component { static propTypes = { onMetronomeEnded: PropTypes.func, - settings: PropTypes.object.isRequired, - statisticService: PropTypes.object.isRequired + settings: PropTypes.object.isRequired }; constructor(props, context) { diff --git a/app/scripts/views/newsletter_form.js b/app/scripts/views/newsletter_form.js index cb976a2..002178d 100644 --- a/app/scripts/views/newsletter_form.js +++ b/app/scripts/views/newsletter_form.js @@ -36,8 +36,6 @@ export default class NewsLetterForm extends Component { this.email = c; }} className="form-control" - groupClassName="group-class" - labelClassName="label-class" />
diff --git a/app/scripts/views/range_setting_component.js b/app/scripts/views/range_setting_component.js index a8d6ab2..b4a5fbf 100644 --- a/app/scripts/views/range_setting_component.js +++ b/app/scripts/views/range_setting_component.js @@ -15,7 +15,7 @@ export default class RangeSettingComponent extends Component { static propTypes = { rangeMin: PropTypes.number.isRequired, rangeMax: PropTypes.number.isRequired, - values: PropTypes.array, + values: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), onChange: PropTypes.func.isRequired, label: PropTypes.string, valueToString: PropTypes.func, diff --git a/package.json b/package.json index bd2ca33..1f3cd3e 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "lodash": "^4.5.1", "prop-types": "^15.5.10", "react": "^15.6.1", - "react-bootstrap": "^0.28.3", + "react-bootstrap": "^0.31.1", "react-dom": "^15.6.1", "react-motion": "^0.5.0", "react-range-slider-bem": "^0.2.11", From a177ee7bd5c6a7f5970bc8d59cc3c2f14aa72219 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sat, 7 Oct 2017 15:59:04 -0400 Subject: [PATCH 6/9] Change nodejs runtime target for tests to LTS --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 762841e..d21c482 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 4.4.0 + - lts/* - stable install: - npm install From 0226757f81962e96599a51945d9c8cec5531463e Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Sat, 7 Oct 2017 16:03:18 -0400 Subject: [PATCH 7/9] Upgrade prettier and format code --- .../services/pitch_statistic_service.js | 24 ++++++++-- .../services/rhythm_statistic_service.js | 14 ++++-- app/scripts/views/animated_number.js | 5 +- app/scripts/views/beat_visualization.js | 22 ++++----- app/scripts/views/claviature_view.js | 4 +- app/scripts/views/game_button.js | 20 +++----- app/scripts/views/level_view.js | 4 +- app/scripts/views/metronome_view.js | 4 +- app/scripts/views/pitch_reading_view.js | 22 ++++----- app/scripts/views/pitch_settings_view.js | 40 ++++++++-------- app/scripts/views/rhythm_reading_view.js | 28 +++++------ app/scripts/views/rhythm_statistic_view.js | 8 ++-- app/scripts/views/setting_line.js | 4 +- app/scripts/views/stave_renderer.js | 10 +++- app/styles/chartist_modifications.less | 6 ++- app/styles/checkbox.css | 22 +++++---- app/styles/claviature.less | 29 ++++++------ app/styles/index.less | 46 ++++++++++--------- app/styles/star_animation.less | 16 +++++-- package.json | 4 +- webpack.config.js | 5 +- 21 files changed, 183 insertions(+), 154 deletions(-) diff --git a/app/scripts/services/pitch_statistic_service.js b/app/scripts/services/pitch_statistic_service.js index f9ac113..24dc694 100644 --- a/app/scripts/services/pitch_statistic_service.js +++ b/app/scripts/services/pitch_statistic_service.js @@ -28,7 +28,9 @@ class PitchStatisticService { this.stats = localStorage.getItem(localStoragePitchStatsKey); if (this.stats) { - this.stats = JSON.parse(this.stats).map(this.transformDate).map(StatEvolver.evolveToLatestSchema); + this.stats = JSON.parse(this.stats) + .map(this.transformDate) + .map(StatEvolver.evolveToLatestSchema); } else { this.stats = []; } @@ -45,7 +47,9 @@ class PitchStatisticService { } getSuccessCount() { - return _(this.stats).filter(el => el.success).value().length; + return _(this.stats) + .filter(el => el.success) + .value().length; } rateEvent(event) { @@ -67,7 +71,10 @@ class PitchStatisticService { } getLastTimes(n = 10) { - return this.stats.filter(el => el.success).map(el => el.time).slice(-n); + return this.stats + .filter(el => el.success) + .map(el => el.time) + .slice(-n); } computeAverage(array) { @@ -83,11 +90,18 @@ class PitchStatisticService { } getTotalAmountOfChords() { - return _(this.stats).filter(el => el.success).map(el => el.keys).size(); + return _(this.stats) + .filter(el => el.success) + .map(el => el.keys) + .size(); } getTotalAmountOfKeys() { - return _(this.stats).filter(el => el.success).map(el => el.keys).flatten().size(); + return _(this.stats) + .filter(el => el.success) + .map(el => el.keys) + .flatten() + .size(); } getSuccessRate() { diff --git a/app/scripts/services/rhythm_statistic_service.js b/app/scripts/services/rhythm_statistic_service.js index bdf829b..f798f63 100644 --- a/app/scripts/services/rhythm_statistic_service.js +++ b/app/scripts/services/rhythm_statistic_service.js @@ -64,7 +64,9 @@ class RhythmStatisticService { } getSuccessCount() { - return _(this.stats).filter(el => el.success).value().length; + return _(this.stats) + .filter(el => el.success) + .value().length; } getLastScores(n) { @@ -72,7 +74,10 @@ class RhythmStatisticService { } getLastTimes(n = 10) { - return this.stats.filter(el => el.success).map(el => el.time).slice(-n); + return this.stats + .filter(el => el.success) + .map(el => el.time) + .slice(-n); } computeAverage(array) { @@ -88,7 +93,10 @@ class RhythmStatisticService { } getTotalAmountOfBeats() { - return _(this.stats).map(el => el.durations).flatten().size(); + return _(this.stats) + .map(el => el.durations) + .flatten() + .size(); } getTotalRhythmTime() { diff --git a/app/scripts/views/animated_number.js b/app/scripts/views/animated_number.js index 03269b6..6c7cf22 100644 --- a/app/scripts/views/animated_number.js +++ b/app/scripts/views/animated_number.js @@ -12,10 +12,7 @@ export default class AnimatedNumber extends Component { const number = this.props.number; return ( - {value => - - {formatter ? formatter(value.x) : Math.round(value.x)} - } + {value => {formatter ? formatter(value.x) : Math.round(value.x)}} ); } diff --git a/app/scripts/views/beat_visualization.js b/app/scripts/views/beat_visualization.js index 03bdfa3..252181b 100644 --- a/app/scripts/views/beat_visualization.js +++ b/app/scripts/views/beat_visualization.js @@ -27,11 +27,11 @@ export default class BeatVisualization extends Component { const ticks = necessaryBeatNames.slice(tickIndex, tickIndex + tickStepCount); return (
- {ticks.map((beatName, index) => + {ticks.map((beatName, index) => (
{beatName}
- )} + ))}
); } @@ -53,11 +53,11 @@ export default class BeatVisualization extends Component { currentX = x + width; return [ - marginLeft > 0 - ?
- {beatNamesRest} -
- : null, + marginLeft > 0 ? ( +
+ {beatNamesRest} +
+ ) : null,
{beatNames}
@@ -99,12 +99,8 @@ export default class BeatVisualization extends Component { // uniqueId avoids that different beat bars are animated into each other return (
-
- {expectedBeats} -
-
- {actualBeats} -
+
{expectedBeats}
+
{actualBeats}
); } diff --git a/app/scripts/views/claviature_view.js b/app/scripts/views/claviature_view.js index 16eb8c7..db928c6 100644 --- a/app/scripts/views/claviature_view.js +++ b/app/scripts/views/claviature_view.js @@ -111,9 +111,7 @@ export default class ClaviatureView extends Component { ].map(args => this.renderKey.apply(this, args)); return (
-
    - {keys} -
+
    {keys}
); } diff --git a/app/scripts/views/game_button.js b/app/scripts/views/game_button.js index bf69246..6bd5b67 100644 --- a/app/scripts/views/game_button.js +++ b/app/scripts/views/game_button.js @@ -39,22 +39,16 @@ export default class GameButton extends Component { } render() { - const subtext = this.props.shortcutLetter - ?
- - Or press ‘{this.props.shortcutLetter}’ - -
- : null; + const subtext = this.props.shortcutLetter ? ( +
+ Or press ‘{this.props.shortcutLetter}’ +
+ ) : null; return ( ); } diff --git a/app/scripts/views/level_view.js b/app/scripts/views/level_view.js index 7dd7555..81d4773 100644 --- a/app/scripts/views/level_view.js +++ b/app/scripts/views/level_view.js @@ -65,9 +65,7 @@ export default class LevelView extends Component { return (
{content} -
- Current level: {levelIndex + 2} -
+
Current level: {levelIndex + 2}
); } diff --git a/app/scripts/views/metronome_view.js b/app/scripts/views/metronome_view.js index aa1c818..cd242d0 100644 --- a/app/scripts/views/metronome_view.js +++ b/app/scripts/views/metronome_view.js @@ -65,9 +65,7 @@ export default class MetronomeView extends Component { opacityOut: (this.state.currentMetronomeBeat + 1) % 4 === 0 })} > -

- {this.state.currentMetronomeBeat + 1} -

+

{this.state.currentMetronomeBeat + 1}

); } diff --git a/app/scripts/views/pitch_reading_view.js b/app/scripts/views/pitch_reading_view.js index 5ba0db2..0cee583 100644 --- a/app/scripts/views/pitch_reading_view.js +++ b/app/scripts/views/pitch_reading_view.js @@ -141,15 +141,15 @@ export default class PitchReadingView extends Component { const isMidiAvailable = this.props.settings.midi.inputs.get().length > 0; const noErrors = this.state.errorMessage !== null; const miniClaviature = - isMidiAvailable && noErrors - ? null - : ; + isMidiAvailable && noErrors ? null : ( + + ); const startStopButton = ( -

- {this.state.errorMessage} -

+

{this.state.errorMessage}

diff --git a/app/scripts/views/pitch_settings_view.js b/app/scripts/views/pitch_settings_view.js index f8e809b..1161346 100644 --- a/app/scripts/views/pitch_settings_view.js +++ b/app/scripts/views/pitch_settings_view.js @@ -50,26 +50,26 @@ export default class PitchSettingsView extends Component { const midiSettings = this.props.settings.midi; const midiInputs = midiSettings.inputs.get(); const isMidiAvailable = midiInputs.length > 0; - const deviceSelector = !isMidiAvailable - ? null - : - - ; + const deviceSelector = !isMidiAvailable ? null : ( + + + + ); const useAutomaticDifficulty = this.props.settings.useAutomaticDifficulty; diff --git a/app/scripts/views/rhythm_reading_view.js b/app/scripts/views/rhythm_reading_view.js index 1bf9b0b..d3d8a0a 100644 --- a/app/scripts/views/rhythm_reading_view.js +++ b/app/scripts/views/rhythm_reading_view.js @@ -262,17 +262,19 @@ export default class RhythmReadingView extends Component { ); const buttons = - this.state.phase !== Phases.feedback - ? - : this.state.result.success - ?
- - -
- :
- - -
; + this.state.phase !== Phases.feedback ? ( + + ) : this.state.result.success ? ( +
+ + +
+ ) : ( +
+ + +
+ ); return (
@@ -296,9 +298,7 @@ export default class RhythmReadingView extends Component {
-
- {buttons} -
+
{buttons}
diff --git a/app/scripts/views/rhythm_statistic_view.js b/app/scripts/views/rhythm_statistic_view.js index 23ce513..1525224 100644 --- a/app/scripts/views/rhythm_statistic_view.js +++ b/app/scripts/views/rhythm_statistic_view.js @@ -24,19 +24,19 @@ export default class RhythmStatisticView extends Component { unit: "y" }, { - amount: Math.floor(seconds % 31536000 / 86400), + amount: Math.floor((seconds % 31536000) / 86400), unit: "d" }, { - amount: Math.floor(seconds % 31536000 % 86400 / 3600), + amount: Math.floor(((seconds % 31536000) % 86400) / 3600), unit: "h" }, { - amount: Math.floor(seconds % 31536000 % 86400 % 3600 / 60), + amount: Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), unit: "m" }, { - amount: seconds % 31536000 % 86400 % 3600 % 60, + amount: (((seconds % 31536000) % 86400) % 3600) % 60, unit: "s" } ] diff --git a/app/scripts/views/setting_line.js b/app/scripts/views/setting_line.js index f6545e6..52013af 100644 --- a/app/scripts/views/setting_line.js +++ b/app/scripts/views/setting_line.js @@ -26,9 +26,7 @@ export default class SettingLine extends Component {
{this.props.label}
-
- {this.props.children} -
+
{this.props.children}
); } diff --git a/app/scripts/views/stave_renderer.js b/app/scripts/views/stave_renderer.js index 0d81318..027817b 100644 --- a/app/scripts/views/stave_renderer.js +++ b/app/scripts/views/stave_renderer.js @@ -85,10 +85,16 @@ class StaveRenderer extends PureComponent { this.setCanvasExtent(canvas, width, height, ratio); const rightHandStave = new Vex.Flow.Stave(10, 0, staveWidth); - rightHandStave.addClef("treble").setKeySignature(this.props.keySignature).setContext(ctx); + rightHandStave + .addClef("treble") + .setKeySignature(this.props.keySignature) + .setContext(ctx); const leftHandStave = new Vex.Flow.Stave(10, 80, staveWidth); - leftHandStave.addClef("bass").setKeySignature(this.props.keySignature).setContext(ctx); + leftHandStave + .addClef("bass") + .setKeySignature(this.props.keySignature) + .setContext(ctx); this.colorizeKeys(); diff --git a/app/styles/chartist_modifications.less b/app/styles/chartist_modifications.less index c35d793..51663e9 100644 --- a/app/styles/chartist_modifications.less +++ b/app/styles/chartist_modifications.less @@ -1,6 +1,9 @@ /* override chartist color */ -.ct-chart .ct-series.ct-series-a .ct-bar, .ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point, .ct-chart .ct-series.ct-series-a .ct-slice.ct-donut { +.ct-chart .ct-series.ct-series-a .ct-bar, +.ct-chart .ct-series.ct-series-a .ct-line, +.ct-chart .ct-series.ct-series-a .ct-point, +.ct-chart .ct-series.ct-series-a .ct-slice.ct-donut { stroke: #333 !important; } @@ -21,7 +24,6 @@ stroke-width: 6px; } - .graph-stats .ct-slice-donut { stroke: #449d44; } diff --git a/app/styles/checkbox.css b/app/styles/checkbox.css index 8414f78..6a85b53 100644 --- a/app/styles/checkbox.css +++ b/app/styles/checkbox.css @@ -1,4 +1,4 @@ -input[type=checkbox] { +input[type="checkbox"] { visibility: hidden; } @@ -11,23 +11,30 @@ input[type=checkbox] { top: 0; border-radius: 4px; - -webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,.4); - -moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,.4); - box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,.4); + -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.5), + 0px 1px 0px rgba(255, 255, 255, 0.4); + -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.5), + 0px 1px 0px rgba(255, 255, 255, 0.4); + box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.5), + 0px 1px 0px rgba(255, 255, 255, 0.4); background: -webkit-linear-gradient(top, #222 0%, #45484d 100%); background: -moz-linear-gradient(top, #222 0%, #45484d 100%); background: -o-linear-gradient(top, #222 0%, #45484d 100%); background: -ms-linear-gradient(top, #222 0%, #45484d 100%); background: linear-gradient(top, #222 0%, #45484d 100%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#222', endColorstr='#45484d',GradientType=0 ); + filter: progid:DXImageTransform.Microsoft.gradient( + startColorstr="#222", + endColorstr="#45484d", + GradientType=0 + ); } .setting_checkbox label:after { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); opacity: 0; - content: ''; + content: ""; position: absolute; width: 8px; height: 5px; @@ -51,9 +58,8 @@ input[type=checkbox] { opacity: 0.3; } -.setting_checkbox input[type=checkbox]:checked + label:after { +.setting_checkbox input[type="checkbox"]:checked + label:after { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter: alpha(opacity=100); opacity: 1; } - diff --git a/app/styles/claviature.less b/app/styles/claviature.less index 06064fb..a6f63b1 100644 --- a/app/styles/claviature.less +++ b/app/styles/claviature.less @@ -8,22 +8,22 @@ top: 0px; z-index: 1; font-size: 1.5rem; - background: linear-gradient(to bottom, #F3F3F3, #f0f0f0 10%, #FBFAFA); + background: linear-gradient(to bottom, #f3f3f3, #f0f0f0 10%, #fbfafa); transition: all 0.1s ease-in-out; margin: 0; display: inline-block; border: 1px solid #ccc; padding: 160px 15px 50px; border-radius: 0 0 5px 5px; - box-shadow: 0 3px 3px rgba(170, 170, 170, 0.50); + box-shadow: 0 3px 3px rgba(170, 170, 170, 0.5); position: relative; cursor: pointer; color: rgba(255, 255, 255, 0); &:hover { - color: #171C1A; + color: #171c1a; } - &:active{ + &:active { box-shadow: 0 0 0 rgb(0, 0, 0, 0); top: 3px; color: #333; @@ -44,7 +44,7 @@ border-width: 0 6px 12px; border-color: #000; border-bottom-color: #424546; - background: #171C1A; + background: #171c1a; &:hover { color: #faf0e6; } @@ -55,21 +55,22 @@ } } - li:active, li.active { + li:active, + li.active { // by default all keys are wrong which is shown when clicked - background: linear-gradient(to bottom, #B50C0C, #D81313 10%, #D20909); + background: linear-gradient(to bottom, #b50c0c, #d81313 10%, #d20909); &.black-note { - border-color: #790C0C; - border-bottom-color: #5A0202; + border-color: #790c0c; + border-bottom-color: #5a0202; } } - li.green:active, li.green.active { + li.green:active, + li.green.active { color: white; - background: linear-gradient(to bottom, #158C0D, #2DAD3D 10%, #09A915); + background: linear-gradient(to bottom, #158c0d, #2dad3d 10%, #09a915); &.black-note { - border-color: #18790C; - border-bottom-color: #025A1D; + border-color: #18790c; + border-bottom-color: #025a1d; } } - } diff --git a/app/styles/index.less b/app/styles/index.less index ea9642e..20725da 100644 --- a/app/styles/index.less +++ b/app/styles/index.less @@ -44,7 +44,7 @@ footer { } } h2 { - color: #ECECEC; + color: #ececec; } div.left { text-align: left; @@ -55,19 +55,23 @@ footer { } .form-control:focus { - border-color: #E0E0E0; + border-color: #e0e0e0; outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(224, 224, 224, 0.6); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(224, 224, 224, 0.6); } - .btn, .btn:focus { + .btn, + .btn:focus { transition: all 0.5s ease; background-color: transparent; border: 1px solid white; color: white; outline: none; - &:hover, &:active { + &:hover, + &:active { background-color: rgba(255, 255, 255, 0.15); border-color: white; } @@ -93,7 +97,6 @@ footer { } } - .jumbotron { background-color: rgba(0, 0, 0, 0.7); padding-top: 24px; @@ -105,7 +108,7 @@ footer { .jumbotron > h1 { /*Kozuka Gothic ...*/ text-align: center; - font-family: 'Poiret One', sans-serif; + font-family: "Poiret One", sans-serif; font-size: 70pt; font-weight: 100; color: white; @@ -116,11 +119,10 @@ footer { text-align: center; color: white; margin-top: 10px; - font-family: 'Poiret One', sans-serif; + font-family: "Poiret One", sans-serif; margin-bottom: 20px; } - #image-background { min-height: 100%; min-width: 1600px; @@ -138,7 +140,6 @@ footer { right: 10px; } - h1 { font-size: 50*2px; } @@ -209,7 +210,8 @@ h1 { transition: all 0.5s ease; } -li.modeNavItem a, li.modeNavItem a:focus { +li.modeNavItem a, +li.modeNavItem a:focus { background-color: transparent; border: 1px solid white; color: white; @@ -218,7 +220,8 @@ li.modeNavItem a, li.modeNavItem a:focus { } } -li.modeNavItem.active a:focus, li.modeNavItem.active a { +li.modeNavItem.active a:focus, +li.modeNavItem.active a { background-color: white; border: 1px solid white; color: black; @@ -229,10 +232,7 @@ li.modeNavItem.active a:focus, li.modeNavItem.active a { } .transition { - transition: - max-height 0.4s ease, - height 0.4s ease, - margin 0.4s ease, + transition: max-height 0.4s ease, height 0.4s ease, margin 0.4s ease, opacity 0.75s ease; opacity: 1; overflow: hidden; @@ -280,7 +280,14 @@ li.modeNavItem.active a:focus, li.modeNavItem.active a { margin: 25px 0; height: 1px; background: black; - background: -webkit-gradient(linear, 0 0, 100% 0, from(rgba(255, 255, 255, 0.0)), to(rgba(255, 255, 255, 0.0)), color-stop(50%, white)); + background: -webkit-gradient( + linear, + 0 0, + 100% 0, + from(rgba(255, 255, 255, 0)), + to(rgba(255, 255, 255, 0)), + color-stop(50%, white) + ); } .inlineBlock { @@ -293,7 +300,6 @@ li.modeNavItem.active a:focus, li.modeNavItem.active a { margin-left: 0.5%; } - .noSelect { -webkit-touch-callout: none; -webkit-user-select: none; @@ -311,8 +317,6 @@ li.modeNavItem.active a:focus, li.modeNavItem.active a { display: none; } - - .gameContainer { white-space: nowrap; overflow: hidden; diff --git a/app/styles/star_animation.less b/app/styles/star_animation.less index 998fa49..d15ff90 100644 --- a/app/styles/star_animation.less +++ b/app/styles/star_animation.less @@ -17,11 +17,19 @@ } @keyframes rotation-1 { - from {transform: rotate(0deg); } - to {transform: rotate(360deg); } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } @keyframes rotation-2 { - from {transform: rotate(0deg); } - to {transform: rotate(360deg); } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } diff --git a/package.json b/package.json index 1f3cd3e..d26d2d5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "babel-preset-stage-0": "^6.3.13", "css-loader": "^0.23.1", "eslint": "^3.14.1", - "eslint-plugin-prettier": "^2.1.2", + "eslint-plugin-prettier": "^2.3.1", "eslint-plugin-react": "^7.1.0", "font-awesome-webpack": "0.0.4", "jasmine-core": "^2.4.1", @@ -55,7 +55,7 @@ "less": "^2.6.0", "less-loader": "^2.2.2", "phantomjs-prebuilt": "^2.1.6", - "prettier": "^1.5.0", + "prettier": "^1.7.4", "react-transform-hmr": "^1.0.1", "style-loader": "^0.13.0", "url-loader": "^0.5.7", diff --git a/webpack.config.js b/webpack.config.js index 980f345..9c0fe0d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -76,7 +76,10 @@ module.exports = { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff" }, - { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }, + { + test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, + loader: "file-loader" + }, { test: /\.html/, loader: "file?name=[name].[ext]" } ] } From 4c7e6726eb8e4bd462b4ec3cc9520091c67051e9 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Fri, 13 Oct 2017 19:12:16 -0400 Subject: [PATCH 8/9] Change slider component libraries The old library wasn't being maintained and we need something up-to-date to be able to upgrade React. --- app/scripts/views/pitch_settings_view.js | 19 ++++-- app/scripts/views/range_setting_component.js | 66 +++++++++----------- app/styles/index.less | 3 +- app/styles/slider.css | 36 ----------- app/styles/slider.less | 30 +++++++++ package.json | 2 +- 6 files changed, 76 insertions(+), 80 deletions(-) delete mode 100644 app/styles/slider.css create mode 100644 app/styles/slider.less diff --git a/app/scripts/views/pitch_settings_view.js b/app/scripts/views/pitch_settings_view.js index 1161346..1cb103e 100644 --- a/app/scripts/views/pitch_settings_view.js +++ b/app/scripts/views/pitch_settings_view.js @@ -89,7 +89,7 @@ export default class PitchSettingsView extends Component { accuracyStateChanger(value / 100)} valueToString={el => `${el}%`} label={"Accuracy goal"} @@ -97,7 +97,7 @@ export default class PitchSettingsView extends Component { newNotesShareStateChanger(value / 100)} valueToString={el => `${el}%`} label={"Share of new notes"} @@ -110,7 +110,10 @@ export default class PitchSettingsView extends Component { el * multiplier); + /** + * Converts values recieved as props to expected form for state + * + * @param {number | {from: number, to: number}} values + * @returns {number[]} + */ + convertValues(values) { + return typeof values === "object" ? [values.from, values.to] : [values]; } componentWillReceiveProps(newProps) { - this.setState = { - values: this.valuesFromProps(newProps) - }; - } - - onChange(event, index, values) { this.setState({ - values: values.map(el => el.value) + values: this.convertValues(newProps.values) }); } - onAfterChange() { - if (this.props.disabled) { - return; - } - let newValues = this.state.values.map(this.quantitizeValue).map(el => el / multiplier); - this.props.onChange(newValues.length === 1 ? newValues[0] : newValues); + onChange(values) { + this.setState({ + values: values + }); } - quantitizeValue(value) { - return Math.round(value / multiplier) * multiplier; + onAfterChange(values) { + this.props.onChange(values.length === 1 ? values[0] : values); } render() { - const upscaledRangeMin = this.props.rangeMin * multiplier; - const upscaledRangeMax = this.props.rangeMax * multiplier; - - let renderedRangeValues = this.state.values; - let quantitizedValues = this.state.values.map(this.quantitizeValue); - - const downScaledValues = quantitizedValues.map(el => Math.round(el / multiplier)); const rangeContainerStyle = { marginBottom: -2 }; - const valueLabel = this.props.label + ": " + downScaledValues.map(this.props.valueToString).join(" - "); + const valueLabel = this.props.label + ": " + this.state.values.map(this.props.valueToString).join(" - "); return (
-
diff --git a/app/styles/index.less b/app/styles/index.less index 20725da..762a58c 100644 --- a/app/styles/index.less +++ b/app/styles/index.less @@ -1,14 +1,13 @@ // @import "../../node_modules/bootstrap/less/bootstrap.less"; @import (less) "../../node_modules/chartist/dist/chartist.min.css"; @import (less) "../../node_modules/flexboxgrid/dist/flexboxgrid.min.css"; -@import (less) "./slider.css"; +@import (less) "./slider.less"; @import (less) "./checkbox.css"; @import (less) "./chartist_modifications.less"; @import (less) "./beat_visualization.less"; @import (less) "./claviature.less"; @import (less) "./star_animation.less"; - @import url(http://fonts.googleapis.com/css?family=Poiret+One); @import url(http://fonts.googleapis.com/css?family=Droid+Sans:400); diff --git a/app/styles/slider.css b/app/styles/slider.css deleted file mode 100644 index 63b89ff..0000000 --- a/app/styles/slider.css +++ /dev/null @@ -1,36 +0,0 @@ -.range-slider { - -webkit-appearance: none; - width: 100%; - margin: 5px 0; -} -.range-slider:focus { - outline: none; -} -.range-slider__bars { - width: 100%; - height: 5px; - cursor: pointer; - box-shadow: 1px 1px 0.9px rgba(0, 0, 0, 0.76), 0px 0px 1px rgba(13, 13, 13, 0.76); - background: rgba(0, 0, 0, 0.68); - border-radius: 25px; - border: 0px solid #010101; -} -.range-slider__cursor { - box-shadow: 0px 0px 1px #670000, 0px 0px 0px #810000; - border: 0px solid #000000; - height: 10px; - width: 10px; - border-radius: 15px; - background: rgba(255, 255, 255, 0.99); - cursor: pointer; - -webkit-appearance: none; - margin-top: -7px; - - - span { - visibility: hidden; - } -} -.range-slider__bars:focus { - background: rgba(0, 0, 0, 0.68); -} diff --git a/app/styles/slider.less b/app/styles/slider.less new file mode 100644 index 0000000..dfd71f9 --- /dev/null +++ b/app/styles/slider.less @@ -0,0 +1,30 @@ +@import (less) "../../node_modules/rc-slider/assets/index.css"; + +.rc-slider:not(.rc-slider-disabled) { + .rc-slider-rail { + background: rgba(0, 0, 0, 0.68); + box-shadow: 1px 1px 0.9px rgba(0, 0, 0, 0.3), 0 0 1px hsla(0, 0%, 5%, 0.3); + } + + .rc-slider-handle { + box-shadow: 0 0 4px #670000; + border: 1px solid black; + } + + .rc-slider-handle:hover, + .rc-slider-handle:active { + border-color: #670000; + box-shadow: 0 0 8px #670000; + } + + .rc-slider-handle:focus { + border-color: #670000; + box-shadow: 0 0 1px 4px #fa9494; + } + .rc-slider-track { + background: #000; + } +} +.rc-slider-disabled { + background: none; +} diff --git a/package.json b/package.json index d26d2d5..8c7a1ef 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "html-loader": "^0.4.3", "lodash": "^4.5.1", "prop-types": "^15.5.10", + "rc-slider": "^8.3.1", "react": "^15.6.1", "react-bootstrap": "^0.31.1", "react-dom": "^15.6.1", "react-motion": "^0.5.0", - "react-range-slider-bem": "^0.2.11", "vexflow": "^1.2.41" }, "devDependencies": { From c99eb7fb16b844605092290558020d371c294c29 Mon Sep 17 00:00:00 2001 From: Graham McGregor Date: Fri, 13 Oct 2017 19:21:58 -0400 Subject: [PATCH 9/9] Upgrade to React 16 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8c7a1ef..ca68ed1 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "lodash": "^4.5.1", "prop-types": "^15.5.10", "rc-slider": "^8.3.1", - "react": "^15.6.1", + "react": "^16.0.0", "react-bootstrap": "^0.31.1", - "react-dom": "^15.6.1", + "react-dom": "^16.0.0", "react-motion": "^0.5.0", "vexflow": "^1.2.41" }, @@ -41,7 +41,7 @@ "css-loader": "^0.23.1", "eslint": "^3.14.1", "eslint-plugin-prettier": "^2.3.1", - "eslint-plugin-react": "^7.1.0", + "eslint-plugin-react": "^7.4.0", "font-awesome-webpack": "0.0.4", "jasmine-core": "^2.4.1", "karma": "^0.13.21",