Skip to content

Commit

Permalink
New functions for practice mode
Browse files Browse the repository at this point in the history
  • Loading branch information
lpatmo committed Sep 8, 2023
1 parent 2e57fc1 commit f599354
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/Instruments.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import InputLabel from '@mui/material/InputLabel';
import NativeSelect from '@mui/material/NativeSelect';

export default function Instruments({instrument, setInstrument}) {
return (<>
<InputLabel variant="standard" htmlFor="instrument">
Instrument
</InputLabel>
<NativeSelect
defaultValue={instrument}
inputProps={{
name: 'instrument',
id: 'instrument',
}}
onChange={(e) => setInstrument(e.target.value)}
sx={{ fontSize: '1.6rem', mr: '2em' }}
>
<option value="acoustic_grand_piano">Piano</option>
<option value="choir_aahs">Choir</option>
<option value="flute">Flute</option>
<option value="french_horn">French Horn</option>
<option value="acoustic_guitar_steel">Guitar</option>
<option value="violin">Violin</option>
<option value="bird_tweet">Bird Tweet</option>
</NativeSelect></>)
}
9 changes: 9 additions & 0 deletions src/helpers/isNote.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Check if the provided string is a note
* @params {str} str
* @return boolean
*/
export default function isNote(str) {
//console.log('isNote str', str)
return str.length <= 2 && "abcdefg".includes(str[0].toLowerCase());
}
102 changes: 102 additions & 0 deletions src/routes/Practice.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { useState, useCallback, useEffect } from 'react';
import Navbar from '../Navbar';
import VolumeContext from '../contexts/VolumeContext'
import PianoNew from '../PianoNew'
import isNote from '../helpers/isNote'
import getNote from '../helpers/getNote'
import { playNote } from "../helpers/playMusic";
import Instruments from '../Instruments'
import Grid from '@mui/material/Grid';
import styles from './Practice.module.css'


export default function Practice() {
const [volume, setVolume] = useState(3);
const [gameOver, setGameOver] = useState(false);
const [instrument, setInstrument] = useState('acoustic_grand_piano')
const [octave, setOctave] = useState(4);
const [error, setError] = useState(null);
const [hasFlats, setHasFlats] = useState(false);
const answer = { sequence: [`D${octave}`] }

function handlePianoPress(note) {
console.log('note', note)
handleKeyDown({ key: note });
}

function handleSubmit() {
console.log('submitting...')
}

const handleKeyDown = useCallback(
(event) => {
switch (true) {
case gameOver:
/*Do not accept user input if game is over */
break;
case isNote(event.key):
/*Update guess state after valid note*/
let note = getNote(event, answer?.hasFlats);
console.log("note", note)
if (note[1] === "b") {
note = note[0].toUpperCase() + note[1];
} else {
note = note.toUpperCase();
}

/*Play the note in the same octave as the corresponding answer*/
playNote(instrument, note, answer, 0, volume);
//setError("");
break;
case event.key === "Enter":
handleSubmit(event);
break;
case RegExp("^[a-zA-Z0-9]$").test(event.key):
setError(`${event.key.toUpperCase()} is not a valid note.`);
break;
default:
break;
}
},
[answer, gameOver, handleSubmit, volume, instrument]
);

useEffect(() => {
//listen to keyboard events
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [handleSubmit, handleKeyDown]);

return (
<>
<VolumeContext.Provider value={volume}>
<Navbar showCountdown={false} isPracticing={true} />
<PianoNew handlePianoPress={handlePianoPress} octave={octave} hasFlats={hasFlats} className={styles.keyboard} setOctave={setOctave} />
<Grid container spacing={1} justifyContent="center">
<Grid item xl={4} lg={5} md={7} className={styles.right}>
<Instruments instrument={instrument} setInstrument={setInstrument} />
{/* <InputLabel variant="standard" htmlFor="difficulty">
Key
</InputLabel>
<NativeSelect
defaultValue="C major"
inputProps={{
name: 'key',
id: 'key',
}}
onChange={(e) => setKey(e.target.value)}
sx={{ fontSize: '1.6rem' }}
>
<option value="c_major">C major</option>
<option value="d_major">D major</option>
</NativeSelect> */}
</Grid>
</Grid>
<Grid container sx={{ mt: 5 }} spacing={1} justifyContent="center">
<button type="button" className={styles.action}>Start Game</button>
</Grid>
</VolumeContext.Provider>
</>

)
}
3 changes: 3 additions & 0 deletions src/routes/Practice.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.keyboard {
margin-top: 3em;
}

0 comments on commit f599354

Please sign in to comment.