summaryrefslogtreecommitdiff
path: root/app/client
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-05-25 19:54:38 +0200
committerJules Laplace <julescarbon@gmail.com>2018-05-25 19:54:38 +0200
commit5a4de48a6d63cb383832f6ef85b21699a511b755 (patch)
tree4c4fd18d26f8b5c95a6788d138ed62869357c975 /app/client
parent1a99af129427275c22e8276e75fa4b8da6602129 (diff)
stubbing in a lot of stuff!
Diffstat (limited to 'app/client')
-rw-r--r--app/client/common/group.component.js10
-rw-r--r--app/client/common/header.component.js14
-rw-r--r--app/client/dashboard/actions.js1
-rw-r--r--app/client/dashboard/dashboard.component.js71
-rw-r--r--app/client/dashboard/dashboard.reducer.js16
-rw-r--r--app/client/dashboard/dashboardHeader.component.js39
-rw-r--r--app/client/dashboard/filelist.component.js46
-rw-r--r--app/client/dashboard/gallery.component.js33
-rw-r--r--app/client/dashboard/index.js2
-rw-r--r--app/client/dashboard/tasklist.component.js45
-rw-r--r--app/client/index.jsx8
-rw-r--r--app/client/live/actions.js21
-rw-r--r--app/client/live/player.js21
-rw-r--r--app/client/live/reducer.js28
-rw-r--r--app/client/pix2pix/index.js (renamed from app/client/live/index.js)8
-rw-r--r--app/client/socket.js9
-rw-r--r--app/client/store.js4
-rw-r--r--app/client/system/system.reducer.js106
-rw-r--r--app/client/types.js31
-rw-r--r--app/client/util.js6
20 files changed, 475 insertions, 44 deletions
diff --git a/app/client/common/group.component.js b/app/client/common/group.component.js
new file mode 100644
index 0000000..5dc9ddf
--- /dev/null
+++ b/app/client/common/group.component.js
@@ -0,0 +1,10 @@
+import { h, Component } from 'preact'
+
+export default function Group (props){
+ return (
+ <div className='group'>
+ <h3>{this.props.title}</h3>
+ {this.props.children}
+ </div>
+ )
+}
diff --git a/app/client/common/header.component.js b/app/client/common/header.component.js
index b5a484e..1e27856 100644
--- a/app/client/common/header.component.js
+++ b/app/client/common/header.component.js
@@ -1,10 +1,24 @@
import { h, Component } from 'preact'
+import { Link } from 'react-router-dom';
import { connect } from 'react-redux'
function Header(props) {
+ const tools = "pix2pix samplernn style_transfer_video style_transfer_audio".split(" ").map((s,i) => {
+ return <option value={s}>{s}</option>
+ })
return (
<header>
<b>live cortex</b>
+ <span>
+ <select>
+ {tools}
+ </select>
+ </span>
+ <span><Link to="/dashboard">dashboard</Link></span>
+ <span>checkpoints</span>
+ <span>datasets</span>
+ <span>results</span>
+ <span>live</span>
<span>{props.fps} fps</span>
</header>
)
diff --git a/app/client/dashboard/actions.js b/app/client/dashboard/actions.js
new file mode 100644
index 0000000..01c0a96
--- /dev/null
+++ b/app/client/dashboard/actions.js
@@ -0,0 +1 @@
+import types from '../types'
diff --git a/app/client/dashboard/dashboard.component.js b/app/client/dashboard/dashboard.component.js
new file mode 100644
index 0000000..6db42ae
--- /dev/null
+++ b/app/client/dashboard/dashboard.component.js
@@ -0,0 +1,71 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux'
+
+import Player from '../common/player.component'
+import Group from '../common/group.component'
+import Slider from '../common/slider.component'
+import Select from '../common/select.component'
+import Button from '../common/button.component'
+
+import DashboardHeader from './dashboardheader.component'
+import TaskList from './tasklist.component'
+import FileList from './filelist.component'
+import Gallery from './gallery.component'
+
+import * as liveActions from './actions'
+
+class Dashboard extends Component {
+ constructor(props){
+ super()
+ }
+ componentWillUpdate(nextProps) {
+ // if (nextProps.opt.checkpoint_name && nextProps.opt.checkpoint_name !== this.props.opt.checkpoint_name) {
+ // this.props.actions.list_epochs(nextProps.opt.checkpoint_name)
+ // }
+ }
+ render(){
+ const { tasks, files, images, site } = this.props
+ return (
+ <div className='dashboard'>
+ <DashboardHeader />
+ <div className='params'>
+ <div className='column'>
+ <Group title='Completed Tasks'>
+ <TaskList tasks={tasks} />
+ </Group>
+ <Group title='Upcoming Tasks'>
+ <TaskList tasks={tasks} />
+ </Group>
+ </div>
+ <div className='column'>
+ <Group title='Your Datasets'>
+ <FileList files={files} />
+ </Group>
+ <Group title='Results'>
+ <FileList files={files} />
+ </Group>
+ <Group title='Audio Player'>
+ <FileList files={files} />
+ </Group>
+ </div>
+ </div>
+ <div>
+ <Gallery images={images} />
+ </div>
+ </div>
+ )
+ }
+}
+const mapStateToProps = state => ({
+ site: state.system.site,
+ images: state.system.images,
+ tasks: state.system.tasks,
+ files: state.system.files
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ actions: bindActionCreators(liveActions, dispatch)
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(Dashboard)
diff --git a/app/client/dashboard/dashboard.reducer.js b/app/client/dashboard/dashboard.reducer.js
new file mode 100644
index 0000000..c5b3d4a
--- /dev/null
+++ b/app/client/dashboard/dashboard.reducer.js
@@ -0,0 +1,16 @@
+import moment from 'moment'
+let FileSaver = require('file-saver')
+
+const dashboardInitialState = {
+ loading: false,
+ error: null,
+}
+
+const dashboardReducer = (state = dashboardInitialState, action) => {
+ switch(action.type) {
+ default:
+ return state
+ }
+}
+
+export default dashboardReducer
diff --git a/app/client/dashboard/dashboardHeader.component.js b/app/client/dashboard/dashboardHeader.component.js
new file mode 100644
index 0000000..492dfd8
--- /dev/null
+++ b/app/client/dashboard/dashboardHeader.component.js
@@ -0,0 +1,39 @@
+import { h, Component } from 'preact'
+import { connect } from 'react-redux'
+import { bindActionCreators } from 'redux'
+import * as liveActions from '../live/actions'
+
+import * as util from '../util'
+
+class DashboardHeader extends Component {
+ constructor(props){
+ super(props)
+ this.handleClick = this.handleClick.bind(this)
+ }
+ handleClick(e){
+ this.props.onClick && this.props.onClick()
+ }
+ render() {
+ const { currentTask, site } = this.props
+ const eta = ((currentTask.epochs - currentTask.epoch) * 180 / 60) + " minutes"
+ return (
+ <div class='dashboardHeader heading'>
+ <h3>{site.name}</h3>
+ Currently {util.gerund(currentTask.activity)} {currentTask.library} on {currentTask.dataset}<br/>
+ Epoch: {currentTask.epoch} / {currentTask.epochs}, ETA {eta}<br/>
+ <br/>
+ Want to play live? <button>Pause at the end of this epoch</button>
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+ currentTask: state.system.currentTask,
+ site: state.system.site,
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(DashboardHeader)
diff --git a/app/client/dashboard/filelist.component.js b/app/client/dashboard/filelist.component.js
new file mode 100644
index 0000000..2833ec8
--- /dev/null
+++ b/app/client/dashboard/filelist.component.js
@@ -0,0 +1,46 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux'
+import * as util from '../util'
+
+class FileList extends Component {
+ constructor(props){
+ super()
+ }
+ render(){
+ const { files } = this.props
+ let time = 0
+ const fileList = files.map(file => {
+ const eta = (time + (file.epochs) * 180 / 60) + " min."
+ time += (file.epochs) * 180 / 60
+ let dataset_type, dataset_name
+ if (file.dataset.indexOf('/') !== -1) {
+ [dataset_type, dataset_name] = file.dataset.split('/')
+ } else {
+ dataset_name = file.dataset
+ }
+ return (
+ <div class='row'>
+ <div class='activity'>{file.activity} {file.library} {dataset_type}</div>
+ <div class='dataset'>{dataset_name}</div>
+ <div class='epochs'>{file.epochs} ep.</div>
+ <div class='eta'>{eta}</div>
+ </div>
+ )
+ })
+ return (
+ <div class='filelist rows'>
+ {fileList}
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ // actions: bindActionCreators(liveActions, dispatch)
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(FileList)
diff --git a/app/client/dashboard/gallery.component.js b/app/client/dashboard/gallery.component.js
new file mode 100644
index 0000000..0e1f44d
--- /dev/null
+++ b/app/client/dashboard/gallery.component.js
@@ -0,0 +1,33 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux'
+
+class Gallery extends Component {
+ constructor(props){
+ super()
+ }
+ render(){
+ const { title, images } = this.props
+ images.push(images[0])
+ const imageList = images.map(image => {
+ return (
+ <div>
+ <img src={image.url} />
+ </div>
+ )
+ })
+ return (
+ <div class='gallery'>
+ {imageList}
+ </div>
+ )
+ }
+}
+const mapStateToProps = state => ({
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ // actions: bindActionCreators(liveActions, dispatch)
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(Gallery)
diff --git a/app/client/dashboard/index.js b/app/client/dashboard/index.js
new file mode 100644
index 0000000..29b1ecf
--- /dev/null
+++ b/app/client/dashboard/index.js
@@ -0,0 +1,2 @@
+export default {
+} \ No newline at end of file
diff --git a/app/client/dashboard/tasklist.component.js b/app/client/dashboard/tasklist.component.js
new file mode 100644
index 0000000..fa002de
--- /dev/null
+++ b/app/client/dashboard/tasklist.component.js
@@ -0,0 +1,45 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux'
+
+class TaskList extends Component {
+ constructor(props){
+ super()
+ }
+ render(){
+ const { title, tasks } = this.props
+ let time = 0
+ const taskList = tasks.map(task => {
+ const eta = (time + (task.epochs) * 180 / 60) + " min."
+ time += (task.epochs) * 180 / 60
+ let dataset_type, dataset_name
+ if (task.dataset.indexOf('/') !== -1) {
+ [dataset_type, dataset_name] = task.dataset.split('/')
+ } else {
+ dataset_name = task.dataset
+ }
+ return (
+ <div class='row'>
+ <div class='activity'>{task.activity} {task.library} {dataset_type}</div>
+ <div class='dataset'>{dataset_name}</div>
+ <div class='epochs'>{task.epochs} ep.</div>
+ <div class='eta'>{eta}</div>
+ </div>
+ )
+ })
+ return (
+ <div class='taskList rows'>
+ {taskList}
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ // actions: bindActionCreators(liveActions, dispatch)
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(TaskList)
diff --git a/app/client/index.jsx b/app/client/index.jsx
index d30c73f..a084306 100644
--- a/app/client/index.jsx
+++ b/app/client/index.jsx
@@ -7,15 +7,17 @@ import { store, history } from './store'
import socket from './socket'
import Header from './common/header.component'
-import Live from './live'
+import Dashboard from './dashboard/dashboard.component'
+import LivePix2Pix from './pix2pix'
const app = (
<Provider store={store}>
<BrowserRouter>
<div>
+ <Route path='/' component={Dashboard} />
+ <Route path='/live/' component={LivePix2Pix} />
+ <Route path='/dashboard/' component={Dashboard} />
<Header />
- <Route path='/' component={Live} />
- <Route path='/live/' component={Live} />
</div>
</BrowserRouter>
</Provider>
diff --git a/app/client/live/actions.js b/app/client/live/actions.js
index c9927b3..e63854e 100644
--- a/app/client/live/actions.js
+++ b/app/client/live/actions.js
@@ -1,52 +1,53 @@
import * as socket from '../socket'
+import types from '../types'
export const get_params = () => {
socket.get_params()
- return { type: 'GET_PARAMS', }
+ return { type: types.player.get_params, }
}
export const set_param = (key, value) => {
console.log('set param', key, value)
socket.set_param(key, value)
- return { type: 'SET_PARAM', key, value, }
+ return { type: types.player.set_param, key, value, }
}
export const list_checkpoints = () => {
socket.list_checkpoints()
- return { type: 'LOADING_CHECKPOINTS', }
+ return { type: types.player.loading_checkpoints, }
}
export const list_epochs = (path) => {
socket.list_epochs(path)
- return { type: 'LOADING_EPOCHS', }
+ return { type: types.player.loading_epochs, }
}
export const list_sequences = () => {
socket.list_sequences()
- return { type: 'LOADING_SEQUENCES', }
+ return { type: types.player.loading_sequences }
}
export const load_sequence = (sequence) => {
socket.load_sequence(sequence)
- return { type: 'LOADING_SEQUENCE', }
+ return { type: types.player.loading_sequence, }
}
export const load_epoch = (checkpoint, epoch) => {
socket.load_epoch(checkpoint, epoch)
- return { type: 'LOADING_CHECKPOINT', }
+ return { type: types.player.loading_checkpoint, }
}
export const seek = (frame) => {
socket.seek(frame)
- return { type: 'SEEKING', }
+ return { type: types.player.seeking, }
}
export const pause = (frame) => {
socket.pause(pause)
- return { type: 'PAUSING', }
+ return { type: types.player.pausing, }
}
export const play = (frame) => {
socket.play()
- return { type: 'PLAYING', }
+ return { type: types.player.playing, }
}
diff --git a/app/client/live/player.js b/app/client/live/player.js
index b39d717..ac5f0c8 100644
--- a/app/client/live/player.js
+++ b/app/client/live/player.js
@@ -1,5 +1,6 @@
import { store } from '../store'
import Whammy from './whammy'
+import types from '../types'
let fps = 0, last_frame
let recording = false, saving = false
@@ -9,7 +10,7 @@ export function startRecording(){
videoWriter = new Whammy.Video(10)
recording = true
store.dispatch({
- type: 'START_RECORDING',
+ type: types.player.start_recording,
})
}
@@ -17,12 +18,12 @@ export function stopRecording(){
if (!recording) return
recording = false
store.dispatch({
- type: 'SAVING_VIDEO',
+ type: types.player.saving_video,
})
videoWriter.compile(false, function(blob){
- console.log(blob)
+ // console.log(blob)
store.dispatch({
- type: 'SAVE_VIDEO',
+ type: types.player.save_video,
blob: blob,
})
})
@@ -37,23 +38,25 @@ export function onFrame (data) {
const url = URL.createObjectURL(blob)
const img = new Image ()
img.onload = function() {
+ img.onload = null
last_frame = data.meta
URL.revokeObjectURL(url)
- const canvas = document.querySelector('.player canvas')
+ let canvas = document.querySelector('.player canvas')
+ if (! canvas) return console.error('no canvas for frame')
const ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
if (recording) {
console.log('record frame')
videoWriter.add(canvas)
store.dispatch({
- type: 'ADD_RECORD_FRAME',
+ type: types.player.add_record_frame,
})
}
if (saving) {
saving = false
canvas.toBlob(function(blob) {
store.dispatch({
- type: 'SAVE_FRAME',
+ type: types.player.save_frame,
blob: blob,
})
})
@@ -65,11 +68,11 @@ export function onFrame (data) {
setInterval(() => {
store.dispatch({
- type: 'SET_FPS',
+ type: types.player.set_fps,
fps: fps,
})
store.dispatch({
- type: 'CURRENT_FRAME',
+ type: types.player.current_frame,
meta: last_frame,
})
fps = 0
diff --git a/app/client/live/reducer.js b/app/client/live/reducer.js
index 8fa6edd..60bcb41 100644
--- a/app/client/live/reducer.js
+++ b/app/client/live/reducer.js
@@ -1,6 +1,6 @@
-import { combineReducers } from 'redux'
import moment from 'moment'
-let FileSaver = require('file-saver')
+import FileSaver from 'file-saver'
+import types from '../types'
const liveInitialState = {
loading: false,
@@ -17,7 +17,7 @@ const liveReducer = (state = liveInitialState, action) => {
let results;
switch(action.type) {
- case 'LOAD_PARAMS':
+ case types.player.load_params:
if (! action.opt || ! Object.keys(action.opt).length) {
return state
}
@@ -28,7 +28,7 @@ const liveReducer = (state = liveInitialState, action) => {
opt: action.opt,
}
- case 'SET_PARAM':
+ case types.player.set_param:
return {
...state,
opt: {
@@ -37,14 +37,14 @@ const liveReducer = (state = liveInitialState, action) => {
}
}
- case 'LIST_CHECKPOINTS':
+ case types.player.list_checkpoints:
return {
...state,
checkpoints: action.checkpoints,
epochs: [],
}
- case 'LIST_EPOCHS':
+ case types.player.list_epochs:
return {
...state,
epochs: (action.epochs || []).map(a => [ a == 'latest' ? Infinity : a, a ])
@@ -52,25 +52,25 @@ const liveReducer = (state = liveInitialState, action) => {
.map(a => a[1])
}
- case 'LIST_SEQUENCES':
+ case types.player.list_sequences:
return {
...state,
sequences: action.sequences,
}
- case 'SET_FPS':
+ case types.player.set_fps:
return {
...state,
fps: action.fps,
}
- case 'CURRENT_FRAME':
+ case types.player.current_frame:
return action.meta ? {
...state,
frame: action.meta
} : state
- case 'START_RECORDING':
+ case types.player.start_recording:
return {
...state,
opt: {
@@ -78,7 +78,7 @@ const liveReducer = (state = liveInitialState, action) => {
recording: true,
}
}
- case 'ADD_RECORD_FRAME':
+ case types.player.add_record_frame:
return {
...state,
opt: {
@@ -87,7 +87,7 @@ const liveReducer = (state = liveInitialState, action) => {
}
}
- case 'SAVE_FRAME':
+ case types.player.save_frame:
FileSaver.saveAs(
action.blob,
state.opt.checkpoint_name + "_" +
@@ -96,7 +96,7 @@ const liveReducer = (state = liveInitialState, action) => {
)
return state
- case 'SAVING_VIDEO':
+ case types.player.saving_video:
return {
...state,
opt: {
@@ -104,7 +104,7 @@ const liveReducer = (state = liveInitialState, action) => {
savingVideo: true,
}
}
- case 'SAVE_VIDEO':
+ case types.player.save_video:
FileSaver.saveAs(
action.blob,
state.opt.checkpoint_name + "_" +
diff --git a/app/client/live/index.js b/app/client/pix2pix/index.js
index 94af289..9d41fbc 100644
--- a/app/client/live/index.js
+++ b/app/client/pix2pix/index.js
@@ -8,11 +8,11 @@ import Slider from '../common/slider.component'
import Select from '../common/select.component'
import Button from '../common/button.component'
-import { startRecording, stopRecording, saveFrame } from './player'
+import { startRecording, stopRecording, saveFrame } from '../live/player'
-import * as liveActions from './actions'
+import * as liveActions from '../live/actions'
-class App extends Component {
+class LivePix2Pix extends Component {
constructor(props){
super()
props.actions.get_params()
@@ -249,4 +249,4 @@ const mapDispatchToProps = (dispatch, ownProps) => ({
actions: bindActionCreators(liveActions, dispatch)
})
-export default connect(mapStateToProps, mapDispatchToProps)(App)
+export default connect(mapStateToProps, mapDispatchToProps)(LivePix2Pix)
diff --git a/app/client/socket.js b/app/client/socket.js
index a2a745e..ea6f380 100644
--- a/app/client/socket.js
+++ b/app/client/socket.js
@@ -17,25 +17,25 @@ socket.on('res', (data) => {
break
case 'get_params':
store.dispatch({
- type: 'LOAD_PARAMS',
+ type: types.socket.load_params,
opt: data.res,
})
break
case 'list_checkpoints':
store.dispatch({
- type: 'LIST_CHECKPOINTS',
+ type: types.socket.list_checkpoints,
checkpoints: data.res,
})
break
case 'list_sequences':
store.dispatch({
- type: 'LIST_SEQUENCES',
+ type: types.socket.list_sequences,
sequences: data.res,
})
break
case 'list_epochs':
store.dispatch({
- type: 'LIST_EPOCHS',
+ type: types.socket.list_epochs,
epochs: data.res,
})
break
@@ -49,6 +49,7 @@ socket.on('frame', player.onFrame)
socket.on('status', (data) => {
console.log('got status', data.key, data.value)
+ store.dispatch({ type: types.socket.status })
switch (data.key) {
case 'processing':
store.dispatch({
diff --git a/app/client/store.js b/app/client/store.js
index 863161d..600e53c 100644
--- a/app/client/store.js
+++ b/app/client/store.js
@@ -6,9 +6,13 @@ import createHistory from 'history/createBrowserHistory'
import { routerReducer } from 'react-router-redux'
// import navReducer from './nav.reducer'
+import systemReducer from './system/system.reducer'
+import dashboardReducer from './dashboard/dashboard.reducer'
import liveReducer from './live/reducer'
const appReducer = combineReducers({
+ system: systemReducer,
+ dashboard: dashboardReducer,
live: liveReducer,
router: routerReducer,
})
diff --git a/app/client/system/system.reducer.js b/app/client/system/system.reducer.js
new file mode 100644
index 0000000..bc19fd1
--- /dev/null
+++ b/app/client/system/system.reducer.js
@@ -0,0 +1,106 @@
+import moment from 'moment'
+let FileSaver = require('file-saver')
+
+const systemInitialState = {
+ loading: false,
+ error: null,
+
+ site: {
+ name: 'Lens Cortex',
+ },
+ currentTask: {
+ id: 1072,
+ activity: 'train',
+ library: 'pix2pix',
+ dataset: 'video/woods_final',
+ epoch: 87,
+ epochs: 100,
+ },
+ images: [
+ {
+ url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2125.png',
+ },
+ {
+ url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2146%20(1).png',
+ },
+ {
+ url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2149.png',
+ },
+ {
+ url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2150.png',
+ },
+ ],
+ tasks: [
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'pix2pix',
+ dataset: 'video/woods_green',
+ epochs: 100,
+ },
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'samplernn',
+ dataset: 'bobby_brown_-_every_little_step',
+ epochs: 6,
+ },
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'pix2pix',
+ checkpoint: 'lyra_voice_layers',
+ dataset: 'audio/lyra_improv',
+ epochs: 30,
+ },
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'pix2pix',
+ checkpoint: 'lyra_melody_lines',
+ dataset: 'audio/lyra_improv',
+ epochs: 30,
+ },
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'pix2pix',
+ checkpoint: 'ensemble_chords',
+ dataset: 'audio/lyra_improv',
+ epochs: 30,
+ },
+ {
+ id: 1073,
+ activity: 'generate',
+ library: 'samplernn',
+ dataset: 'coccoglass3',
+ opt: { time: 5, count: 6 },
+ },
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'pix2pix',
+ dataset: 'video/woods_green',
+ epochs: 100,
+ },
+ {
+ id: 1073,
+ activity: 'train',
+ library: 'samplernn',
+ dataset: 'bobby_brown_-_every_little_step',
+ epochs: 6,
+ },
+ ],
+ files: [
+ { id: 2, library: 'samplernn', checkpoint: 'jwcglassbeat', dataset: 'jwcglassbeat', epoch: 18, duration: 30, batch_size: 5, filename: 'jwcglassbeat-ep18.mp3', size: 3 * 1024 * 1024, date: Date.now(), opt: "{}", }
+ ]
+}
+
+const systemReducer = (state = systemInitialState, action) => {
+ switch(action.type) {
+ default:
+ return state
+ }
+}
+
+export default systemReducer
diff --git a/app/client/types.js b/app/client/types.js
new file mode 100644
index 0000000..782a225
--- /dev/null
+++ b/app/client/types.js
@@ -0,0 +1,31 @@
+export default {
+ socket: {
+ load_params: 'LOAD_PARAMS',
+ list_sequences: 'LIST_SEQUENCES',
+ list_epochs: 'LIST_EPOCHS',
+ },
+ player: {
+ get_params: 'GET_PARAMS',
+ set_param: 'SET_PARAM',
+
+ loading_checkpoints: 'LOADING_CHECKPOINTS',
+ list_checkpoints: 'LIST_CHECKPOINTS',
+
+ loading_sequences: 'LOADING_SEQUENCES',
+ load_sequence: 'LOAD_SEQUENCE',
+
+ loading_epochs: 'LOADING_EPOCHS',
+ load_epoch: 'LOAD_EPOCH',
+
+ set_fps: 'SET_FPS',
+ seeking: 'SEEKING',
+ pausing: 'PAUSING',
+ playing: 'PLAYING',
+ current_frame: 'CURRENT_FRAME',
+ start_recording: 'START_RECORDING',
+ add_record_frame: 'ADD_RECORD_FRAME',
+ save_frame: 'SAVE_FRAME',
+ saving_video: 'SAVING_VIDEO',
+ save_video: 'SAVE_VIDEO',
+ }
+} \ No newline at end of file
diff --git a/app/client/util.js b/app/client/util.js
new file mode 100644
index 0000000..db9fa8c
--- /dev/null
+++ b/app/client/util.js
@@ -0,0 +1,6 @@
+export function timeInSeconds(n){
+ return (n / 10).toFixed(1) + ' s.'
+}
+export function gerund(s){
+ return s.replace(/e?$/, 'ing')
+}