Skip to content

Commit

Permalink
Add notes selector (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrilgourgouillon committed Dec 1, 2023
1 parent 6c9a382 commit 6d13f18
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 17 deletions.
20 changes: 13 additions & 7 deletions src/components/AutoSkipper.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { ButtonGroup, IconButton, useToast } from "@chakra-ui/react";
import { Speed, speeds } from "../config";
import { getSpeedColor, getSpeedIcon } from "../services";
import { useSpeedContext } from "../hooks";
import { AbsoluteCenter, Box, ButtonGroup, Divider, IconButton, useToast } from '@chakra-ui/react';
import { Speed, speeds } from '../config';
import { getSpeedColor, getSpeedIcon } from '../services';
import { useSpeedContext } from '../hooks';

export const AutoSkipper = () => {
const toast = useToast();
const {speed, setCurrentSpeed} = useSpeedContext();
const { speed, setCurrentSpeed } = useSpeedContext();

const triggerToast = (skipDuration: Speed) => {
toast({
title: `Auto skip every ${skipDuration / 1000}"`,
status: "info",
status: 'info',
duration: 1000,
});
};

return (
<>
<Box position="relative" padding="2">
<Divider />
<AbsoluteCenter bg="white" px="4">
Auto skipper
</AbsoluteCenter>
</Box>
<ButtonGroup isAttached className="flex justify-center">
{speeds.map((s, i) => (
<IconButton
Expand All @@ -31,7 +37,7 @@ export const AutoSkipper = () => {
setCurrentSpeed(s);
}
}}
variant={"outline"}
variant={'outline'}
isActive={speed === s}
colorScheme={getSpeedColor(s)}
/>
Expand Down
52 changes: 52 additions & 0 deletions src/components/NoteSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { AbsoluteCenter, Box, Button, Divider } from '@chakra-ui/react';
import { Note, notes as allNotes } from '../config';
import { useNoteSettingsContext } from '../hooks';

export const NoteSelector = () => {
const { availableNotes, setAvailableNotes } = useNoteSettingsContext();

const handleRemoveNote = (note: Note) => {
console.log('remove');
setAvailableNotes(availableNotes.filter((n) => n !== note));
};

const handleAddNote = (note: Note) => {
console.log('add');
setAvailableNotes([note, ...availableNotes]);
};

return (
<>
<Box position="relative" padding="2">
<Divider />
<AbsoluteCenter bg="white" px="4">
Notes selector
</AbsoluteCenter>
</Box>
<div className="flex flex-row flex-wrap justify-center gap-1">
{allNotes.map((note) => {
const noteIsActive = availableNotes.includes(note);
return (
<Button
key={note}
variant="outline"
width={'10px'}
size="sm"
isActive={noteIsActive}
colorScheme={noteIsActive ? 'green' : 'gray'}
onClick={() => {
if (noteIsActive) {
handleRemoveNote(note);
} else {
handleAddNote(note);
}
}}
>
{note}
</Button>
);
})}
</div>
</>
);
};
10 changes: 6 additions & 4 deletions src/components/NotesSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { MdBuild } from 'react-icons/md';
import { NOTES_LIST_MIN, NOTES_LIST_MAX } from '../config/constants';
import { AutoSkipper } from './AutoSkipper';
import { useNoteSettingsContext } from '../hooks';
import { NoteSelector } from '.';

export const NotesSettings = () => {
const { numberOfNoteDisplayed, getRandomNotesOnClick, changeNumberOfNoteDisplayed, toggleStringVisible } =
Expand All @@ -25,18 +26,18 @@ export const NotesSettings = () => {
Settings
</IconButton>
</PopoverTrigger>
<PopoverContent>
<PopoverContent width={'350px'}>
<PopoverArrow />
<PopoverBody>
<div className="flex flex-col gap-3 items-stretch">
<ButtonGroup variant="outline">
<div className="flex flex-col gap-3 items-stretch w-full">
<ButtonGroup variant='outline' className="flex flex-row items-stretch justify-stretch">
<IconButton
aria-label="minus"
icon={<FaMinus />}
onClick={() => changeNumberOfNoteDisplayed(-1)}
disabled={numberOfNoteDisplayed === NOTES_LIST_MIN}
/>
<Button onClick={getRandomNotesOnClick}>Generate list of {numberOfNoteDisplayed} notes</Button>
<Button className='flex-grow' onClick={getRandomNotesOnClick}>Generate list of {numberOfNoteDisplayed} notes</Button>
<IconButton
aria-label="plus"
icon={<FaPlus />}
Expand All @@ -47,6 +48,7 @@ export const NotesSettings = () => {
<Button variant="outline" leftIcon={<MdBuild />} onClick={toggleStringVisible}>
Toggle string complexity
</Button>
<NoteSelector />
<AutoSkipper />
</div>
</PopoverBody>
Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './AutoSkipper';
export * from './NotesSettings'
export * from './ChordsSettings';
export * from './TimerCue';
export * from './NoteSelector';
17 changes: 11 additions & 6 deletions src/contexts/NoteContext.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { createContext, useCallback, useEffect, useState } from "react";
import { Dispatch, SetStateAction, createContext, useCallback, useEffect, useState } from "react";
import { DEFAULT_NUMBER_OF_NOTE } from "../config/constants";
import {
getListOfRandomNotes,
getListOfRandomNotesOf,
getRandomString,
isValidNoteCountList,
} from "../services";
import { GuitarString, Note } from "../config";
import { GuitarString, Note, notes as allNotes } from "../config";
import { useSpeedContext } from "../hooks";

interface NoteSettingsContextProps {
notes: Note[];
availableNotes: Note[],
setAvailableNotes: Dispatch<SetStateAction<Note[]>>
numberOfNoteDisplayed: number;
isStringVisible: boolean;
guitarString: GuitarString;
Expand All @@ -27,8 +29,9 @@ export const NoteSettingsContextProvider = ({
}: {
children: React.ReactNode;
}) => {
const [availableNotes, setAvailableNotes] = useState<Note[]>([...allNotes]);
const [notes, setNotes] = useState<Note[]>(
getListOfRandomNotes(DEFAULT_NUMBER_OF_NOTE)
getListOfRandomNotesOf(availableNotes, DEFAULT_NUMBER_OF_NOTE)
);
const [numberOfNoteDisplayed, setNumberOfNoteDisplayed] = useState(
DEFAULT_NUMBER_OF_NOTE
Expand All @@ -55,9 +58,9 @@ export const NoteSettingsContextProvider = ({
};

const getRandomNotesOnClick = useCallback(() => {
setNotes(getListOfRandomNotes(numberOfNoteDisplayed));
setNotes(getListOfRandomNotesOf(availableNotes, numberOfNoteDisplayed));
setGuitarString(getRandomString());
}, [numberOfNoteDisplayed]);
}, [availableNotes, numberOfNoteDisplayed]);

useEffect(() => {
if (speed && speed / 1000 === secondsElapsed) {
Expand All @@ -75,6 +78,8 @@ export const NoteSettingsContextProvider = ({
<NoteSettingsContext.Provider
value={{
notes,
availableNotes,
setAvailableNotes,
numberOfNoteDisplayed,
isStringVisible,
guitarString,
Expand Down
6 changes: 6 additions & 0 deletions src/services/noteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export const getListOfRandomNotes = (count: number): Note[] => {
return randomNotes.slice(undefined, count);
};

export const getListOfRandomNotesOf = (allNotes: Note[], count: number): Note[] => {
const randomNotes = shuffle(allNotes);

return randomNotes.slice(undefined, count);
};

export const isValidNoteCountList = (count: number): boolean => {
return count >= NOTES_LIST_MIN && count <= NOTES_LIST_MAX
}
Expand Down

0 comments on commit 6d13f18

Please sign in to comment.