Skip to content

Commit ca0d42e

Browse files
author
Joshua Kifer
committed
Finishing touches
1 parent a6eb725 commit ca0d42e

File tree

7 files changed

+70
-34
lines changed

7 files changed

+70
-34
lines changed

README.md

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
1-
# ElasticSuite
1+
# React MIDI Player
22

3-
## Candidate Evaluation Project.
3+
This project demonstrates a simple MIDI player. MIDI files when added are saved to Local Storage. Sample MIDI files can be found at [midiworld.com](http://www.midiworld.com/).
44

5-
### A Music Player
5+
---
66

77
Requirements:
88

99
- [x] Add music button, opens add music form
1010
- [x] Add music form, title, artist, album, file
1111
- [x] Queue list, displays title, artist, album
1212
- [x] Double-clicking in queue list plays selected song
13-
- [ ] When a song finishes playing, play next song in queue
14-
- [ ] Player status: current song title, artist, album, time elapsed, duration
15-
- [ ] Player interface: play, stop, previous, next, scrubber bar, should all actually function.
13+
- [x] When a song finishes playing, play next song in queue
14+
- [x] Player status: current song title, artist, album, time elapsed, duration
15+
- [x] Player interface: play, stop, previous, next, scrubber bar, should all actually function.
1616

17-
Extra Credit:
17+
Extra:
1818

1919
- [x] Actually playing audio. If not playing audio, just stub out file upload, playing, etc. Make each song just a two minute timer.
20-
- [ ] Simple UI theme in CSS.
20+
- [x] Simple UI theme in CSS.
2121
- [x] Persistence in local storage.
2222

2323
---
2424

25+
### Install
26+
27+
* Make sure yarn is available: `brew install yarn`
28+
* Install dependencies: `yarn`
29+
* Start the project: `yarn start`
30+
* Browse to the reported URL.
31+

components/Editor.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'react'
22
import { Form } from 'semantic-ui-react'
33

4-
export default ({ track, onFieldChange }) => (
5-
<Form inverted>
4+
export default ({ inverted, track, onFieldChange }) => (
5+
<Form inverted={inverted}>
66
<Form.Field>
77
<label>Title</label>
88
<input

components/Library.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'react'
22
import { Icon, List } from 'semantic-ui-react'
33

4-
export default ({ list, playing, onClickTrack, onDoubleClickTrack, onDeleteTrack }) => (
5-
<List divided inverted selection>
4+
export default ({ inverted, list, playing, onClickTrack, onDoubleClickTrack, onDeleteTrack }) => (
5+
<List divided inverted={inverted} selection>
66
{Object.values(list).map(track => (
77
<List.Item
88
key={track.id}

components/Loader.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function loadFile (file, then) {
1818
reader.readAsDataURL(file)
1919
}
2020

21-
export default ({ onTrackLoaded }) => (
21+
export default ({ inverted, onTrackLoaded }) => (
2222
<div>
2323
<input multiple
2424
style={{ display: 'none' }}
@@ -29,6 +29,6 @@ export default ({ onTrackLoaded }) => (
2929
}
3030
}}
3131
/>
32-
<Button inverted onClick={event => event.target.previousSibling.click()}>Add Files</Button>
32+
<Button inverted={inverted} onClick={event => event.target.previousSibling.click()}>Add Files</Button>
3333
</div>
3434
)

components/Main.js

+29-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22
import { playerFromMIDIBuffer } from 'hackmidi'
3-
import { Divider, Grid, Segment } from 'semantic-ui-react'
3+
import { Divider, Grid, Icon, Segment } from 'semantic-ui-react'
44

55
import Player from './Player'
66
import Editor from './Editor'
@@ -19,9 +19,10 @@ export default class Main extends React.Component {
1919
activity: {
2020
track: null,
2121
playing: false,
22-
duration: 0,
23-
position: 0
24-
}
22+
duration: 0.01,
23+
position: 0.00000001
24+
},
25+
inverted: true
2526
})
2627
this.player = null
2728
}
@@ -35,8 +36,8 @@ export default class Main extends React.Component {
3536
activity: {
3637
track: null,
3738
playing: false,
38-
duration: 0,
39-
position: 0
39+
duration: 0.01,
40+
position: 0.00000001
4041
}
4142
})
4243
}
@@ -46,7 +47,6 @@ export default class Main extends React.Component {
4647
activity.playing = playing
4748
this.setState({ activity })
4849
if (position === activity.duration) this.playOffset(1)
49-
console.log(activity)
5050
}
5151
componentDidUpdate () {
5252
// console.log(this.state.activity)
@@ -141,8 +141,8 @@ export default class Main extends React.Component {
141141
}
142142
return (
143143
<div style={style}>
144-
<Segment inverted>
145-
<Grid columns='two' stackable>
144+
<Segment inverted={this.state.inverted}>
145+
<Grid columns='2' stackable>
146146
<Grid.Row>
147147
<Grid.Column>
148148
<Player
@@ -155,15 +155,28 @@ export default class Main extends React.Component {
155155
/>
156156
</Grid.Column>
157157
<Grid.Column verticalAlign='bottom' textAlign='right'>
158-
<Loader onTrackLoaded={track => this.addTrack(track)} />
158+
<div style={{ marginBottom: '3.8em' }}>
159+
{this.state.inverted
160+
? <span>
161+
Dark&nbsp;&nbsp;
162+
<Icon name='toggle on' onClick={() => this.setState({inverted: false})} />
163+
</span>
164+
: <span>
165+
Light&nbsp;&nbsp;
166+
<Icon name='toggle off' onClick={() => this.setState({inverted: true})} />
167+
</span>
168+
}
169+
</div>
170+
<Loader onTrackLoaded={track => this.addTrack(track)} inverted={this.state.inverted} />
159171
</Grid.Column>
160172
</Grid.Row>
161173
</Grid>
162174
<Divider />
163-
<Grid columns='two' stackable>
175+
<Grid columns='2' stackable>
164176
<Grid.Row>
165177
<Grid.Column>
166178
<Library
179+
inverted={this.state.inverted}
167180
list={this.state.library}
168181
playing={this.state.activity.track}
169182
onClickTrack={track => this.selectTrack(track)}
@@ -173,7 +186,11 @@ export default class Main extends React.Component {
173186
</Grid.Column>
174187
<Grid.Column>
175188
{this.state.selected &&
176-
<Editor track={this.state.selected} onFieldChange={data => this.updateSelected(data)} />}
189+
<Editor
190+
inverted={this.state.inverted}
191+
track={this.state.selected}
192+
onFieldChange={data => this.updateSelected(data)}
193+
/>}
177194
</Grid.Column>
178195
</Grid.Row>
179196
</Grid>

components/Player.js

+11-8
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,26 @@ import { secondsToMinutes } from '../lib/time'
88
export default ({ activity, onPlay, onPause, onPrevious, onNext, onSeek }) => (
99
<div>
1010
<div style={{ textAlign: 'center', paddingBottom: '.2em' }}>
11-
{activity.track ? <span>{activity.track.title}</span> : <span>&nbsp;</span>}
11+
{activity.track
12+
? <span>
13+
{activity.track.artist ? activity.track.artist + ' - ' : ''}
14+
{activity.track.title}
15+
{activity.track.album ? ' - ' + activity.track.album : ''}
16+
</span> : <span>&nbsp;</span>}
1217
</div>
13-
<div style={{ }}>
14-
<div style={{ float: 'left', marginTop: '1.15em', marginRight: '2em'}}>
18+
<div>
19+
<div style={{ float: 'left', marginTop: '1.15em', marginRight: '1.5em' }}>
1520
{secondsToMinutes(activity.position)}
1621
</div>
1722
<Slider
1823
min={0}
1924
max={activity.duration}
2025
value={activity.position}
2126
format={secondsToMinutes}
22-
// onChangeStart={this.handleChangeStart}
2327
onChange={onSeek}
24-
// onChangeComplete={this.handleChangeComplete}
25-
/>
26-
<div style={{ float: 'left', marginTop: '1.15em', marginLeft: '1em'}}>
27-
{secondsToMinutes(activity.duration)}
28+
/>
29+
<div style={{ float: 'left', marginTop: '1.15em', marginLeft: '1.4em' }}>
30+
{secondsToMinutes(activity.duration - activity.position)}
2831
</div>
2932
</div>
3033
<div style={{ clear: 'both', textAlign: 'center' }}>

index.html

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66
<title>Elastic MIDI Jukebox</title>
77
<!-- <script type='text/javascript' src='//www.midijs.net/lib/midi.js'></script> -->
88
<!-- <script type='text/javascript' src='midi.js'></script> -->
9+
<style>
10+
.rangeslider {
11+
float: left;
12+
width: 70%;
13+
}
14+
.rangeslider__handle {
15+
display: none !importan;
16+
}
17+
</style>
918
</head>
1019
<body>
1120
<main></main>

0 commit comments

Comments
 (0)