diff --git a/app/scripts/AppFreezer.js b/app/scripts/AppFreezer.js
index e4b7e70..2248f64 100644
--- a/app/scripts/AppFreezer.js
+++ b/app/scripts/AppFreezer.js
@@ -15,6 +15,7 @@ let defaultSettings = {
},
keySignature: [7, 7],
useAccidentals: false,
+ tryToUseMidi: true,
midi: {
inputs: Freezer.createLeaf([]),
activeInputIndex: 0,
diff --git a/app/scripts/services/bar_generator.js b/app/scripts/services/bar_generator.js
index 37b2ab6..b23f05e 100644
--- a/app/scripts/services/bar_generator.js
+++ b/app/scripts/services/bar_generator.js
@@ -148,10 +148,7 @@ export default {
return ["treble", "bass"].map(clef => _.random.apply(_, settings.chordSizeRanges[clef]));
},
- generateBars: function(settings, level) {
- const isMidiAvailable = settings.midi.inputs.get().length > 0;
- const onePerTime = !isMidiAvailable;
-
+ generateBars: function(settings, level, onePerTime) {
const [trebleNotes, bassNotes] = _.unzip(
_.range(0, options.chordsPerBar).map(() => {
const generatePossibleNotes = clef => {
diff --git a/app/scripts/views/claviature_view.js b/app/scripts/views/claviature_view.js
index 40668b1..c56b1d7 100644
--- a/app/scripts/views/claviature_view.js
+++ b/app/scripts/views/claviature_view.js
@@ -114,9 +114,15 @@ export default class ClaviatureView extends Component {
["a#", "A# B♭", "black"],
["b", "B", "white"],
].map(args => this.renderKey.apply(this, args));
+
return (
-
-
{keys}
+
+
+ Click on the keys of the claviature or use your keyboard to hit notes!
);
}
diff --git a/app/scripts/views/collapsable_container.js b/app/scripts/views/collapsable_container.js
index e215942..b1b3613 100644
--- a/app/scripts/views/collapsable_container.js
+++ b/app/scripts/views/collapsable_container.js
@@ -28,7 +28,7 @@ export default class CollapsableContainer extends Component {
}),
]).join(" ");
- const maxHeight = this.props.maxHeight || 300;
+ const maxHeight = this.props.maxHeight || 500;
const style = collapsed ? {} : { maxHeight };
const children =
collapsed && this.props.freeze && this.oldChildren ? this.oldChildren : this.props.children;
diff --git a/app/scripts/views/pitch_reading_view.js b/app/scripts/views/pitch_reading_view.js
index 22156bb..39d76cf 100644
--- a/app/scripts/views/pitch_reading_view.js
+++ b/app/scripts/views/pitch_reading_view.js
@@ -37,8 +37,8 @@ export default class PitchReadingView extends Component {
this.midiService = new MidiService({
successCallback: this.onSuccess.bind(this),
failureCallback: this.onFailure.bind(this),
- errorCallback: this.onError.bind(this),
- errorResolveCallback: this.onErrorResolve.bind(this),
+ errorCallback: this.onMidiError.bind(this),
+ errorResolveCallback: this.onMidiErrorResolve.bind(this),
});
this.startDate = new Date();
this.midiService.setDesiredKeys(this.getAllCurrentKeys(), this.state.currentKeySignature);
@@ -106,7 +106,15 @@ export default class PitchReadingView extends Component {
generateNewBars(settings) {
const levelIndex = LevelService.getLevelOfUser(this.props.statisticService.getAllEvents()) + 1;
const level = LevelService.getLevelByIndex(levelIndex);
- return BarGenerator.generateBars(settings, settings.useAutomaticDifficulty ? level : null);
+
+ const { isMidiAvailable } = this.getMidiInfo();
+ const onePerTime = !isMidiAvailable;
+
+ return BarGenerator.generateBars(
+ settings,
+ settings.useAutomaticDifficulty ? level : null,
+ onePerTime,
+ );
}
generateNewBarState() {
@@ -120,7 +128,7 @@ export default class PitchReadingView extends Component {
constructor(props, context) {
super(props, context);
this.state = {
- errorMessage: null,
+ midiErrorMessage: null,
running: false,
...this.generateNewBarState(),
};
@@ -132,16 +140,30 @@ export default class PitchReadingView extends Component {
this.startDate = new Date();
}
+ getMidiInfo() {
+ const tryToUseMidi = this.props.settings.tryToUseMidi;
+ const isMidiAvailable = this.props.settings.midi.inputs.get().length > 0;
+ const useMidi = tryToUseMidi && isMidiAvailable;
+ const noMidiErrors = !this.state ? true : this.state.midiErrorMessage == null;
+
+ return {
+ tryToUseMidi,
+ isMidiAvailable,
+ useMidi,
+ noMidiErrors,
+ };
+ }
+
render() {
const claviatureContainerClasses = classNames({
"content-box": true,
"claviature-container": true,
});
- const isMidiAvailable = this.props.settings.midi.inputs.get().length > 0;
- const noErrors = this.state.errorMessage !== null;
+ const { tryToUseMidi, isMidiAvailable, useMidi, noMidiErrors } = this.getMidiInfo();
+
const miniClaviature =
- isMidiAvailable && noErrors ? null : (
+ useMidi && noMidiErrors ? null : (
- Welcome to this pitch training!
+ Welcome to pitch training!
{"When you hit Start, notes will be displayed in the stave above. "}
- {isMidiAvailable
+ {useMidi
? "Since we found a connected piano, you can use it to play the notes. "
: "Just use the mini claviature below to play the notes. "}
{"Don't worry about the rhythm or speed for now."}
- {isMidiAvailable ? null : midiSetUpText}
+ {tryToUseMidi && !isMidiAvailable ? midiSetUpText : null}
);
@@ -194,6 +216,8 @@ export default class PitchReadingView extends Component {
bass: [],
};
+ const hideMidiError = !tryToUseMidi || noMidiErrors;
+
return (
@@ -217,16 +241,16 @@ export default class PitchReadingView extends Component {
-
+
{miniClaviature}
-
{this.state.errorMessage}
+ {this.state.midiErrorMessage}
@@ -257,13 +281,13 @@ export default class PitchReadingView extends Component {
this.midiService.setDesiredKeys(this.getAllCurrentKeys(), this.state.currentKeySignature);
}
- onError(msg) {
+ onMidiError(msg) {
console.error.apply(console, arguments);
- this.setState({ errorMessage: msg });
+ this.setState({ midiErrorMessage: msg });
}
- onErrorResolve() {
- this.setState({ errorMessage: null });
+ onMidiErrorResolve() {
+ this.setState({ midiErrorMessage: null });
}
getAllCurrentKeys() {
diff --git a/app/scripts/views/pitch_settings_view.js b/app/scripts/views/pitch_settings_view.js
index 4d968ff..f0f2a8b 100644
--- a/app/scripts/views/pitch_settings_view.js
+++ b/app/scripts/views/pitch_settings_view.js
@@ -57,25 +57,39 @@ export default class PitchSettingsView extends Component {
const midiSettings = this.props.settings.midi;
const midiInputs = midiSettings.inputs.get();
const isMidiAvailable = midiInputs.length > 0;
+ const tryToUseMidi = this.props.settings.tryToUseMidi;
const deviceSelector = !isMidiAvailable ? null : (
-
- {
- this.midiSelect = c;
- }}
- >
- {midiInputs.map((el, index) => {
- return (
-
- Device {index + 1}
-
- );
- })}
-
-
+
+
+
+
+
+
+ {
+ this.midiSelect = c;
+ }}
+ disabled={!tryToUseMidi}
+ >
+ {midiInputs.map((el, index) => {
+ return (
+
+ Device {index + 1}
+
+ );
+ })}
+
+
+
);
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 699fea7..20fd63a 100644
--- a/app/scripts/views/rhythm_reading_view.js
+++ b/app/scripts/views/rhythm_reading_view.js
@@ -214,7 +214,7 @@ export default class RhythmReadingView extends Component {
render() {
const welcomeText = (
- Welcome to this rhythm training!
+ Welcome to 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