moved models and utils variables/types into models/Piano.ts to fix recursive include and now handling Notes with PianoKey type

This commit is contained in:
Clément Le Bihan
2023-03-18 00:12:37 +01:00
parent 7bf8f32805
commit 319295d2e5
4 changed files with 91 additions and 44 deletions

View File

@@ -16,6 +16,7 @@ import { Center } from 'native-base';
import LoadingComponent from './components/Loading';
import ProfileView from './views/ProfileView';
import useColorScheme from './hooks/colorScheme';
import VirtualPiano from './components/VirtualPiano/VirtualPiano';
const Stack = createNativeStackNavigator();
@@ -41,6 +42,8 @@ export const Router = () => {
});
const colorScheme = useColorScheme();
return <VirtualPiano />
return (
<NavigationContainer theme={colorScheme == 'light'
? DefaultTheme

View File

@@ -1,12 +1,34 @@
import { Note } from "./VirtualPiano";
import {
Note,
PianoKey,
NoteNameBehavior,
octaveKeys,
Accidental,
} from "../../models/Piano";
import { Box, Row, Pressable } from "native-base";
const notesList: Array<Note> = ["C", "D", "E", "F", "G", "A", "B"];
const accidentalsList: Array<Accidental> = ["#", "b", "##", "bb"];
const getKeyIndex = (k: PianoKey, keys: PianoKey[]) => {
for (let i = 0; i < keys.length; i++) {
if (
keys[i]?.note === k.note &&
((keys[i]?.accidental && keys[i]?.accidental === k.accidental) ||
(!keys[i]?.accidental && !k.accidental))
) {
return i;
}
}
return -1;
};
type OctaveProps = {
number: number;
startNote: Note;
endNote: Note;
onNoteDown: (note: Note) => void;
onNoteUp: (note: Note) => void;
startNote: PianoKey;
endNote: PianoKey;
onNoteDown: (note: PianoKey) => void;
onNoteUp: (note: PianoKey) => void;
};
const Octave = ({
@@ -16,28 +38,31 @@ const Octave = ({
onNoteDown,
onNoteUp,
}: OctaveProps) => {
const notesList: Array<Note> = ["C", "D", "E", "F", "G", "A", "B"];
const startNoteIndex = notesList.indexOf(startNote);
const endNoteIndex = notesList.indexOf(endNote);
const whiteKeys = notesList.slice(startNoteIndex, endNoteIndex + 1);
const oK: PianoKey[] = octaveKeys.map((k) => {
return { ...k, number: number };
});
const startNoteIndex = getKeyIndex(startNote, oK);
const endNoteIndex = getKeyIndex(endNote, oK);
const keys = oK.slice(startNoteIndex, endNoteIndex + 1);
return (
<Row>
{whiteKeys.map((note) => {
{keys.map((key, i) => {
return (
<Pressable
onPressIn={() => onNoteDown(note + number)}
onPressOut={() => onNoteUp(note + number)}
onPressIn={() => onNoteDown(key)}
onPressOut={() => onNoteUp(key)}
>
<Box
key={note}
key={i}
bg="white"
w="50px"
h="200px"
borderWidth="1px"
borderColor="black"
>
{note}
{key.toString()}
</Box>
</Pressable>
);

View File

@@ -1,30 +1,19 @@
import { Row, Box } from "native-base";
import React, { useState, useEffect } from "react";
import Octave from "./Octave";
export type Note = "C" | "D" | "E" | "F" | "G" | "A" | "B";
export type Accidental = "#" | "b" | "##" | "bb";
export type NoteValue = {
note: Note;
accidental?: Accidental;
octave?: number;
};
export type NoteNameBehavior = "always" | "onpress" | "onhighlight" | "never";
export type KeyPressStyle = "subtle" | "vivid";
import { Note, PianoKey, NoteNameBehavior, KeyPressStyle, octaveKeys } from "../../models/Piano";
type VirtualPianoProps = Parameters<typeof Row>[0] & {
onNoteDown: (note: Note) => void;
onNoteUp: (note: Note) => void;
onNoteDown: (note: PianoKey) => void;
onNoteUp: (note: PianoKey) => void;
startOctave: number;
startNote: Note;
startNote: PianoKey;
endOctave: number;
endNote: Note;
endNote: PianoKey;
showNoteNames: NoteNameBehavior; // default "onpress"
highlightedNotes: Array<NoteValue | string>;
highlightedNotes: Array<PianoKey | string>;
highlightColor: string;
specialHighlightedNotes: Array<NoteValue | string>;
specialHighlightedNotes: Array<PianoKey | string>;
specialHighlightColor: string;
showOctaveNumbers: boolean;
keyPressStyle: KeyPressStyle;
@@ -47,20 +36,12 @@ const VirtualPiano = ({
keyPressStyle,
vividKeyPressColor,
}: VirtualPianoProps) => {
const notesList: Array<Note> = ["C", "D", "E", "F", "G", "A", "B"];
const nbOctaves = endOctave - startOctave;
const nbWhiteKeys =
notesList.length * (endOctave - startOctave) -
notesList.indexOf(startNote) -
(notesList.length - notesList.indexOf(endNote) + 1);
const octaveList = [];
for (let octaveNum = startOctave; octaveNum <= endOctave; octaveNum++) {
octaveList.push(octaveNum);
};
return (
<Row>
{octaveList.map((octaveNum) => {
@@ -68,8 +49,8 @@ const VirtualPiano = ({
<Octave
key={octaveNum}
number={octaveNum}
startNote={octaveNum == startOctave ? startNote : notesList[0]}
endNote={octaveNum == endOctave ? endNote : notesList[notesList.length - 1]}
startNote={octaveNum == startOctave ? startNote : octaveKeys[0]}
endNote={octaveNum == endOctave ? endNote : octaveKeys[octaveKeys.length - 1]}
onNoteDown={onNoteDown}
onNoteUp={onNoteUp}
/>
@@ -87,9 +68,9 @@ VirtualPiano.defaultProps = {
console.log("Note up: " + n);
},
startOctave: 2,
startNote: "C",
startNote: new PianoKey("C"),
endOctave: 6,
endNote: "C",
endNote: new PianoKey("C"),
showNoteNames: "onpress",
highlightedNotes: [],
highlightColor: "red",

38
front/models/Piano.ts Normal file
View File

@@ -0,0 +1,38 @@
export type Note = "C" | "D" | "E" | "F" | "G" | "A" | "B";
export type Accidental = "#" | "b" | "##" | "bb";
export type NoteNameBehavior = "always" | "onpress" | "onhighlight" | "never";
export type KeyPressStyle = "subtle" | "vivid";
export class PianoKey {
public note: Note;
public accidental?: Accidental;
public octave?: number;
constructor(note: Note, accidental?: Accidental, octave?: number) {
this.note = note;
this.accidental = accidental;
this.octave = octave;
};
public toString = () => {
return this.note + (this.accidental || "") + (this.octave || "");
}
};
export const octaveKeys: Array<PianoKey> = [
new PianoKey("C", undefined),
new PianoKey("C", "#"),
new PianoKey("D", undefined),
new PianoKey("D", "#"),
new PianoKey("E", undefined),
new PianoKey("F", undefined),
new PianoKey("F", "#"),
new PianoKey("G", undefined),
new PianoKey("G", "#"),
new PianoKey("A", undefined),
new PianoKey("A", "#"),
new PianoKey("B", undefined),
];