summaryrefslogtreecommitdiff
path: root/client/components/Browser
diff options
context:
space:
mode:
Diffstat (limited to 'client/components/Browser')
-rw-r--r--client/components/Browser/Browser.jsx57
-rw-r--r--client/components/Browser/Folder/FileUploadButton.jsx35
-rw-r--r--client/components/Browser/Folder/Folder.jsx77
-rw-r--r--client/components/Browser/Folders/FolderForm.jsx47
-rw-r--r--client/components/Browser/Folders/Folders.jsx56
5 files changed, 272 insertions, 0 deletions
diff --git a/client/components/Browser/Browser.jsx b/client/components/Browser/Browser.jsx
new file mode 100644
index 0000000..10b86c3
--- /dev/null
+++ b/client/components/Browser/Browser.jsx
@@ -0,0 +1,57 @@
+import { h, Component } from 'preact'
+
+import Folders from './Folders/Folders.jsx'
+import Folder from './Folder/Folder.jsx'
+
+import client from '../../client'
+
+class Browser extends Component {
+ constructor(props) {
+ super()
+ let openFolders = JSON.parse( localStorage['openFolders'] || 'null' )
+ this.state = {
+ folders: [],
+ openFolders: openFolders || [],
+ }
+ client.folder.index().then( folders => this.setState({ folders }) )
+ }
+ openFolder(folder) {
+ if (this.state.openFolders.indexOf(folder.id) === -1) {
+ const newOpenFolders = this.state.openFolders.concat(folder.id)
+ localStorage['openFolders'] = JSON.stringify(newOpenFolders)
+ this.setState({ openFolders: newOpenFolders })
+ }
+ }
+ closeFolder(folder) {
+ const openFolders = this.state.openFolders.filter( folder_id => folder_id !== folder.id )
+ localStorage['openFolders'] = JSON.stringify(openFolders)
+ this.setState({ openFolders })
+ }
+ addFolder(folder) {
+ this.setState({ folders: this.state.folders.concat([folder]) })
+ }
+ render() {
+ const openFolders = this.state.openFolders.map((folder_id) => {
+ const folder_list = this.state.folders.filter(folder => folder.id === folder_id)
+ if (! folder_list.length) return
+ const folder = folder_list[0]
+ return (
+ <Folder
+ folder={folder}
+ onClose={() => this.closeFolder(folder)}
+ />
+ )
+ })
+ return (
+ <div class='column'>
+ <Folders folders={this.state.folders}
+ openFolder={(folder) => this.openFolder(folder)}
+ addFolder={(folder) => this.addFolder(folder)}
+ />
+ {openFolders}
+ </div>
+ )
+ }
+}
+
+export default Browser
diff --git a/client/components/Browser/Folder/FileUploadButton.jsx b/client/components/Browser/Folder/FileUploadButton.jsx
new file mode 100644
index 0000000..136cd45
--- /dev/null
+++ b/client/components/Browser/Folder/FileUploadButton.jsx
@@ -0,0 +1,35 @@
+import { h, Component } from 'preact'
+
+import client from '../../../client.js'
+
+export default class Folder extends Component {
+ constructor(props) {
+ super()
+ this.state = {
+ }
+ this.updateFiles = this.updateFiles.bind(this)
+ }
+ updateFiles(event){
+ const name = event.target.name
+ const files = event.target.files
+ client.upload(this.props.folder.id, files).then( got_files => {
+ this.props.addFiles(got_files)
+ })
+ }
+
+ render() {
+ const files = (this.props.folder.files || []).map( (file, i) => {
+ return (
+ <div key={i}>
+ {file.name}
+ </div>
+ )
+ })
+ return (
+ <div class='fileUploadButton'>
+ <input type='file' multiple name='files' onChange={this.updateFiles} />
+ <span>+ upload</span>
+ </div>
+ )
+ }
+}
diff --git a/client/components/Browser/Folder/Folder.jsx b/client/components/Browser/Folder/Folder.jsx
new file mode 100644
index 0000000..3ed3ddb
--- /dev/null
+++ b/client/components/Browser/Folder/Folder.jsx
@@ -0,0 +1,77 @@
+import { h, Component } from 'preact'
+
+import client from '../../../client.js'
+
+import FileUploadButton from './FileUploadButton.jsx'
+
+export default class Folder extends Component {
+ constructor(props) {
+ super()
+ this.state = {
+ files: props.folder.files || [],
+ }
+ this.addFiles = this.addFiles.bind(this)
+ if (! props.folder.files) {
+ client.file.index({ folder_id: props.folder.id }).then( files => this.setState({ files }) )
+ }
+ this.audio = document.createElement('audio')
+ }
+ addFiles(newFiles) {
+ if (! newFiles) return
+ const files = this.state.files.concat(newFiles).sort( (a,b) => { return b.id - a.id } )
+ this.setState({ files })
+ }
+ handleClick(file) {
+ if (file.type === 'audio') {
+ this.audio.setAttribute('src', mp3path(file))
+ this.audio.play()
+ document.body.style.backgroundImage = 'url(' + pngpath(file) + ')'
+ }
+ }
+ render() {
+ const files = (this.state.files).map(toFilenamePair).sort(sortByFilename).map(fromPair).map( (file, i) => {
+ if (! file) return
+ return (
+ <div key={i}>
+ <span class='name' onClick={() => this.handleClick(file)}>{file.name}</span>
+ <span class='mime'>{file.mime}</span>
+ <span class='actions'>
+ <span onClick={() => this.props.setContent(file)}>content &gt;</span>
+ <span onClick={() => this.props.setStyle(file)}>style &gt;</span>
+ </span>
+ </div>
+ )
+ })
+ return (
+ <div class='window'>
+ <div class='heading'>
+ <b>{this.props.folder.name}</b>
+ <div class='buttons'>
+ <FileUploadButton folder={this.props.folder} addFiles={this.addFiles} />
+ <button onClick={this.props.onClose}>&times;</button>
+ </div>
+ </div>
+ <div class='list'>
+ {files}
+ </div>
+ </div>
+ )
+ }
+}
+
+function toFilenamePair (file) { return [file.name.toLowerCase(), file] }
+function sortByFilename (a,b) { return a[0] < b[0] ? -1 : a[0] == b[0] ? 0 : 1 }
+function fromPair (pair) { return pair[1] }
+
+function filepath (file) {
+ return '/data/' + file.folder_id + '/' + encodeURIComponent(file.name)
+}
+function mp3path (file) {
+ if (file.mime !== 'audio/mp3') {
+ return filepath(file) + '.mp3'
+ }
+ return filepath(file)
+}
+function pngpath (file) {
+ return filepath(file) + '.png'
+} \ No newline at end of file
diff --git a/client/components/Browser/Folders/FolderForm.jsx b/client/components/Browser/Folders/FolderForm.jsx
new file mode 100644
index 0000000..ad3e321
--- /dev/null
+++ b/client/components/Browser/Folders/FolderForm.jsx
@@ -0,0 +1,47 @@
+import { h, Component } from 'preact'
+
+import client from '../../../client.js'
+
+export default class FolderForm extends Component {
+ constructor(props) {
+ super()
+ this.state = {
+ name: '',
+ }
+ this.updateState = this.updateState.bind(this)
+ this.handleSubmit = this.handleSubmit.bind(this)
+ }
+ updateState(event){
+ const name = event.target.name
+ let value = event.target.value
+ console.log(name, value)
+ this.setState({
+ [name]: value,
+ error: null,
+ })
+ }
+ handleSubmit(event) {
+ event.preventDefault()
+ let rec = Object.assign({}, this.state)
+ delete rec.error
+ this.props.onClose()
+ client.folder.create( rec ).then( (data) => {
+ this.props.addFolder( data )
+ })
+ }
+ render() {
+ return (
+ <div class='form'>
+ <h1>new folder</h1>
+ <div>
+ <label for='folders_folder_name'>Name</label>
+ <input type='text' id='folders_folder_name' name='name' value={this.state.name} onChange={this.updateState} />
+ </div>
+ <div>
+ <label></label>
+ <button onClick={this.handleSubmit}>Create</button>
+ </div>
+ </div>
+ )
+ }
+}
diff --git a/client/components/Browser/Folders/Folders.jsx b/client/components/Browser/Folders/Folders.jsx
new file mode 100644
index 0000000..2c85e80
--- /dev/null
+++ b/client/components/Browser/Folders/Folders.jsx
@@ -0,0 +1,56 @@
+import { h, Component } from 'preact'
+
+import Modal from '../../UI/Modal.jsx'
+import FolderForm from './FolderForm.jsx'
+
+import client from '../../../client.js'
+
+export default class Folders extends Component {
+ constructor(props) {
+ super()
+ this.state = {
+ adding: false,
+ }
+ }
+ openModal() {
+ this.setState({ adding: true })
+ }
+ closeModal() {
+ this.setState({ adding: false })
+ }
+ toggle(folder) {
+ folder.open = ! folder.open
+ if (folder.open && ! folder.files) {
+ client.file.index({ 'folder_id': folder.id }).then( files => {
+ console.log(files)
+ folder.files = files
+ this.props.openFolder(folder)
+ })
+ }
+ }
+ render() {
+ const folders = (this.props.folders || []).map( (folder,i) => {
+ return (
+ <div key={i} onClick={() => this.toggle(folder)}>
+ <span class='name'>{folder.name}</span>
+ </div>
+ )
+ })
+ return (
+ <div class='window'>
+ <div class='heading'>
+ <b>browser</b>
+ <div class='buttons'>
+ <button onClick={() => this.openModal()}>+ folder</button>
+ </div>
+ </div>
+ <div class='list'>
+ {folders}
+ </div>
+ <Modal visible={this.state.adding} onClose={() => this.closeModal()}>
+ <FolderForm addFolder={this.props.addFolder} onClose={() => this.closeModal()} />
+ </Modal>
+ </div>
+ )
+ }
+}