Skip to content

Commit 7625f63

Browse files
authored
Merge pull request #45 from ishythefishy/show-scales-same-as-current
Show similar modes to standard modes, clean up tests and some styles
2 parents 4a176c3 + cfb0340 commit 7625f63

25 files changed

+655
-26
lines changed

apps/fretonator-web/src/app/common/fret-map/fret-map.service.spec.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import {
1212
cIonianChordMap,
1313
cIonianFretMappings,
1414
cIonianMode,
15+
cIonianSimilarModes,
16+
cLydianMode,
17+
cLydianSimilarModes,
1518
cMajorPentatonicChordMap,
1619
cMinorPentatonicChordMap,
1720
cPhrygianMode,
@@ -1351,3 +1354,70 @@ describe('FretMapService:convertFretMapConfigurationToDisplayString', () => {
13511354
expect(result).toBe('A flat Minor Pentatonic');
13521355
});
13531356
});
1357+
1358+
describe('FretMapService:getNoteExtenderStringFromNoteObject', () => {
1359+
let service: FretMapService;
1360+
1361+
beforeEach(() => {
1362+
TestBed.configureTestingModule({});
1363+
service = TestBed.inject(FretMapService);
1364+
});
1365+
1366+
it('returns NoteExtenderString.flat for a flat note', () => {
1367+
const result = service.getNoteExtenderStringFromNoteObject({
1368+
name: 'b',
1369+
flat: true,
1370+
sharp: false,
1371+
doubleSharp: false,
1372+
doubleFlat: false
1373+
});
1374+
expect(result).toBe('flat');
1375+
});
1376+
1377+
1378+
it('returns NoteExtenderString.sharp for a sharp note', () => {
1379+
const result = service.getNoteExtenderStringFromNoteObject({
1380+
name: 'd',
1381+
flat: false,
1382+
sharp: true,
1383+
doubleSharp: false,
1384+
doubleFlat: false
1385+
});
1386+
expect(result).toBe('sharp');
1387+
});
1388+
1389+
it('returns NoteExtenderString.natural for a natural note', () => {
1390+
const result = service.getNoteExtenderStringFromNoteObject({
1391+
name: 'd',
1392+
flat: false,
1393+
sharp: false,
1394+
doubleSharp: false,
1395+
doubleFlat: false
1396+
});
1397+
expect(result).toBe('natural');
1398+
});
1399+
});
1400+
1401+
describe('FretMapService:getSimilarModes', () => {
1402+
let service: FretMapService;
1403+
1404+
beforeEach(() => {
1405+
TestBed.configureTestingModule({});
1406+
service = TestBed.inject(FretMapService);
1407+
});
1408+
1409+
it('returns correctly for an input of c natural ionian', () => {
1410+
const result = service.getSimilarModes(cIonianMode, Mode.ionian);
1411+
expect(result).toEqual(cIonianSimilarModes);
1412+
});
1413+
1414+
it('returns correctly for an input of c natural lydian', () => {
1415+
const result = service.getSimilarModes(cLydianMode, Mode.lydian);
1416+
expect(result).toEqual(cLydianSimilarModes);
1417+
});
1418+
1419+
it('returns an empty array for a mode not in the StandardModePatterns array', () => {
1420+
const result = service.getSimilarModes(fSharpHarmonicMinor, Mode.harmonicMinor);
1421+
expect(result).toEqual([]);
1422+
});
1423+
});

apps/fretonator-web/src/app/common/fret-map/fret-map.service.testConstants.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,65 @@ export const cIonianMode: ModeMap = [
446446
},
447447
];
448448

449+
export const cLydianMode: ModeMap = [
450+
{
451+
name: 'c',
452+
sharp: false,
453+
flat: false,
454+
doubleFlat: false,
455+
doubleSharp: false,
456+
displayName: 'C'
457+
},
458+
{
459+
name: 'd',
460+
sharp: false,
461+
flat: false,
462+
doubleFlat: false,
463+
doubleSharp: false,
464+
displayName: 'D'
465+
},
466+
{
467+
name: 'e',
468+
sharp: false,
469+
flat: false,
470+
doubleFlat: false,
471+
doubleSharp: false,
472+
displayName: 'E'
473+
},
474+
{
475+
name: 'f',
476+
sharp: true,
477+
flat: false,
478+
doubleFlat: false,
479+
doubleSharp: false,
480+
displayName: 'F'
481+
},
482+
{
483+
name: 'g',
484+
sharp: false,
485+
flat: false,
486+
doubleFlat: false,
487+
doubleSharp: false,
488+
displayName: 'G'
489+
},
490+
{
491+
name: 'a',
492+
sharp: false,
493+
flat: false,
494+
doubleFlat: false,
495+
doubleSharp: false,
496+
displayName: 'A'
497+
},
498+
{
499+
name: 'b',
500+
sharp: false,
501+
flat: false,
502+
doubleFlat: false,
503+
doubleSharp: false,
504+
displayName: 'B'
505+
},
506+
];
507+
449508
export const dDorianMode: ModeMap = [
450509
{
451510
name: 'd',
@@ -1209,3 +1268,81 @@ export const cIonianChordMap = [
12091268
type: ChordType.diminished,
12101269
},
12111270
]
1271+
1272+
export const cIonianSimilarModes = [
1273+
{
1274+
noteDisplayName: 'D',
1275+
note: 'd',
1276+
mode: 'dorian',
1277+
noteExtender: 'natural'
1278+
},
1279+
{
1280+
noteDisplayName: 'E',
1281+
note: 'e',
1282+
mode: 'phrygian',
1283+
noteExtender: 'natural'
1284+
},
1285+
{
1286+
noteDisplayName: 'F',
1287+
note: 'f',
1288+
mode: 'lydian',
1289+
noteExtender: 'natural'
1290+
},
1291+
{
1292+
noteDisplayName: 'G',
1293+
note: 'g',
1294+
mode: 'mixolydian',
1295+
noteExtender: 'natural'
1296+
},
1297+
{
1298+
noteDisplayName: 'A',
1299+
note: 'a',
1300+
mode: 'aolian',
1301+
noteExtender: 'natural'
1302+
},
1303+
{
1304+
noteDisplayName: 'B',
1305+
note: 'b',
1306+
mode: 'locrian',
1307+
noteExtender: 'natural'
1308+
}
1309+
]
1310+
1311+
export const cLydianSimilarModes = [
1312+
{
1313+
noteDisplayName: 'D',
1314+
note: 'd',
1315+
mode: 'mixolydian',
1316+
noteExtender: 'natural'
1317+
},
1318+
{
1319+
noteDisplayName: 'E',
1320+
note: 'e',
1321+
mode: 'aolian',
1322+
noteExtender: 'natural'
1323+
},
1324+
{
1325+
noteDisplayName: 'F',
1326+
note: 'f',
1327+
mode: 'locrian',
1328+
noteExtender: 'sharp'
1329+
},
1330+
{
1331+
noteDisplayName: 'G',
1332+
note: 'g',
1333+
mode: 'ionian',
1334+
noteExtender: 'natural'
1335+
},
1336+
{
1337+
noteDisplayName: 'A',
1338+
note: 'a',
1339+
mode: 'dorian',
1340+
noteExtender: 'natural'
1341+
},
1342+
{
1343+
noteDisplayName: 'B',
1344+
note: 'b',
1345+
mode: 'phrygian',
1346+
noteExtender: 'natural'
1347+
}
1348+
]

apps/fretonator-web/src/app/common/fret-map/fret-map.service.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ import {
88
ModeMap,
99
NoteExtenderString,
1010
NoteObject,
11-
NoteSymbol
11+
NoteSymbol,
12+
SimilarMode,
13+
SimilarModes
1214
} from '../../util/types';
1315
import {
1416
ChordPatterns,
1517
ModePatterns,
1618
ModeSelectorObjects,
1719
NoteToStringAndFretMap,
1820
Octave,
19-
ScaleDegrees
21+
ScaleDegrees,
22+
StandardModePatterns
2023
} from '../../util/constants';
2124
import { JamTracksData } from '../../data/jamTracks';
2225

@@ -257,7 +260,7 @@ export class FretMapService {
257260

258261
for (let i = 0; i < modePattern.length - 1; i++) {
259262
newNote = this.generateNextNote(currentNote, modePattern[i]);
260-
newNote.displayName = this.convertNoteObjectToHumanReadable(newNote)
263+
newNote.displayName = this.convertNoteObjectToHumanReadable(newNote);
261264

262265
newMode.push(newNote);
263266
currentNote = newNote;
@@ -408,6 +411,40 @@ export class FretMapService {
408411
note: this.convertNoteObjectToHumanReadable(noteObject),
409412
type: chordPattern[index]
410413
}));
414+
};
415+
416+
getNoteExtenderStringFromNoteObject = (noteObject: NoteObject): NoteExtenderString => {
417+
if (this.isSharp(noteObject, noteObject.name)) {
418+
return NoteExtenderString.sharp;
419+
}
420+
421+
if (this.isFlat(noteObject, noteObject.name)) {
422+
return NoteExtenderString.flat;
423+
}
424+
425+
if (this.isNatural(noteObject, noteObject.name)) {
426+
return NoteExtenderString.natural;
427+
}
428+
};
429+
430+
getSimilarModes = (modeMap: ModeMap, inputMode: Mode): SimilarModes => {
431+
const firstModeInPattern = StandardModePatterns.indexOf(inputMode);
432+
433+
if (firstModeInPattern === -1) {
434+
return [];
435+
}
436+
437+
const similarModes = modeMap
438+
.map((noteObject, index) => (
439+
{
440+
noteDisplayName: noteObject.displayName,
441+
note: noteObject.name,
442+
mode: StandardModePatterns[firstModeInPattern + index],
443+
noteExtender: this.getNoteExtenderStringFromNoteObject(noteObject)
444+
}
445+
));
411446

447+
similarModes.shift();
448+
return similarModes;
412449
};
413450
}

apps/fretonator-web/src/app/common/fretonator/fretonator.component.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
</ng-template>
1717

1818
<div class="fretboard__toggle">
19-
<button class="fretboard__toggleButton fretboard__toggleButton--left"
19+
<button class="fretboard__toggleButton fretboard__toggleButton--twelve"
2020
[class.fretboard__toggleButton--active]="fretMode === fretModes.twelve"
2121
(click)="setFretMode(fretModes.twelve)">12 frets
2222
</button>
23-
<button class="fretboard__toggleButton fretboard__toggleButton--right"
23+
<button class="fretboard__toggleButton fretboard__toggleButton--twentyFour"
2424
[class.fretboard__toggleButton--active]="fretMode === fretModes.twentyFour"
2525
(click)="setFretMode(fretModes.twentyFour)">24 frets
2626
</button>
@@ -85,4 +85,10 @@ <h4 class="fretonator__playCta">
8585
<app-interval-map [intervalMap]="intervalMap"></app-interval-map>
8686

8787
<app-chord-map [chordMap]="chordMap"></app-chord-map>
88+
89+
<app-similar-modes [modeDisplayString]="modeDisplayString"
90+
[similarModes]="modeMap | getSimilarModes : mode">
91+
92+
</app-similar-modes>
93+
8894
</div>

apps/fretonator-web/src/app/common/fretonator/fretonator.component.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,13 @@
369369
color: var(--offwhite);
370370
}
371371

372-
.fretboard__toggleButton--left {
372+
.fretboard__toggleButton--twelve {
373373
border-top-right-radius: 0;
374374
border-bottom-right-radius: 0;
375375
border-right-width: calc(var(--border-width-button) / 2);
376376
}
377377

378-
.fretboard__toggleButton--right {
378+
.fretboard__toggleButton--twentyFour {
379379
border-top-left-radius: 0;
380380
border-bottom-left-radius: 0;
381381
border-left-width: calc(var(--border-width-button) / 2);

apps/fretonator-web/src/app/common/fretonator/fretonator.component.spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
22

33
import { FretonatorComponent } from './fretonator.component';
44
import { FretonatorModule } from './fretonator.module';
5-
import { Component } from '@angular/core';
5+
import { Component, DebugElement } from '@angular/core';
6+
import { By } from '@angular/platform-browser';
67

78
describe('FretonatorComponent', () => {
9+
10+
const selectors = {
11+
twelveButton: By.css('.fretboard__toggleButton--twelve'),
12+
twentyFourButton: By.css('.fretboard__toggleButton--twentyFour')
13+
}
14+
15+
const classNames = {
16+
toggleFretButtonSelected: 'fretboard__toggleButton--active'
17+
}
18+
819
@Component({
920
selector: 'app-fretonator-spec',
1021
template: `
@@ -44,4 +55,26 @@ describe('FretonatorComponent', () => {
4455
it('should create', () => {
4556
expect(component).toBeTruthy();
4657
});
58+
59+
describe('setFretMode()', () => {
60+
let twelveButton: DebugElement;
61+
let twentyFourButton: DebugElement;
62+
63+
beforeEach(() => {
64+
twelveButton = fixture.debugElement.query(selectors.twelveButton);
65+
twentyFourButton = fixture.debugElement.query(selectors.twentyFourButton);
66+
});
67+
68+
it('changes the fret mode to twenty four when the button is clicked', () => {
69+
twentyFourButton.nativeElement.click();
70+
fixture.detectChanges();
71+
expect(twentyFourButton.classes[classNames.toggleFretButtonSelected]).toBeTruthy();
72+
});
73+
74+
it('changes the fret mode to twelve when the button is clicked', () => {
75+
twelveButton.nativeElement.click();
76+
fixture.detectChanges();
77+
expect(twelveButton.classes[classNames.toggleFretButtonSelected]).toBeTruthy();
78+
});
79+
});
4780
});

0 commit comments

Comments
 (0)