diff --git a/app/scripts/App.js b/app/scripts/App.js index 0cf2415..b5fc3df 100644 --- a/app/scripts/App.js +++ b/app/scripts/App.js @@ -20,13 +20,13 @@ export default class App extends Component { super(props, context); this.state = { activeGame: "pitch", - showPrivacyPolicy: false + showPrivacyPolicy: false, }; } selectGame(newGame) { this.setState({ - activeGame: newGame + activeGame: newGame, }); AnalyticsService.sendEvent("GameSelection", newGame); @@ -87,7 +87,10 @@ export default class App extends Component {
-

Sheet Music Tutor is still under development. Be first to find out when it gets updates.

+

+ Sheet Music Tutor is still under development. Be first to find out when it gets + updates. +

@@ -100,7 +103,10 @@ export default class App extends Component {
-

Follow us on social media to stay up to date on new features or to give us feedback.

+

+ Follow us on social media to stay up to date on new features or to give us + feedback. +

diff --git a/app/scripts/AppFreezer.js b/app/scripts/AppFreezer.js index d68e086..e4b7e70 100644 --- a/app/scripts/AppFreezer.js +++ b/app/scripts/AppFreezer.js @@ -7,18 +7,18 @@ let defaultSettings = { accuracyGoal: 0.85, timeGoal: 2000, amount: 5, - newNotesShare: 0.6 + newNotesShare: 0.6, }, chordSizeRanges: { treble: [1, 3], - bass: [1, 3] + bass: [1, 3], }, keySignature: [7, 7], useAccidentals: false, midi: { inputs: Freezer.createLeaf([]), - activeInputIndex: 0 - } + activeInputIndex: 0, + }, }, rhythmReading: { barDuration: 3000, @@ -29,8 +29,8 @@ let defaultSettings = { eighthNotes: true, sixteenthNotes: false, dottedNotes: false, - triplets: false - } + triplets: false, + }, }; const savedSettings = localStorage.getItem("SheetMusicTutor-settings"); @@ -41,7 +41,7 @@ if (savedSettings) { } const AppFreezer = new Freezer({ - settings: defaultSettings + settings: defaultSettings, }); AppFreezer.on("update", () => { diff --git a/app/scripts/services/analytics_service.js b/app/scripts/services/analytics_service.js index f4a3ca7..617ffa0 100644 --- a/app/scripts/services/analytics_service.js +++ b/app/scripts/services/analytics_service.js @@ -9,7 +9,7 @@ export default { hitType: "event", eventCategory, eventAction, - eventValue + eventValue, }); - } + }, }; diff --git a/app/scripts/services/bar_generator.js b/app/scripts/services/bar_generator.js index 1a2a17a..37b2ab6 100644 --- a/app/scripts/services/bar_generator.js +++ b/app/scripts/services/bar_generator.js @@ -10,9 +10,9 @@ const options = { chordsPerBar: 4, levels: { bass: [2, 3], - treble: [4, 5] + treble: [4, 5], }, - maximumInterval: 12 + maximumInterval: 12, }; function sampleWithoutReplacement(options) { @@ -30,7 +30,9 @@ function randomInvokeAOrB(probability, functionA, functionB) { export default { generateKeySignature: function(settings) { - const keySignatureIndex = _.sample(_.range(settings.keySignature[0], settings.keySignature[1] + 1)); + const keySignatureIndex = _.sample( + _.range(settings.keySignature[0], settings.keySignature[1] + 1), + ); return KeyConverter.keySignatureValueToString(keySignatureIndex); }, @@ -38,9 +40,9 @@ export default { return { keys: { treble: [], - bass: [] + bass: [], }, - durations: [] + durations: [], }; }, @@ -52,7 +54,11 @@ export default { const generateRandomDurations = () => { const durations = []; while (calcBarLength(durations) < 1) { - const possibleNotes = _.flatten([[4, 2], settings.eighthNotes ? 8 : null, settings.sixteenthNotes ? 16 : null]); + const possibleNotes = _.flatten([ + [4, 2], + settings.eighthNotes ? 8 : null, + settings.sixteenthNotes ? 16 : null, + ]); let newDuration = _.sample(possibleNotes); if (settings.rests && Math.random() < settings.restProbability) { @@ -78,16 +84,16 @@ export default { new Vex.Flow.StaveNote({ clef: "treble", keys: ["a/4"], - duration: duration > 0 ? `${duration}` : `${duration}r` - }) + duration: duration > 0 ? `${duration}` : `${duration}r`, + }), ); return { keys: { treble: staveNotes, - bass: [] + bass: [], }, - durations + durations, }; }, @@ -97,7 +103,7 @@ export default { new: level.keys.treble.concat(level.keys.bass).length, old: LevelService.getAllNotesUntilLevelIndex(level.index).length, trebleAndNew: level.keys.treble.length, - trebleAndOld: LevelService.getAllNotesUntilLevelIndex(level.index, "treble").length + trebleAndOld: LevelService.getAllNotesUntilLevelIndex(level.index, "treble").length, }; if (amounts.new === amounts.trebleAndNew && amounts.old === amounts.trebleAndOld) { // there are no bass notes @@ -107,10 +113,11 @@ export default { const frequencies = { new: settings.automaticDifficulty.newNotesShare, trebleGivenNew: amounts.trebleAndNew / (amounts.new || 1), - trebleGivenOld: amounts.trebleAndOld / (amounts.old || 1) + trebleGivenOld: amounts.trebleAndOld / (amounts.old || 1), }; const trebleProbability = - frequencies.trebleGivenNew * frequencies.new + frequencies.trebleGivenOld * (1 - frequencies.new); + frequencies.trebleGivenNew * frequencies.new + + frequencies.trebleGivenOld * (1 - frequencies.new); return trebleProbability; }; @@ -124,7 +131,7 @@ export default { } const lengths = { treble: _.max(settings.chordSizeRanges.treble), - bass: _.max(settings.chordSizeRanges.bass) + bass: _.max(settings.chordSizeRanges.bass), }; if (lengths.treble > 0 && lengths.bass > 0) { return _.sample([[0, 1], [1, 0]]); @@ -151,7 +158,7 @@ export default { if (level) { return { new: level.keys[clef], - old: LevelService.getAllNotesUntilLevelIndex(level.index, clef) + old: LevelService.getAllNotesUntilLevelIndex(level.index, clef), }; } const levels = clef === "treble" ? [4, 5] : [2, 3]; @@ -160,7 +167,7 @@ export default { const [possibleTrebleNotes, possibleBassNotes] = [ generatePossibleNotes("treble"), - generatePossibleNotes("bass") + generatePossibleNotes("bass"), ]; const [trebleAmount, bassAmount] = this.getClefAmounts(settings, onePerTime, level); @@ -170,14 +177,14 @@ export default { return [ this.generateNotesForBeat(settings, "treble", trebleAmount, possibleTrebleNotes), - this.generateNotesForBeat(settings, "bass", bassAmount, possibleBassNotes) + this.generateNotesForBeat(settings, "bass", bassAmount, possibleBassNotes), ]; - }) + }), ); return { treble: trebleNotes, - bass: bassNotes + bass: bassNotes, }; }, @@ -202,7 +209,7 @@ export default { return randomInvokeAOrB( newNoteProbability, () => sampleWithoutReplacement(newPossibleNotes), - () => sampleWithoutReplacement(oldPossibleNotes) + () => sampleWithoutReplacement(oldPossibleNotes), ); }); }, @@ -219,7 +226,7 @@ export default { const rest = new Vex.Flow.StaveNote({ clef: clef, keys: [clef === "treble" ? "a/4" : "c/3"], - duration: `${options.chordsPerBar}r` + duration: `${options.chordsPerBar}r`, }); return rest; } @@ -232,9 +239,12 @@ export default { const staveChord = new Vex.Flow.StaveNote({ clef: clef, keys: randomNoteSet.sort((keyA, keyB) => { - return KeyConverter.getKeyNumberForKeyString(keyA, "C") - KeyConverter.getKeyNumberForKeyString(keyB, "C"); + return ( + KeyConverter.getKeyNumberForKeyString(keyA, "C") - + KeyConverter.getKeyNumberForKeyString(keyB, "C") + ); }), - duration: `${options.chordsPerBar}` + duration: `${options.chordsPerBar}`, }); randomNoteSet.forEach(({ note, modifier }, index) => { @@ -244,5 +254,5 @@ export default { }); return staveChord; - } + }, }; diff --git a/app/scripts/services/key_converter.js b/app/scripts/services/key_converter.js index 8d3c5ea..ebf4211 100644 --- a/app/scripts/services/key_converter.js +++ b/app/scripts/services/key_converter.js @@ -18,10 +18,26 @@ const keySignatureOffsets = { Ab: ["b", "e", "a", "d"], Db: ["b", "e", "a", "d", "g"], Gb: ["b", "e", "a", "d", "g", "c"], - Cb: ["b", "e", "a", "d", "g", "c", "f"] + Cb: ["b", "e", "a", "d", "g", "c", "f"], }; -const keySignatures = ["C#", "F#", "B", "E", "A", "D", "G", "C", "F", "Bb", "Eb", "Ab", "Db", "Gb", "Cb"]; +const keySignatures = [ + "C#", + "F#", + "B", + "E", + "A", + "D", + "G", + "C", + "F", + "Bb", + "Eb", + "Ab", + "Db", + "Gb", + "Cb", +]; const octaveNotes = ["c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"]; const keyMap = initializeKeyMap(); @@ -137,7 +153,8 @@ const KeyConverter = { [keyString, flatDifference] = stripKey(keyString, "b"); [keyString, sharpDifference] = stripKey(keyString, "#"); - const keyNumber = KeyConverter.getKeyNumberForCanonicalKeyString(keyString) + sharpDifference - flatDifference; + const keyNumber = + KeyConverter.getKeyNumberForCanonicalKeyString(keyString) + sharpDifference - flatDifference; return KeyConverter.getKeyStringForKeyNumber(keyNumber); }, @@ -175,7 +192,7 @@ const KeyConverter = { .map(KeyConverter.getNoteFromKeyString); return _.difference(octaveNotes, cScaleNotes); - } + }, }; export default KeyConverter; diff --git a/app/scripts/services/level_service.js b/app/scripts/services/level_service.js index 169db1e..6faf887 100644 --- a/app/scripts/services/level_service.js +++ b/app/scripts/services/level_service.js @@ -9,34 +9,34 @@ const levelGroups = [ base: { clef: "treble", signature: "C", - accidentals: false + accidentals: false, }, sublevels: [ r("c/4", "e/4"), r("f/4", "a/4"), r("b/4", "d/5"), r("e/5", "g/5"), - r("a/5", "c/6") + r("a/5", "c/6"), // very high and very low end should also go here - ] + ], }, { base: { clef: "bass", signature: "C", - accidentals: false + accidentals: false, }, sublevels: [ r("c/2", "e/2"), r("f/2", "a/2"), r("b/2", "d/3"), r("e/3", "g/3"), - r("a/3", "c/4") + r("a/3", "c/4"), // very high and very low end should also go here - ] - } + ], + }, ]; const Levels = _.flatMap(levelGroups, levelGroup => { @@ -44,8 +44,8 @@ const Levels = _.flatMap(levelGroups, levelGroup => { const level = _.assign({}, levelGroup.base, { keys: { treble: levelGroup.base.clef === "treble" ? sublevel : [], - bass: levelGroup.base.clef === "bass" ? sublevel : [] - } + bass: levelGroup.base.clef === "bass" ? sublevel : [], + }, }); delete level.clef; return level; @@ -67,7 +67,7 @@ const LevelService = { return keys[optClef]; } return [].concat(keys.treble, keys.bass); - }) + }), ); }, getLevelOfUser(events) { @@ -103,15 +103,17 @@ const LevelService = { optThresholds = optThresholds || { amount: thresholdSettings.amount, accuracy: thresholdSettings.accuracyGoal, - time: thresholdSettings.timeGoal + time: thresholdSettings.timeGoal, }; - const filteredEvents = eventsToAssess.filter(event => event.keys.some(this.levelContainsKey.bind(this, level))); + const filteredEvents = eventsToAssess.filter(event => + event.keys.some(this.levelContainsKey.bind(this, level)), + ); const unfoldedEvents = _.flatMap(filteredEvents, event => { return event.keys.map(key => { const subEvent = { ...event, - key + key, }; delete subEvent.keys; return subEvent; @@ -142,17 +144,17 @@ const LevelService = { eventsLength, time, accuracy, - thresholds: optThresholds - } + thresholds: optThresholds, + }, }; }); const goodEnoughPartition = _.partition(evaluation, el => el.isGoodEnough); return { goodEnoughKeys: goodEnoughPartition[0], notGoodEnoughKeys: goodEnoughPartition[1], - isInLevel: goodEnoughPartition[1].length === 0 && evaluation.length > 0 + isInLevel: goodEnoughPartition[1].length === 0 && evaluation.length > 0, }; - } + }, }; export default LevelService; diff --git a/app/scripts/services/metronome_service.js b/app/scripts/services/metronome_service.js index 3b45888..2679ea7 100644 --- a/app/scripts/services/metronome_service.js +++ b/app/scripts/services/metronome_service.js @@ -17,7 +17,7 @@ function loadMp3() { }, function(e) { console.error("Error with decoding audio data" + e.err); - } + }, ); }; @@ -40,5 +40,5 @@ export default { }, stop: function(source) { source.stop(0); - } + }, }; diff --git a/app/scripts/services/midi_service.js b/app/scripts/services/midi_service.js index cf15f5b..10635b5 100644 --- a/app/scripts/services/midi_service.js +++ b/app/scripts/services/midi_service.js @@ -115,13 +115,13 @@ export default class MidiService { getMidiSettings().set({ inputs: Freezer.createLeaf(inputs), - activeInputIndex: 0 + activeInputIndex: 0, }); AppFreezer.on("input:changed", newIndex => { const midiSettings = getMidiSettings(); midiSettings.set({ - activeInputIndex: newIndex + activeInputIndex: newIndex, }); this.unlistenToInputs(midiSettings.inputs.get()); this.listenToInput(midiSettings.inputs.get()[newIndex]); diff --git a/app/scripts/services/pitch_statistic_service.js b/app/scripts/services/pitch_statistic_service.js index 24dc694..e4e14c5 100644 --- a/app/scripts/services/pitch_statistic_service.js +++ b/app/scripts/services/pitch_statistic_service.js @@ -60,8 +60,8 @@ class PitchStatisticService { event.success ? 10 : -0.1, event.keys.length, 10e6 / Math.pow(event.time, 2), - KeyConverter.rateKeySignatureDifficulty(event.keySignature) - ].reduce((a, b) => a * b, 1) + KeyConverter.rateKeySignatureDifficulty(event.keySignature), + ].reduce((a, b) => a * b, 1), ) ); } @@ -124,7 +124,7 @@ class PitchStatisticService { return [ el.date.getUTCFullYear(), ("0" + el.date.getMonth()).slice(-2), - ("0" + el.date.getDate()).slice(-2) + ("0" + el.date.getDate()).slice(-2), ].join("-"); }) .map((aDay, formattedDate) => { diff --git a/app/scripts/services/rhythm_checker.js b/app/scripts/services/rhythm_checker.js index 0577cb2..e5aaf0e 100644 --- a/app/scripts/services/rhythm_checker.js +++ b/app/scripts/services/rhythm_checker.js @@ -67,14 +67,14 @@ export default { if (givenTimes.length > expectedTimes.length) { beatEvaluations = beatEvaluations.concat( - givenTimes.slice(expectedTimes.length).map(() => ({ superfluous: true, correct: false })) + givenTimes.slice(expectedTimes.length).map(() => ({ superfluous: true, correct: false })), ); } return { beatEvaluations, missesBeat, - success: beatEvaluations.every(el => el.correct) && !missesBeat + success: beatEvaluations.every(el => el.correct) && !missesBeat, }; }, @@ -87,5 +87,5 @@ export default { shortestNote = 16; } return shortestNote; - } + }, }; diff --git a/app/scripts/services/rhythm_statistic_service.js b/app/scripts/services/rhythm_statistic_service.js index f798f63..9d61793 100644 --- a/app/scripts/services/rhythm_statistic_service.js +++ b/app/scripts/services/rhythm_statistic_service.js @@ -110,8 +110,8 @@ class RhythmStatisticService { _.sum(event.durations.map(el => Math.abs(el))), 10e5 / Math.pow(event.barDuration, 2), event.liveBeatBars ? 0.5 : 1, - event.liveBeatBars && event.labelBeats ? 0.5 : 1 - ].reduce((a, b) => a * b, 1) + event.liveBeatBars && event.labelBeats ? 0.5 : 1, + ].reduce((a, b) => a * b, 1), ); } @@ -130,7 +130,7 @@ class RhythmStatisticService { return [ el.date.getUTCFullYear(), ("0" + el.date.getMonth()).slice(-2), - ("0" + el.date.getDate()).slice(-2) + ("0" + el.date.getDate()).slice(-2), ].join("-"); }) .map((aDay, formattedDate) => { diff --git a/app/scripts/services/stat_evolver.js b/app/scripts/services/stat_evolver.js index 282886a..1e9b9e5 100644 --- a/app/scripts/services/stat_evolver.js +++ b/app/scripts/services/stat_evolver.js @@ -15,10 +15,10 @@ const evolutions = [ statObj.keySignature = "C"; } return statObj; - } + }, ]; export default { runEvolution: (statObj, index) => evolutions[index](statObj), - evolveToLatestSchema: statObj => _.flow(...evolutions)(statObj) + evolveToLatestSchema: statObj => _.flow(...evolutions)(statObj), }; diff --git a/app/scripts/spec/key_converter_spec.js b/app/scripts/spec/key_converter_spec.js index 7873f1c..9b1e921 100644 --- a/app/scripts/spec/key_converter_spec.js +++ b/app/scripts/spec/key_converter_spec.js @@ -27,13 +27,20 @@ describe("KeyConverter", function() { }); it("gets scales for an arbitrary base", function() { - const cScale = KeyConverter.getScaleKeysForBase("c/4").map(KeyConverter.getKeyStringForKeyNumber); + const cScale = KeyConverter.getScaleKeysForBase("c/4").map( + KeyConverter.getKeyStringForKeyNumber, + ); expect(cScale).toEqual(["c/4", "d/4", "e/4", "f/4", "g/4", "a/4", "b/4"]); - const fSharpScale = KeyConverter.getScaleKeysForBase("f#/4").map(KeyConverter.getKeyStringForKeyNumber); + const fSharpScale = KeyConverter.getScaleKeysForBase("f#/4").map( + KeyConverter.getKeyStringForKeyNumber, + ); const expectedFSharpScale = ["f#/4", "g#/4", "a#/4", "b/4", "c#/5", "d#/5", "e#/5"]; - const normalizedFSharpScale = expectedFSharpScale.map(KeyConverter.getCanonicalKeyString, KeyConverter); + const normalizedFSharpScale = expectedFSharpScale.map( + KeyConverter.getCanonicalKeyString, + KeyConverter, + ); expect(fSharpScale).toEqual(normalizedFSharpScale); }); diff --git a/app/scripts/spec/level_service_spec.js b/app/scripts/spec/level_service_spec.js index f273013..d3215af 100644 --- a/app/scripts/spec/level_service_spec.js +++ b/app/scripts/spec/level_service_spec.js @@ -4,7 +4,14 @@ describe("LevelService", function() { it("getAllNotesUntilLevel", function() { expect(LevelService.getAllNotesUntilLevelIndex(1)).toEqual(["c/4", "d/4", "e/4"]); - expect(LevelService.getAllNotesUntilLevelIndex(2)).toEqual(["c/4", "d/4", "e/4", "f/4", "g/4", "a/4"]); + expect(LevelService.getAllNotesUntilLevelIndex(2)).toEqual([ + "c/4", + "d/4", + "e/4", + "f/4", + "g/4", + "a/4", + ]); }); it("isInLevel", function() { @@ -12,31 +19,31 @@ describe("LevelService", function() { { success: true, keys: ["c/4", "d/4", "e/4", "f/4"], - time: 1500 + time: 1500, }, { success: true, keys: ["c/4", "d/4", "e/4", "g/4"], - time: 1000 + time: 1000, }, { success: false, keys: ["c/4", "d/4", "e/4", "a/4"], - time: 1500 - } + time: 1500, + }, ]; const positiveEvaluation = LevelService.assessLevel(events, LevelService.getLevelByIndex(0), { amount: 2, accuracy: 0.66, - time: 1334 + time: 1334, }); expect(positiveEvaluation.isInLevel).toBe(true); const negativeEvaluation = LevelService.assessLevel(events, LevelService.getLevelByIndex(0), { amount: 2, accuracy: 0.67, - time: 1334 + time: 1334, }); expect(negativeEvaluation.isInLevel).toBe(false); }); diff --git a/app/scripts/spec/rhythm_checker_spec.js b/app/scripts/spec/rhythm_checker_spec.js index bd190c0..a8eee54 100644 --- a/app/scripts/spec/rhythm_checker_spec.js +++ b/app/scripts/spec/rhythm_checker_spec.js @@ -25,7 +25,7 @@ describe("RhythmChecker", function() { const settings1 = { barDuration: 3000, eighthNotes: true, - sixteenthNotes: false + sixteenthNotes: false, }; const result1 = RhythmChecker.compare(expectedTimes, givenTimesCorrect, settings1); diff --git a/app/scripts/spec/stat_evolver_spec.js b/app/scripts/spec/stat_evolver_spec.js index 49d837c..b2d10b9 100644 --- a/app/scripts/spec/stat_evolver_spec.js +++ b/app/scripts/spec/stat_evolver_spec.js @@ -10,14 +10,14 @@ describe("StatEvolver", function() { "time": 14622, "date":"2016-03-01T23:59:04.462Z", "formattedDate":"2016-02-01" - }`) + }`), ), { success: true, keys: ["f/4", "e/3", "b/3", "d/3"], time: 14622, date: new Date("2016-03-01T23:59:04.462Z"), - version: 1 + version: 1, }, { success: true, @@ -25,8 +25,8 @@ describe("StatEvolver", function() { time: 14622, date: new Date("2016-03-01T23:59:04.462Z"), version: 2, - keySignature: "C" - } + keySignature: "C", + }, ]; it("transforms from version 0 to 1", function() { diff --git a/app/scripts/views/animated_number.js b/app/scripts/views/animated_number.js index 6c7cf22..fb7806e 100644 --- a/app/scripts/views/animated_number.js +++ b/app/scripts/views/animated_number.js @@ -5,7 +5,7 @@ import { Motion, spring } from "react-motion"; export default class AnimatedNumber extends Component { static propTypes = { formatter: PropTypes.func, - number: PropTypes.number + 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 252181b..6610290 100644 --- a/app/scripts/views/beat_visualization.js +++ b/app/scripts/views/beat_visualization.js @@ -11,7 +11,7 @@ export default class BeatVisualization extends Component { barDuration: PropTypes.number.isRequired, currentRhythm: PropTypes.object.isRequired, beatHistory: PropTypes.array.isRequired, - result: PropTypes.object + result: PropTypes.object, }; convertTicksToBeatNames(tickTime, tickLength) { @@ -19,10 +19,29 @@ export default class BeatVisualization extends Component { // round to fix non-integers due to numerical imprecision const tickIndex = Math.round(tickTime / tickTimeToIndexFactor); const tickStepCount = Math.round(tickLength / tickTimeToIndexFactor); - const allBeatNames = ["1", "e", "&", "a", "2", "e", "&", "a", "3", "e", "&", "a", "4", "e", "&", "a"]; + const allBeatNames = [ + "1", + "e", + "&", + "a", + "2", + "e", + "&", + "a", + "3", + "e", + "&", + "a", + "4", + "e", + "&", + "a", + ]; const necessaryNameFraction = 16 / RhythmChecker.getShortestNote(this.props.settings); - const necessaryBeatNames = allBeatNames.filter((el, index) => index % necessaryNameFraction === 0); + const necessaryBeatNames = allBeatNames.filter( + (el, index) => index % necessaryNameFraction === 0, + ); const ticks = necessaryBeatNames.slice(tickIndex, tickIndex + tickStepCount); return ( @@ -54,13 +73,17 @@ export default class BeatVisualization extends Component { return [ marginLeft > 0 ? ( -
+
{beatNamesRest}
) : null,
{beatNames} -
+
, ]; }; @@ -72,7 +95,10 @@ export default class BeatVisualization extends Component { return _.flatten(createBeat(a, width, getColor(index), index)); }); }; - const expectedTimes = RhythmChecker.convertDurationsToTimes(this.props.currentRhythm.durations, barDuration); + const expectedTimes = RhythmChecker.convertDurationsToTimes( + this.props.currentRhythm.durations, + barDuration, + ); const expectedBeats = drawBeats(expectedTimes, _.constant("gray"), true); @@ -88,12 +114,12 @@ export default class BeatVisualization extends Component { } return result.beatEvaluations[index].correct ? "green" : "red"; }, - false + false, ); const className = classNames({ "beat-container": true, - thin: !this.props.settings.labelBeats + thin: !this.props.settings.labelBeats, }); // uniqueId avoids that different beat bars are animated into each other diff --git a/app/scripts/views/claviature_view.js b/app/scripts/views/claviature_view.js index db928c6..40668b1 100644 --- a/app/scripts/views/claviature_view.js +++ b/app/scripts/views/claviature_view.js @@ -9,19 +9,19 @@ export default class ClaviatureView extends Component { keySignature: PropTypes.string, successCallback: PropTypes.func, failureCallback: PropTypes.func, - disabled: PropTypes.bool + disabled: PropTypes.bool, }; constructor(props, context) { super(props, context); this.state = { // The key which is currently "clicked". Only used for keyboard navigation. - activeKey: null + activeKey: null, }; } static contextTypes = { - isInActiveView: PropTypes.bool + isInActiveView: PropTypes.bool, }; isNoteCorrect(noteName) { @@ -49,18 +49,18 @@ export default class ClaviatureView extends Component { } if (eventType === "keydown") { this.setState({ - activeKey: noteName + activeKey: noteName, }); } else { this.setState({ - activeKey: null + activeKey: null, }); this.onClick(noteName); } }; this.keyHandlers = { keydown: keyHandler.bind(this, "keydown"), - keyup: keyHandler.bind(this, "keyup") + keyup: keyHandler.bind(this, "keyup"), }; document.addEventListener("keydown", this.keyHandlers.keydown); document.addEventListener("keyup", this.keyHandlers.keyup); @@ -85,10 +85,15 @@ export default class ClaviatureView extends Component { const className = classNames({ "black-note": color === "black", green: this.isNoteCorrect(keyName), - active: keyName === this.state.activeKey + active: keyName === this.state.activeKey, }); return ( -
  • +
  • {keyLabel}
  • ); @@ -107,7 +112,7 @@ export default class ClaviatureView extends Component { ["g#", "G# A♭", "black"], ["a", "A", "white"], ["a#", "A# B♭", "black"], - ["b", "B", "white"] + ["b", "B", "white"], ].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 fc1e6ba..e215942 100644 --- a/app/scripts/views/collapsable_container.js +++ b/app/scripts/views/collapsable_container.js @@ -9,7 +9,7 @@ export default class CollapsableContainer extends Component { collapsed: PropTypes.bool.isRequired, maxHeight: PropTypes.number, freeze: PropTypes.bool, - className: PropTypes.string + className: PropTypes.string, }; componentWillReceiveProps(nextProps) { @@ -24,13 +24,14 @@ export default class CollapsableContainer extends Component { this.props.className, classNames({ collapsed, - transition: true - }) + transition: true, + }), ]).join(" "); const maxHeight = this.props.maxHeight || 300; const style = collapsed ? {} : { maxHeight }; - const children = collapsed && this.props.freeze && this.oldChildren ? this.oldChildren : this.props.children; + const children = + collapsed && this.props.freeze && this.oldChildren ? this.oldChildren : this.props.children; return (
    diff --git a/app/scripts/views/game_button.js b/app/scripts/views/game_button.js index 6bd5b67..5cd1738 100644 --- a/app/scripts/views/game_button.js +++ b/app/scripts/views/game_button.js @@ -7,11 +7,11 @@ export default class GameButton extends Component { label: PropTypes.string.isRequired, onClick: PropTypes.func.isRequired, primary: PropTypes.bool, - shortcutLetter: PropTypes.string + shortcutLetter: PropTypes.string, }; static contextTypes = { - isInActiveView: PropTypes.bool + isInActiveView: PropTypes.bool, }; componentDidMount() { @@ -46,7 +46,11 @@ export default class GameButton extends Component { ) : null; return ( - diff --git a/app/scripts/views/level_view.js b/app/scripts/views/level_view.js index 81d4773..09cefb0 100644 --- a/app/scripts/views/level_view.js +++ b/app/scripts/views/level_view.js @@ -6,7 +6,7 @@ import PieChart from "../views/pie_chart.js"; export default class LevelView extends Component { static propTypes = { - statisticService: PropTypes.object.isRequired + statisticService: PropTypes.object.isRequired, }; render() { @@ -20,8 +20,8 @@ export default class LevelView extends Component { const evaluation = LevelService.assessLevel(events, nextLevel); const goodEnoughProgress = - evaluation.goodEnoughKeys.length / (evaluation.goodEnoughKeys.length + evaluation.notGoodEnoughKeys.length) || - 0; + evaluation.goodEnoughKeys.length / + (evaluation.goodEnoughKeys.length + evaluation.notGoodEnoughKeys.length) || 0; const notGoodEnoughEvaluations = _.flatten( evaluation.notGoodEnoughKeys.map(keyEvaluation => { @@ -30,14 +30,26 @@ export default class LevelView extends Component { // if you are slower than 30s, it is still considered as 30s const longestTimeThreshold = 30000; - const clampedTime = _.clamp(evaluationDetails.time, evaluationThresholds.time, longestTimeThreshold); + const clampedTime = _.clamp( + evaluationDetails.time, + evaluationThresholds.time, + longestTimeThreshold, + ); const timeProgress = - 1 - (clampedTime - evaluationThresholds.time) / (longestTimeThreshold - evaluationThresholds.time); - const accuracyProgress = Math.min(1, evaluationDetails.accuracy / evaluationThresholds.accuracy); - const amountProgress = Math.min(1, evaluationDetails.eventsLength / evaluationThresholds.amount); + 1 - + (clampedTime - evaluationThresholds.time) / + (longestTimeThreshold - evaluationThresholds.time); + const accuracyProgress = Math.min( + 1, + evaluationDetails.accuracy / evaluationThresholds.accuracy, + ); + const amountProgress = Math.min( + 1, + evaluationDetails.eventsLength / evaluationThresholds.amount, + ); return [timeProgress, accuracyProgress, amountProgress].map(el => el / 3); - }) + }), ).map(el => el / evaluation.notGoodEnoughKeys.length * (1 - goodEnoughProgress)); const pieParts = [_.sum([goodEnoughProgress].concat(notGoodEnoughEvaluations))]; @@ -56,7 +68,10 @@ export default class LevelView extends Component { content = (

    Congratulations! You finished the final level!

    -

    You may want to increase your goals in the settings pane or switch to the manual training mode.

    +

    + You may want to increase your goals in the settings pane or switch to the manual + training mode. +

    ); } diff --git a/app/scripts/views/metronome_view.js b/app/scripts/views/metronome_view.js index cd242d0..fafc0f3 100644 --- a/app/scripts/views/metronome_view.js +++ b/app/scripts/views/metronome_view.js @@ -9,13 +9,13 @@ import CollapsableContainer from "./collapsable_container.js"; export default class MetronomeView extends Component { static propTypes = { onMetronomeEnded: PropTypes.func, - settings: PropTypes.object.isRequired + settings: PropTypes.object.isRequired, }; constructor(props, context) { super(props, context); this.state = { - currentMetronomeBeat: -1 + currentMetronomeBeat: -1, }; } @@ -36,7 +36,8 @@ export default class MetronomeView extends Component { // playing time. const magicPercentileOfAudibleBeat = 0.33; // this is the first beat of the actual bar - this.firstBarBeatTime = startTime + 4 * beatLength + metronomeSoundLength * magicPercentileOfAudibleBeat; + this.firstBarBeatTime = + startTime + 4 * beatLength + metronomeSoundLength * magicPercentileOfAudibleBeat; _.range(beatAmount + 1).map(beatIndex => { const beatTime = startTime + beatIndex * beatLength; @@ -47,7 +48,7 @@ export default class MetronomeView extends Component { } setTimeout(() => { this.setState({ - currentMetronomeBeat: beatIndex < 4 ? beatIndex : -1 + currentMetronomeBeat: beatIndex < 4 ? beatIndex : -1, }); if (beatIndex === beatAmount) { @@ -62,7 +63,7 @@ export default class MetronomeView extends Component {

    {this.state.currentMetronomeBeat + 1}

    diff --git a/app/scripts/views/newsletter_form.js b/app/scripts/views/newsletter_form.js index 002178d..85e42b9 100644 --- a/app/scripts/views/newsletter_form.js +++ b/app/scripts/views/newsletter_form.js @@ -45,7 +45,12 @@ export default class NewsLetterForm extends Component {
    0; @@ -173,7 +173,7 @@ export default class PitchReadingView extends Component {

    Welcome to this pitch training!

    @@ -191,7 +191,7 @@ export default class PitchReadingView extends Component { const emptyKeySet = { treble: [], - bass: [] + bass: [], }; return ( @@ -208,7 +208,7 @@ export default class PitchReadingView extends Component {
    @@ -223,7 +223,7 @@ export default class PitchReadingView extends Component {

    {this.state.errorMessage}

    @@ -234,7 +234,10 @@ export default class PitchReadingView extends Component {
    - +