Skip to content

Commit

Permalink
Selection of individual notes
Browse files Browse the repository at this point in the history
  • Loading branch information
divanvisagie committed Jan 27, 2019
1 parent 8b760a8 commit a35faeb
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 27 deletions.
1 change: 0 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Settings from './container/Settings'
import GitHubForkRibbon from 'react-github-fork-ribbon'

import FocusNoteSelector from './container/FocusNoteSelector'
import ScaleView from './container/ScaleView'

const tuningMap = {
'Standard E' : ['E', 'A', 'D', 'G', 'B', 'E'],
Expand Down
9 changes: 9 additions & 0 deletions src/container/Fretboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,13 @@
overflow-y: hidden;
display: flex;
flex-direction: column;
}

.Fretboard-buttons {
right: 16px;
bottom: 17px;
padding: 16px 0 0 0;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
49 changes: 40 additions & 9 deletions src/container/Fretboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,20 @@ import MarkerBoard from '../presentational/MarkerBoard'
import GuitarString from '../presentational/GuitarString'

class Fretboard extends Component {
clearDisabled () {
return this.props.selectedNotes.length < 1
}

render () {
const {tuning, frets, onNoteClick, focusNote, scale} = this.props
const {
tuning,
frets,
onClearClick,
onNoteClick,
focusNote,
scale,
selectedNotes
} = this.props

return (
<div className="Fretboard">
Expand All @@ -20,31 +32,50 @@ class Fretboard extends Component {
<GuitarString rootNote={note}
frets={frets}
scale={scale}
onClick={onNoteClick}
onClick={n => onNoteClick(n, i)}
key={i}
string={i}
selectedNotes={selectedNotes}
focusNote={focusNote} />
)}
</div>
<MarkerBoard frets={frets}/>
<div className='Fretboard-buttons'>
<button
disabled={this.clearDisabled()}
className='button button-outline'
onClick={onClearClick}>
Clear Selected
</button>
</div>
</div>
)
}
}

const mapStateToProps = (state) => {
return {
tuning : state.tuning.value,
frets : state.frets,
focusNote: state.focusNote,
scale : state.scale
tuning : state.tuning.value,
frets : state.frets,
focusNote : state.focusNote,
scale : state.scale,
selectedNotes: state.selectedNotes
}
}
const mapDispatchToProps = (dispatch) => {
return {
onNoteClick (note) {
onNoteClick (note, string) {
dispatch({
type : 'SET_SELECTED_NOTE',
value: {
note,
string
}
})
},
onClearClick () {
dispatch({
type : 'SET_FOCUS_NOTE',
value: note
type: 'CLEAR_SELECTED_NOTES'
})
}
}
Expand Down
1 change: 0 additions & 1 deletion src/container/ScaleSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import {connect} from 'react-redux'
import React, {Fragment, Component} from 'react'

import Note, {notes} from '../core/Note'
import {scales, Scale} from '../core/Scale'

import './ScaleSelector.css'
Expand Down
1 change: 0 additions & 1 deletion src/container/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const Settings = ({handleFretsChange, frets}) =>
onChange={handleFretsChange}
value={frets}
margin="normal"
min={27}
min={12} />

const mapStateToProps = (state) => {
Expand Down
2 changes: 1 addition & 1 deletion src/container/TuningSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import './TuningSelector.css'

const TuningSelector = ({tuning, handleTuningChange, tuningOptions}) =>
<Fragment>
<div class="TuningSelector-label">Tuning</div>
<div className="TuningSelector-label">Tuning</div>
<select
value={tuning.name}
onChange={handleTuningChange}
Expand Down
2 changes: 0 additions & 2 deletions src/core/Scale.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict'

import Note from './Note'
import {flatten, reduce} from 'ramda'

Expand Down
1 change: 0 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'normalize.css'
import 'milligram'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

import reducers from './reducers/reducers'

Expand Down
4 changes: 3 additions & 1 deletion src/presentational/GuitarString.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class GuitarString extends Component {
}

render () {
const {onClick, focusNote, rootNote, scale} = this.props
const {onClick, focusNote, rootNote, scale, string, selectedNotes} = this.props
return (
<div className="GuitarString">
<NutView note={Note(rootNote)} />
Expand All @@ -49,6 +49,8 @@ class GuitarString extends Component {
onClick={onClick}
scale={scale}
focusNote={focusNote}
selectedNotes={selectedNotes}
string={string}
key={index + note.toString()}/>
)}
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/presentational/NoteView.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
background: #aef !important;
}

.highlight-selected-note {
background: salmon !important;
}

.note {
cursor: pointer;
font-size: 10pt;
Expand Down
20 changes: 16 additions & 4 deletions src/presentational/NoteView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ import React, {Component} from 'react'
import './NoteView.css'
import {Scale} from '../core/Scale'

function getClasses (note, focusNote, scale) {
function getClasses (note, focusNote, scale, string, selectedNotes) {
const noteString = note.toString()

let className = 'note'

if (string !== undefined && selectedNotes) {
const notesOnThisString = selectedNotes.filter(x => {
return x.string === string && x.note === note.toString()
})
if (notesOnThisString.length > 0) {

return `${className} highlight-selected-note`
}
}

if (noteString === focusNote) {
return `${className} highlight`
}
Expand All @@ -23,8 +33,8 @@ function getClasses (note, focusNote, scale) {
return className
}

const NoteDisplay = ({note, focusNote, onClick, scale}) => (
<div className={getClasses(note, focusNote, scale)}
const NoteDisplay = ({note, focusNote, onClick, scale, string, selectedNotes}) => (
<div className={getClasses(note, focusNote, scale, string, selectedNotes)}
onClick={onClick}>
{note.toString()}
</div>
Expand All @@ -44,7 +54,7 @@ export default class NoteView extends Component {
}

render () {
const { note, focusNote, scale } = this.props
const { note, focusNote, scale, string, selectedNotes } = this.props
return (
<div className='NoteView'>
<div className='note-area'>
Expand All @@ -53,6 +63,8 @@ export default class NoteView extends Component {
note={note}
scale={scale}
focusNote={focusNote}
string={string}
selectedNotes={selectedNotes}
onClick={this.handleClick}
/>
<div className='string'></div>
Expand Down
32 changes: 26 additions & 6 deletions src/reducers/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ function frets (state = loadedFrets, action) {
function focusNote (state = 'C', action) {
switch (action.type) {
case 'SET_FOCUS_NOTE':
if (state === action.value) {
state = ''
} else {
state = action.value
}
state = action.value
return state
default:
return state
Expand All @@ -48,11 +44,35 @@ function key (state = '', action) {
return state
}

function selectedNotes (state = [], action) {
switch (action.type) {
case 'SET_SELECTED_NOTE':
const {value} = action

const findExisting = (i) => {
return i.note === value.note && i.string === value.string
}

const existingIndex = state.findIndex(findExisting)

if (existingIndex < 0) {
return [...state, value]
} else {
return state.filter(i => !findExisting(i))
}
case 'CLEAR_SELECTED_NOTES':
return []
default:
return state
}
}

export default combineReducers({
focusNote,
frets,
key,
tuningOptions,
tuning,
scale
scale,
selectedNotes
})

0 comments on commit a35faeb

Please sign in to comment.