summaryrefslogtreecommitdiff
path: root/app/client/modules
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-06-26 01:28:41 +0200
committerJules Laplace <julescarbon@gmail.com>2018-06-26 01:28:41 +0200
commit8d06839056967e8786c63976545aff098ae2f128 (patch)
tree51c83236b2dcc5a6adabb1b4036eccfff63b9ef5 /app/client/modules
parentbd354556f98aa724dd6cee03a1828bd40ce01f33 (diff)
morph module.. enum method for sliders
Diffstat (limited to 'app/client/modules')
-rw-r--r--app/client/modules/index.js3
-rw-r--r--app/client/modules/module.reducer.js2
-rw-r--r--app/client/modules/morph/index.js37
-rw-r--r--app/client/modules/morph/morph.actions.js45
-rw-r--r--app/client/modules/morph/morph.module.js7
-rw-r--r--app/client/modules/morph/morph.reducer.js35
-rw-r--r--app/client/modules/morph/morph.tasks.js23
-rw-r--r--app/client/modules/morph/views/morph.app.js185
8 files changed, 336 insertions, 1 deletions
diff --git a/app/client/modules/index.js b/app/client/modules/index.js
index 6cc6cd4..14a2333 100644
--- a/app/client/modules/index.js
+++ b/app/client/modules/index.js
@@ -1,8 +1,9 @@
+import morph from './morph'
import pix2pix from './pix2pix'
import pix2pixhd from './pix2pixhd'
import pix2wav from './pix2wav'
import samplernn from './samplernn'
export default {
- pix2pix, pix2pixhd, pix2wav, samplernn
+ morph, pix2pix, pix2pixhd, pix2wav, samplernn
}
diff --git a/app/client/modules/module.reducer.js b/app/client/modules/module.reducer.js
index 0598960..ff977ce 100644
--- a/app/client/modules/module.reducer.js
+++ b/app/client/modules/module.reducer.js
@@ -1,11 +1,13 @@
import { combineReducers } from 'redux'
+import morphReducer from './morph/morph.reducer'
import pix2pixReducer from './pix2pix/pix2pix.reducer'
import pix2pixhdReducer from './pix2pixhd/pix2pixhd.reducer'
import pix2wavReducer from './pix2wav/pix2wav.reducer'
import samplernnReducer from './samplernn/samplernn.reducer'
export const moduleReducer = combineReducers({
+ morph: morphReducer,
pix2pix: pix2pixReducer,
pix2pixhd: pix2pixhdReducer,
pix2wav: pix2wavReducer,
diff --git a/app/client/modules/morph/index.js b/app/client/modules/morph/index.js
new file mode 100644
index 0000000..9c90848
--- /dev/null
+++ b/app/client/modules/morph/index.js
@@ -0,0 +1,37 @@
+import { h, Component } from 'preact'
+import { Route, Link } from 'react-router-dom'
+
+import actions from '../../actions'
+
+import util from '../../util'
+
+import MorphApp from './views/morph.app'
+
+class router {
+ componentWillMount(){
+ actions.system.changeTool('morph')
+ document.body.style.backgroundImage = 'linear-gradient(' + (util.randint(40)+40) + 'deg, #def, #dfe)'
+ }
+ componentWillReceiveProps(){
+ actions.system.changeTool('morph')
+ document.body.style.backgroundImage = 'linear-gradient(' + (util.randint(40)+40) + 'deg, #def, #dfe)'
+ }
+ render(){
+ return (
+ <section>
+ <Route exact path='/morph/app/' component={MorphApp} />
+ </section>
+ )
+ }
+}
+
+function links(){
+ return [
+ { url: '/morph/app/', name: 'morph' },
+ ]
+}
+
+export default {
+ name: 'morph',
+ router, links,
+}
diff --git a/app/client/modules/morph/morph.actions.js b/app/client/modules/morph/morph.actions.js
new file mode 100644
index 0000000..9d47d03
--- /dev/null
+++ b/app/client/modules/morph/morph.actions.js
@@ -0,0 +1,45 @@
+import uuidv1 from 'uuid/v1'
+
+import socket from '../../socket'
+import types from '../../types'
+
+import * as datasetLoader from '../../dataset/dataset.loader'
+
+import actions from '../../actions'
+
+import util from '../../util'
+
+import morphModule from './morph.module'
+
+export const load_data = (id) => (dispatch) => {
+ const module = morphModule.name
+ util.allProgress([
+ datasetLoader.load(module),
+ actions.socket.list_sequences({ module: 'pix2pixhd', dir: 'sequences' }),
+ actions.socket.list_directory({ module, dir: 'renders' }),
+ ], (percent, i, n) => {
+ console.log('morph load progress', i, n)
+ dispatch({ type: types.app.load_progress, progress: { i, n }})
+ }).then(res => {
+ const [datasetApiReport, sequences, renders] = res
+ const {
+ folderLookup,
+ fileLookup,
+ datasetLookup,
+ folders,
+ files,
+ unsortedFolder,
+ resultsFolder,
+ } = datasetApiReport
+
+ dispatch({
+ type: types.morph.load,
+ data: datasetApiReport,
+ app: {
+ files,
+ sequences,
+ renders,
+ }
+ })
+ })
+} \ No newline at end of file
diff --git a/app/client/modules/morph/morph.module.js b/app/client/modules/morph/morph.module.js
new file mode 100644
index 0000000..8fc5ce4
--- /dev/null
+++ b/app/client/modules/morph/morph.module.js
@@ -0,0 +1,7 @@
+const morphModule = {
+ name: 'morph',
+ displayName: 'Morph',
+ datatype: 'video',
+}
+
+export default morphModule
diff --git a/app/client/modules/morph/morph.reducer.js b/app/client/modules/morph/morph.reducer.js
new file mode 100644
index 0000000..92cbc9e
--- /dev/null
+++ b/app/client/modules/morph/morph.reducer.js
@@ -0,0 +1,35 @@
+import types from '../../types'
+import datasetReducer from '../../dataset/dataset.reducer'
+
+const morphInitialState = {
+ loading: true,
+ progress: { i: 0, n: 0 },
+ error: null,
+ folder_id: 0,
+ data: null,
+ app: null,
+}
+
+const morphReducer = (state = morphInitialState, action) => {
+ if (action.data && action.data.module === 'morph') {
+ state = datasetReducer(state, action)
+ }
+
+ switch (action.type) {
+ case types.morph.load_results:
+ return {
+ ...state,
+ results: action.results,
+ }
+ case types.morph.load:
+ console.log('morph load', action.app)
+ return {
+ ...state,
+ app: action.app,
+ }
+ default:
+ return state
+ }
+}
+
+export default morphReducer
diff --git a/app/client/modules/morph/morph.tasks.js b/app/client/modules/morph/morph.tasks.js
new file mode 100644
index 0000000..67abc8a
--- /dev/null
+++ b/app/client/modules/morph/morph.tasks.js
@@ -0,0 +1,23 @@
+import uuidv1 from 'uuid/v1'
+
+import socket from '../../socket'
+import types from '../../types'
+
+import actions from '../../actions'
+
+import module from './morph.module'
+
+export const fetch_task = (url, file_id, dataset) => dispatch => {
+ if (! url) return console.log('input file inaccessible (no url)')
+ const task = {
+ module: module.name,
+ activity: 'fetch',
+ dataset: dataset,
+ opt: {
+ url,
+ file_id,
+ dataset,
+ }
+ }
+ return actions.queue.add_task(task)
+}
diff --git a/app/client/modules/morph/views/morph.app.js b/app/client/modules/morph/views/morph.app.js
new file mode 100644
index 0000000..045f396
--- /dev/null
+++ b/app/client/modules/morph/views/morph.app.js
@@ -0,0 +1,185 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { Link } from 'react-router-dom';
+import { connect } from 'react-redux'
+import util from '../../../util'
+
+import actions from '../../../actions'
+
+import * as morphActions from '../morph.actions'
+import * as morphTasks from '../morph.tasks'
+
+import Loading from '../../../common/loading.component'
+import {
+ Select, Slider, Checkbox, Group,
+ Button, Param, FileList, FileRow,
+} from '../../../common'
+
+let yes_count = 0
+
+class MorphResults extends Component {
+ constructor(props){
+ super()
+ this.state = {
+ a: "",
+ b: "",
+ a_offset: 0,
+ b_offset: 0,
+ steps: 16,
+ dilate: 2,
+ smooth: true,
+ cmd: 'mix',
+ }
+ if (!props.morph.data) props.actions.load_data()
+ }
+ componentDidMount(){
+ yes_count = 0
+ }
+ render(){
+ if (! this.props.morph.app) return <Loading progress={this.props.morph.progress} />
+
+ const { sequences, renders, files } = this.props.morph.app
+ const sequence_options = sequences.map(sequence => [
+ sequence.name.split("_").slice(0, 3).join(" ") + "~ (" + sequence.count + ")",
+ sequence.name
+ ])
+
+ console.log(sequence_options)
+ const totalLength = (this.state.steps * this.state.dilate) / 25
+ let lengthWarning
+ if (this.state.steps > 64) {
+ lengthWarning = (
+ <span><br/>warning, this may take a while</span>
+ )
+ }
+
+ return (
+ <div className='app morph'>
+ <div className='heading row middle'>
+ <h1>Morph</h1>
+ </div>
+ <div class='rows params renders'>
+ <div class='column'>
+ <Group title="From">
+ <Select
+ title="Starting sequence"
+ value={this.state.a}
+ options={sequence_options}
+ onChange={key => this.setState({ a: key })}
+ />
+ <Slider
+ title="Offset"
+ value={this.state.a_offset}
+ min={0} max={1} step={0.01}
+ onChange={key => this.setState({ a_offset: key })}
+ />
+ </Group>
+
+ <Group title="To">
+ <Select
+ title="Ending sequence"
+ value={this.state.b}
+ options={sequence_options}
+ onChange={key => this.setState({ b: key })}
+ />
+ <Slider
+ title="Offset"
+ value={this.state.b_offset}
+ min={0} max={1} step={0.01}
+ onChange={key => this.setState({ b_offset: key })}
+ />
+ </Group>
+
+ <Group title="Morph Settings">
+ <Select
+ title="Action"
+ value={this.state.cmd}
+ options={['mix', 'average']}
+ onChange={key => this.setState({ a: key })}
+ />
+ <Slider
+ type="list"
+ title="Steps"
+ value={this.state.steps}
+ options={[2,4,8,16,32,64,128,256]}
+ onChange={key => this.setState({ steps: key })}
+ />
+ <Slider
+ type="list"
+ title="Dilate"
+ value={this.state.dilate}
+ options={[2,4,8,16,32]}
+ onChange={key => this.setState({ dilate: key })}
+ />
+ <Checkbox
+ title="Smooth"
+ value={this.state.smooth}
+ onToggle={key => this.setState({ smooth: key })}
+ />
+ <Button
+ title="Run morph"
+ value="Go"
+ />
+ <br />
+ <Param title="Total length">
+ {totalLength.toFixed(1) + " seconds"}
+ </Param>
+ {lengthWarning}
+ <br />
+ </Group>
+ </div>
+
+ <FileList
+ linkFiles
+ files={files}
+ orderBy='date desc'
+ fields={'name date size delete'}
+ onDelete={file => {
+ let yes;
+ if (yes_count < 3) {
+ yes = confirm('Are you sure you want to delete this file?')
+ } else {
+ yes = true
+ }
+ if (yes) {
+ yes_count += 1
+ console.log('delete: confirmed')
+ actions.file.destroy(file)
+ }
+ }}
+ />
+ <br />
+
+ <h3>renders on server</h3>
+ <FileList
+ files={renders}
+ orderBy='date desc'
+ fields={'name date size'}
+ onClick={(file, e) => {
+ e.preventDefault()
+ e.stopPropagation()
+ console.log('picked a result', file)
+ this.handlePick(file)
+ }}
+ />
+
+ </div>
+ </div>
+ )
+ }
+ handlePick(file){
+ // this.props.audioPlayer.play(file)
+ }
+}
+
+const mapStateToProps = state => ({
+ morph: state.module.morph,
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ actions: bindActionCreators(morphActions, dispatch),
+ remote: bindActionCreators(morphTasks, dispatch),
+ // audioPlayer: bindActionCreators(audioPlayerActions, dispatch),
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(MorphResults)