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
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/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 294ebc8..6c7cf22 100644
--- a/app/scripts/views/animated_number.js
+++ b/app/scripts/views/animated_number.js
@@ -1,20 +1,18 @@
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;
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 ce31ea2..252181b 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.array.isRequired,
+ result: PropTypes.object
};
convertTicksToBeatNames(tickTime, tickLength) {
@@ -26,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}
- )}
+ ))}
);
}
@@ -52,11 +53,11 @@ export default class BeatVisualization extends Component {
currentX = x + width;
return [
- marginLeft > 0
- ?
- {beatNamesRest}
-
- : null,
+ marginLeft > 0 ? (
+
+ {beatNamesRest}
+
+ ) : null,
{beatNames}
@@ -98,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 f101a46..db928c6 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) {
@@ -110,9 +111,7 @@ export default class ClaviatureView extends Component {
].map(args => this.renderKey.apply(this, args));
return (
);
}
diff --git a/app/scripts/views/collapsable_container.js b/app/scripts/views/collapsable_container.js
index 5b022e1..fc1e6ba 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 {
+export default class CollapsableContainer 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..6bd5b67 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() {
@@ -38,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 (
-
- {this.props.label}
-
-
- {subtext}
-
+ {this.props.label}
+ {subtext}
);
}
diff --git a/app/scripts/views/level_view.js b/app/scripts/views/level_view.js
index b13eed3..81d4773 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() {
@@ -64,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 3adbf8b..cd242d0 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,8 @@ 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
};
constructor(props, context) {
@@ -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/newsletter_form.js b/app/scripts/views/newsletter_form.js
index b741216..002178d 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,10 +32,10 @@ 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 5f24d3e..5650e82 100644
--- a/app/scripts/views/pie_chart.js
+++ b/app/scripts/views/pie_chart.js
@@ -1,24 +1,30 @@
import Chartist from "Chartist";
-import React, { Component } from "react";
-import PureRenderMixin from "react-addons-pure-render-mixin";
+import PropTypes from "prop-types";
+import React, { PureComponent } from "react";
-export default class LevelView extends Component {
+export default class PieChart extends PureComponent {
static propTypes = {
- pieParts: React.PropTypes.array.isRequired
+ pieParts: PropTypes.array.isRequired
};
constructor(props, context) {
super(props, context);
- this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
}
render() {
- 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..0cee583 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() {
@@ -140,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}
@@ -237,7 +236,15 @@ export default class PitchReadingView extends Component {