diff --git a/src/app/modules/songs/services/key.helper.ts b/src/app/modules/songs/services/key.helper.ts index 18708ee..e89b3d5 100644 --- a/src/app/modules/songs/services/key.helper.ts +++ b/src/app/modules/songs/services/key.helper.ts @@ -1,7 +1,8 @@ export const KEYS = [ - 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'F', 'F#', 'Gb', 'G', 'G#', 'Ab', 'A', 'A#', 'B', 'H', - 'c', 'c#', 'db', 'd', 'd#', 'eb', 'e', 'f', 'f#', 'gb', 'g', 'g#', 'ab', 'a', 'a#', 'b', 'h' + 'C#', 'C', 'Db', 'D#', 'D', 'Eb', 'E', 'F#', 'F', 'Gb', 'G#', 'G', 'Ab', 'A#', 'A', 'B', 'H', + 'c#', 'c', 'db', 'd#', 'd', 'eb', 'e', 'f#', 'f', 'gb', 'g#', 'g', 'ab', 'a#', 'a', 'b', 'h' ]; +export const KEYS_REGEX = new RegExp('(' + KEYS.reduce((a, b) => a + '|' + b) + ')', 'gm'); export const KEYS_MAJOR_FLAT = [ 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'H', ]; diff --git a/src/app/modules/songs/services/song-data.service.ts b/src/app/modules/songs/services/song-data.service.ts index a8e7355..1b30a52 100644 --- a/src/app/modules/songs/services/song-data.service.ts +++ b/src/app/modules/songs/services/song-data.service.ts @@ -12,6 +12,6 @@ export class SongDataService { public list$ = (): Observable => this.dbService.col$('songs'); public read$ = (songId: string): Observable => this.dbService.doc$('songs/' + songId); - public update = async (songId: string, data: any): Promise => await this.dbService.doc(songId).update(data); + public update = async (songId: string, data: any): Promise => await this.dbService.doc('songs/' + songId).update(data); } diff --git a/src/app/modules/songs/services/text-rendering.service.spec.ts b/src/app/modules/songs/services/text-rendering.service.spec.ts index 7f252fe..de4216a 100644 --- a/src/app/modules/songs/services/text-rendering.service.spec.ts +++ b/src/app/modules/songs/services/text-rendering.service.spec.ts @@ -16,7 +16,7 @@ Text Line 1-2 Text Line 2-2 Refrain -c# cb c7 cmaj7 c/e +c c# db c7 cmaj7 c/e and the chorus Bridge @@ -69,6 +69,17 @@ Cool bridge without any chords expect(sections[1].lines[2].type).toBe(LineType.chord); expect(sections[1].lines[2].text).toBe(' a d e f g a h c b'); expect(sections[2].lines[0].type).toBe(LineType.chord); - expect(sections[2].lines[0].text).toBe('c# cb c7 cmaj7 c/e'); + expect(sections[2].lines[0].text).toBe('c c# db c7 cmaj7 c/e'); + + // c c# db c7 cmaj7 c/e + console.log(sections[2].lines[0].chords); + expect(sections[2].lines[0].chords).toEqual([ + {chord: 'c', length: 2, position: 0}, + {chord: 'c#', length: 3, position: 2}, + {chord: 'db', length: 3, position: 5}, + {chord: 'c', length: 2, position: 8, add: '7'}, + {chord: 'c', length: 5, position: 13, add: 'maj7'}, + {chord: 'c', length: 3, position: 22, slashChord: 'e'}, + ]); }); }); diff --git a/src/app/modules/songs/services/text-rendering.service.ts b/src/app/modules/songs/services/text-rendering.service.ts index 1b9cd25..18e170e 100644 --- a/src/app/modules/songs/services/text-rendering.service.ts +++ b/src/app/modules/songs/services/text-rendering.service.ts @@ -11,9 +11,18 @@ export enum LineType { text, } +export interface Chord { + chord: string; + length: number; + position: number; + slashChord?: string; + add?: string; +} + export interface Line { type: LineType; text: string; + chords?: Chord[] } export interface Section { @@ -27,8 +36,8 @@ export interface Section { }) export class TextRenderingService { + private regexSection = /(Strophe|Refrain|Bridge)/; - private regexChords = /\b([CDEFGAHBcdefgahb](#|##|b|bb|sus|maj|maj7|min|aug|\d+|\/[CDEFGAHBcdefgahb])?\b)/; constructor() { } @@ -47,9 +56,13 @@ export class TextRenderingService { } private getLineOfLineText(text: string): Line { - const matches = !!text.match(this.regexChords); - const type = matches ? LineType.chord : LineType.text; - return {type, text} + const regex = /\b(C#|C|Db|D#|D|Eb|E|F#|F|Gb|G#|G|Ab|A#|A|B|H|c#|c|db|d#|d|eb|e|f#|f|gb|g#|g|ab|a#|a|b|h)(\/(C#|C|Db|D#|D|Eb|E|F#|F|Gb|G#|G|Ab|A#|A|B|H|c#|c|db|d#|d|eb|e|f#|f|gb|g#|g|ab|a#|a|b|h))?(\d+|maj7)?.?\b/mg; + + const match = text.match(regex); + const hasMatches = !!match; + const type = hasMatches ? LineType.chord : LineType.text; + + return {type, text, chords: hasMatches ? this.readChords(text) : undefined} } private getSectionTypeOfLine(line: string): SectionType { @@ -64,4 +77,24 @@ export class TextRenderingService { } } + private readChords(chordLine: string): Chord[] { + let match; + const chords: Chord[] = []; + + const regex = /\b(C#|C|Db|D#|D|Eb|E|F#|F|Gb|G#|G|Ab|A#|A|B|H|c#|c|db|d#|d|eb|e|f#|f|gb|g#|g|ab|a#|a|b|h)(\/(C#|C|Db|D#|D|Eb|E|F#|F|Gb|G#|G|Ab|A#|A|B|H|c#|c|db|d#|d|eb|e|f#|f|gb|g#|g|ab|a#|a|b|h))?(\d+|maj7)?.?\b/mg; + + while ((match = regex.exec(chordLine)) !== null) { + const chord: Chord = { + chord: match[1], + length: match[0].length, + position: regex.lastIndex - match[0].length, + }; + if (match[3]) chord.slashChord = match[3]; + if (match[4]) chord.add = match[4]; + + chords.push(chord); + } + return chords; + } + } diff --git a/src/app/widget-modules/components/card/card.component.less b/src/app/widget-modules/components/card/card.component.less index 9da63c9..8f355e9 100644 --- a/src/app/widget-modules/components/card/card.component.less +++ b/src/app/widget-modules/components/card/card.component.less @@ -7,6 +7,7 @@ background: #fffe; overflow: hidden; width: 800px; + transition: 3s all ease-in-out; @media screen and (max-width: 860px) { width: 100vw; border-radius: 0px;