Skip to content

Commit

Permalink
Extracts the file manager (and redux and toastr) from ipfs#229 by @di…
Browse files Browse the repository at this point in the history
  • Loading branch information
alanshaw committed Mar 16, 2017
1 parent 7fc3214 commit c412657
Show file tree
Hide file tree
Showing 69 changed files with 2,308 additions and 408 deletions.
4 changes: 2 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"presets": ["react", "es2015", "stage-0"],
"presets": ["es2015", "stage-0", "react"],
"plugins": [
'transform-runtime'
"transform-runtime"
],
"env": {
"development": {
Expand Down
13 changes: 13 additions & 0 deletions app/scripts/actions/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {action, createRequestTypes} from './utils'

export const CONFIG = {
LOAD: createRequestTypes('CONFIG_LOAD')
}

export const config = {
load: {
request: () => action(CONFIG.LOAD.REQUEST),
success: (response) => action(CONFIG.LOAD.SUCCESS, {response}),
failure: (error) => action(CONFIG.LOAD.FAILURE, {error})
}
}
5 changes: 5 additions & 0 deletions app/scripts/actions/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {action} from './utils'

export const RESET_ERROR_MESSAGE = 'RESET_ERROR_MESSAGE'

export const resetErrorMessage = () => action(RESET_ERROR_MESSAGE)
61 changes: 61 additions & 0 deletions app/scripts/actions/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {createRequestTypes, action} from './utils'

export const FILES_LIST = createRequestTypes('FILES_LIST')
export const FILES_MKDIR = createRequestTypes('FILES_MKDIR')
export const FILES_RMDIR = createRequestTypes('FILES_RMDIR')
export const FILES_CREATE_FILES = createRequestTypes('FILES_CREATE_FILES')

export const FILES = {
CANCEL: 'FILES_CANCEL',
SET_ROOT: 'FILES_SET_ROOT',
CREATE_TMP_DIR: 'FILES_CREATE_TMP_DIR',
RM_TMP_DIR: 'FILES_RM_TMP_DIR',
SET_TMP_DIR_NAME: 'FILES_SET_TMP_DIR_NAME',
CREATE_DIR: 'FILES_CREATE_DIR',
REMOVE_DIR: 'FILES_REMOVE_DIR',
SELECT_FILE: 'SELECT_FILE',
DESELECT_FILE: 'DESELECT_FILE',
DESELECT_ALL_FILE: 'DESELECT_ALL_FILE',
CREATE_FILES: 'CREATE_FILES'
}

export const filesList = {
request: () => action(FILES_LIST.REQUEST),
success: (response) => action(FILES_LIST.SUCCESS, {response}),
failure: (error) => action(FILES_LIST.FAILURE, {error})
}

export const filesMkdir = {
request: () => action(FILES_MKDIR.REQUEST),
success: () => action(FILES_MKDIR.SUCCESS),
failure: (error) => action(FILES_MKDIR.FAILURE, {error})
}

export const filesRmDir = {
request: () => action(FILES_RMDIR.REQUEST),
success: () => action(FILES_RMDIR.SUCCESS),
failure: (error) => action(FILES_RMDIR.FAILURE, {error})
}

export const createFiles = {
request: () => action(FILES_CREATE_FILES.REQUEST),
success: () => action(FILES_CREATE_FILES.SUCCESS),
failure: (error) => action(FILES_CREATE_FILES.FAILURE, {error})
}

export const files = {
cancel: () => action(FILES.CANCEL)
}

export const filesSetRoot = (root) => action(FILES.SET_ROOT, {root})
export const filesCreateTmpDir = (root) => action(FILES.CREATE_TMP_DIR, {root})
export const filesRmTmpDir = () => action(FILES.RM_TMP_DIR)
export const filesSetTmpDirName = (name) => action(FILES.SET_TMP_DIR_NAME, {name})
export const filesCreateDir = () => action(FILES.CREATE_DIR)
export const filesRemoveDir = () => action(FILES.REMOVE_DIR)

export const filesSelect = (file) => action(FILES.SELECT_FILE, {file})
export const filesDeselect = (file) => action(FILES.DESELECT_FILE, {file})
export const filesDeselectAll = () => action(FILES.DESELECT_ALL_FILE)

export const filesCreateFiles = (root, files) => action(FILES.CREATE_FILES, {root, files})
26 changes: 26 additions & 0 deletions app/scripts/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Broken because of https://phabricator.babeljs.io/T2877
// export * from './pages'
// export * from './errors'

// export * from './home'
// export * from './peers'
// export * from './files'
// export * from './preview'
// export * from './logs'

// Workaround

import * as pages from './pages'
import * as errors from './errors'
import * as router from './router'

import * as files from './files'
import * as preview from './preview'
import * as config from './config'

export {pages}
export {errors}
export {router}
export {files}
export {preview}
export {config}
4 changes: 4 additions & 0 deletions app/scripts/actions/pages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {createPage} from './utils'

export const {FILES, files} = createPage('files')
export const {PREVIEW, preview} = createPage('preview')
26 changes: 26 additions & 0 deletions app/scripts/actions/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {createRequestTypes, action} from './utils'

export const requests = {
PREVIEW_STAT: createRequestTypes('PREVIEW_STAT'),
PREVIEW_READ: createRequestTypes('PREVIEW_READ'),
stat: {
request: () => action(requests.PREVIEW_STAT.REQUEST),
success: (response) => action(requests.PREVIEW_STAT.SUCCESS, {response}),
failure: (error) => action(requests.PREVIEW_STAT.FAILURE, {error})
},
read: {
request: () => action(requests.PREVIEW_READ.REQUEST),
success: (response) => action(requests.PREVIEW_READ.SUCCESS, {response}),
failure: (error) => action(requests.PREVIEW_READ.FAILURE, {error})
}
}

export const PREVIEW = {
STAT: 'PREVIEW.STAT',
READ: 'PREVIEW.READ',
CLEAR: 'PREVIEW.CLEAR'
}

export const stat = (name) => action(PREVIEW.STAT, {name})
export const read = (name) => action(PREVIEW.READ, {name})
export const clear = () => action(PREVIEW.CLEAR)
3 changes: 3 additions & 0 deletions app/scripts/actions/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import {push, replace, go, goBack, goForward} from 'react-router-redux'

export {push, replace, go, goBack, goForward}
39 changes: 39 additions & 0 deletions app/scripts/actions/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const REQUEST = 'REQUEST'
const SUCCESS = 'SUCCESS'
const FAILURE = 'FAILURE'

export function createRequestTypes (base) {
const res = {}
const types = [REQUEST, SUCCESS, FAILURE]
types.forEach((type) => {
res[type] = `${base}_${type}`
})

return res
}

export function action (type, payload = {}) {
return {type, ...payload}
}

function createPageConstants (name) {
return {
LOAD: `LOAD_${name.toUpperCase()}_PAGE`,
LEAVE: `LEAVE_${name.toUpperCase()}_PAGE`
}
}

function createPageActions (name, consts) {
return {
load: () => action(consts.LOAD),
leave: () => action(consts.LEAVE)
}
}

export function createPage (name) {
const consts = createPageConstants(name)
return {
[name.toUpperCase()]: consts,
[name]: createPageActions(name, consts)
}
}
16 changes: 0 additions & 16 deletions app/scripts/app.js

This file was deleted.

44 changes: 44 additions & 0 deletions app/scripts/components/files/action-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, {Component, PropTypes} from 'react'
import {isEmpty} from 'lodash-es'

import Icon from '../../views/icon'

export default class ActionBar extends Component {
static propTypes = {
onCreateDir: PropTypes.func.isRequired,
onRemoveDir: PropTypes.func.isRequired,
selectedFiles: PropTypes.array.isRequired
};

render () {
const {selectedFiles, onRemoveDir, onCreateDir} = this.props
let fileActions

if (!isEmpty(selectedFiles)) {
const length = selectedFiles.length
const plural = length > 1 ? 's' : ''
const count = `${length} file${plural}`

fileActions = (
<div className='action-bar-file-actions'>
<a onClick={onRemoveDir}>
<Icon glyph='minus' />
Delete {count}
</a>
</div>
)
}

return (
<div className='action-bar'>
<div className='action-bar-general-actions'>
<a onClick={onCreateDir}>
<Icon glyph='plus' />
Create Folder
</a>
</div>
{fileActions}
</div>
)
}
}
91 changes: 91 additions & 0 deletions app/scripts/components/files/breadcrumbs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, {Component, PropTypes} from 'react'
import {chain, isEmpty, compact} from 'lodash-es'

import Icon from '../../views/icon'

class Breadcrumb extends Component {
static propTypes = {
path: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
text: PropTypes.string.isRequired
};

_onClick = (event) => {
this.props.onClick(this.props.path)
};

render () {
return (
<a
onClick={this._onClick}
className='crumb-link'>
{this.props.text}
</a>
)
}
}

export default class Breadcrumbs extends Component {
static propTypes = {
root: PropTypes.string,
setRoot: PropTypes.func.isRequired
};

static defaultProps = {
root: '/'
};

render () {
const {root} = this.props
const parts = {}
const partsList = compact(root.split('/'))
partsList.map((part, i) => {
if (i === partsList.length - 1) {
parts[part] = null
} else {
parts[part] = '/' + partsList.slice(0, i + 1).join('/')
}
})

const breadcrumbs = chain(parts)
.map((root, part) => {
if (!root) {
return [
<Icon key='last-0' glyph='angle-right' />,
<span key='last-1'>{part}</span>
]
}

return [
<Icon key={`${root}-0`} glyph='angle-right' />,
<Breadcrumb
key={`${root}-1`}
path={root}
onClick={this.props.setRoot}
text={part} />
]
})
.flatten()
.value()

if (isEmpty(partsList)) {
breadcrumbs.unshift(
<span key='-1'>IPFS</span>
)
} else {
breadcrumbs.unshift(
<Breadcrumb
key='-2'
path='/'
onClick={this.props.setRoot}
text='IPFS' />
)
}

return (
<div className='breadcrumbs'>
{breadcrumbs}
</div>
)
}
}
22 changes: 22 additions & 0 deletions app/scripts/components/files/context-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, {Component, PropTypes} from 'react'
import {ContextMenu, MenuItem} from 'react-contextmenu'

class FilesContextMenu extends Component {
static propTypes = {
selectedFiles: PropTypes.array.isRequired,
onRemoveDir: PropTypes.func
}

render () {
const {selectedFiles, onRemoveDir} = this.props
return (
<ContextMenu id='files-context-menu'>
<MenuItem onClick={onRemoveDir}>
{selectedFiles.length > 1 ? `Delete ${selectedFiles.length} files` : 'Delete'}
</MenuItem>
</ContextMenu>
)
}
}

export default FilesContextMenu
Loading

0 comments on commit c412657

Please sign in to comment.