diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index a7e32b8..69f0162 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -3,15 +3,11 @@ import { Routes, RouterModule } from '@angular/router';
import { ChordsComponent } from './chords/chords.component';
import { ScalesComponent } from './scales/scales.component';
-import { ProgressionsComponent } from './progressions/progressions.component';
-import { PiecesComponent } from './pieces/pieces.component';
const routes: Routes = [
{ path: '', redirectTo: '/chords', pathMatch: 'full' },
{ path: 'chords', component: ChordsComponent },
{ path: 'scales', component: ScalesComponent },
- { path: 'progressions', component: ProgressionsComponent },
- { path: 'pieces', component: PiecesComponent },
];
@NgModule({
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 11a0ba9..d5e7f43 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -8,24 +8,10 @@ import { PianoComponent } from './piano/piano.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ChordsComponent } from './chords/chords.component';
import { ScalesComponent } from './scales/scales.component';
-import { ProgressionsComponent } from './progressions/progressions.component';
-import { PiecesComponent } from './pieces/pieces.component';
@NgModule({
- declarations: [
- AppComponent,
- PianoComponent,
- ChordsComponent,
- ScalesComponent,
- ProgressionsComponent,
- PiecesComponent,
- ],
- imports: [
- BrowserModule,
- AppRoutingModule,
- BrowserAnimationsModule,
- FormsModule,
- ],
+ declarations: [AppComponent, PianoComponent, ChordsComponent, ScalesComponent],
+ imports: [BrowserModule, AppRoutingModule, BrowserAnimationsModule, FormsModule],
providers: [],
bootstrap: [AppComponent],
})
diff --git a/src/app/chords/chords.component.html b/src/app/chords/chords.component.html
index 0279731..885abbd 100644
--- a/src/app/chords/chords.component.html
+++ b/src/app/chords/chords.component.html
@@ -4,11 +4,11 @@
No chords enabled!
+ (change)="chordQuestionGenerator.generateQuestions()">
Sharps
+ (change)="chordQuestionGenerator.generateQuestions()">
Naturals
@@ -16,6 +16,6 @@ Enabled chord types
+ (change)="chordQuestionGenerator.generateQuestions()">
{{ chordNames[item.key] }}
diff --git a/src/app/chords/chords.component.ts b/src/app/chords/chords.component.ts
index bb7d589..f14f480 100644
--- a/src/app/chords/chords.component.ts
+++ b/src/app/chords/chords.component.ts
@@ -3,7 +3,7 @@ import { ChangeDetectorRef } from '@angular/core';
import { PianoService } from '../piano/piano.service';
import { Subscription } from 'rxjs';
import { ChordQuestionGenerator } from './chords';
-import { chordNames } from '../data';
+import { chordNames } from '../utils/data';
@Component({
selector: 'app-chords',
@@ -11,29 +11,26 @@ import { chordNames } from '../data';
styleUrls: ['./chords.component.scss'],
})
export class ChordsComponent implements OnInit, OnDestroy {
- public chordQuestionGenerator = new ChordQuestionGenerator();
+ public chordQuestionGenerator: ChordQuestionGenerator;
public chordNames = chordNames;
- private chordSubscription: Subscription;
+ private chordQuestionSubscription: Subscription;
constructor(
- private ref: ChangeDetectorRef,
+ private ref: ChangeDetectorRef, //
private pianoService: PianoService
) {
- this.chordSubscription = this.pianoService.chordsSource.subscribe(
- chords => {
- if (this.chordQuestionGenerator.checkAnswer(chords)) {
- this.chordQuestionGenerator.nextQuestion();
- }
- this.ref.detectChanges();
- }
- );
+ this.chordQuestionGenerator = new ChordQuestionGenerator(pianoService);
+ this.chordQuestionSubscription = this.chordQuestionGenerator.pageUpdateSource.subscribe(() => {
+ this.ref.detectChanges();
+ });
}
ngOnInit() {}
ngOnDestroy() {
// prevent memory leak when component destroyed
- this.chordSubscription.unsubscribe();
+ this.chordQuestionGenerator.destroy();
+ this.chordQuestionSubscription.unsubscribe();
}
}
diff --git a/src/app/chords/chords.ts b/src/app/chords/chords.ts
index 73d2314..d67a1d6 100644
--- a/src/app/chords/chords.ts
+++ b/src/app/chords/chords.ts
@@ -1,58 +1,59 @@
-import { numToString } from '../data';
-import { chordpatterns } from '../data';
+import { numToString } from '../utils/data';
+import { chordpatterns } from '../utils/data';
+import { QuestionGenerator } from '../models/questionGenerator';
+import { PianoService } from '../piano/piano.service';
+import { Subject, Subscription } from 'rxjs';
+
+export class ChordQuestionGenerator implements QuestionGenerator {
+ public enabledQuestions = [];
+ public question = '';
+ public pageUpdateSource = new Subject();
+
+ private chordSubscription: Subscription;
-export class ChordQuestionGenerator {
public enableSharps = false;
public enableNaturals = true;
public enableChords = {
- '': false,
+ '': true,
7: false,
maj7: false,
m: false,
m7: false,
mmaj7: false,
dim: false,
- dim7: true,
+ dim7: false,
};
- public enabledChordNames = [];
- public question = '';
+ constructor(pianoService: PianoService) {
+ this.generateQuestions();
+ this.chordSubscription = pianoService.chordsSource.subscribe(chords => {
+ if (this.checkAnswer(chords)) {
+ this.nextQuestion();
+ }
+ });
+ }
- public generateChordNames() {
- this.enabledChordNames = [];
+ public generateQuestions() {
+ this.enabledQuestions = [];
for (let root = 21; root < 33; root++) {
const note = numToString(root, false);
- if (
- (note.length === 1 || this.enableSharps) &&
- (note.length === 2 || this.enableNaturals)
- ) {
- for (const pat of Object.keys(chordpatterns).filter(
- patt => this.enableChords[patt]
- )) {
- this.enabledChordNames.push(note + ' ' + pat);
+ if ((note.length === 1 || this.enableSharps) && (note.length === 2 || this.enableNaturals)) {
+ for (const pat of Object.keys(chordpatterns).filter(patt => this.enableChords[patt])) {
+ this.enabledQuestions.push(note + ' ' + pat);
}
}
}
- console.log(this.enabledChordNames);
this.nextQuestion();
}
-
- constructor() {
- this.generateChordNames();
- }
-
public nextQuestion() {
- this.question =
- this.enabledChordNames[
- Math.floor(Math.random() * this.enabledChordNames.length)
- ];
- return this.question;
+ this.question = this.enabledQuestions[Math.floor(Math.random() * this.enabledQuestions.length)];
+ this.pageUpdateSource.next();
+ }
+ public destroy() {
+ this.chordSubscription.unsubscribe();
}
- public checkAnswer(chords: string[]) {
- if (chords.includes(this.question)) {
- return true;
- }
- return false;
+ private checkAnswer(chords: string[]) {
+ return chords.includes(this.question);
}
}
diff --git a/src/app/models/questionGenerator.ts b/src/app/models/questionGenerator.ts
new file mode 100644
index 0000000..fab470e
--- /dev/null
+++ b/src/app/models/questionGenerator.ts
@@ -0,0 +1,10 @@
+import { Subject } from 'rxjs';
+
+export interface QuestionGenerator {
+ question: string;
+ enabledQuestions: string[];
+ pageUpdateSource: Subject;
+ generateQuestions(): void;
+ nextQuestion(): void;
+ destroy(): void;
+}
diff --git a/src/app/piano/piano.component.html b/src/app/piano/piano.component.html
index f0db665..d7f2f9e 100644
--- a/src/app/piano/piano.component.html
+++ b/src/app/piano/piano.component.html
@@ -14,9 +14,6 @@
diff --git a/src/app/piano/piano.service.ts b/src/app/piano/piano.service.ts
index ff0e85e..73e5fde 100644
--- a/src/app/piano/piano.service.ts
+++ b/src/app/piano/piano.service.ts
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
-import { octaves, noteNames, generateChords, enharmonicNotes } from '../data';
+import { enharmonicNotes, generateChords, noteNames, octaves } from '../utils/data';
+import { arraysEqual } from '../utils/utils';
@Injectable({
providedIn: 'root',
@@ -10,24 +11,24 @@ export class PianoService {
private activeNotes = [];
private chords = generateChords();
- notesSource = new Subject