diff options
Diffstat (limited to 'app/client/common')
| -rw-r--r-- | app/client/common/browser.component.js | 18 | ||||
| -rw-r--r-- | app/client/common/fileList.component.js | 9 | ||||
| -rw-r--r-- | app/client/common/fileViewer.component.js | 111 |
3 files changed, 102 insertions, 36 deletions
diff --git a/app/client/common/browser.component.js b/app/client/common/browser.component.js index 50b31cf..19cd0f6 100644 --- a/app/client/common/browser.component.js +++ b/app/client/common/browser.component.js @@ -11,19 +11,23 @@ class Browser extends Component { state = { dir: '/', files: [], + file: null, loading: true } + componentDidMount() { this.fetch(this.state.dir) } + handlePick(file) { console.log(file) if (file.dir) { this.fetch([this.state.dir, file.name].join('/').replace('//','/')) } else { - this.fetchFile([this.state.dir, file.name].join('/').replace('//','/')) + this.setState({ file: { ...file, path: this.state.dir } }) } } + fetch(dir) { console.log('fetch', dir) const { tool: module } = this.props.app @@ -33,15 +37,7 @@ class Browser extends Component { this.setState({ dir, files, loading: false }) }) } - fetchFile(fn) { - console.log('fetch file', fn) - const { tool: module } = this.props.app - this.setState({ file: null, loadingFile: true }) - actions.socket.read_file({ module, fn }).then(file => { - console.log(file) - this.setState({ file, loadingFile: false }) - }) - } + render() { const { app } = this.props const { @@ -68,7 +64,7 @@ class Browser extends Component { }} onClickParent={e => { console.log('navigate up') - this.fetch(this.state.dir.split('/').slice(0, -1).join('/') || '/') + this.fetch(dir.split('/').slice(0, -1).join('/') || '/') }} /> {loadingFile && <Loading />} diff --git a/app/client/common/fileList.component.js b/app/client/common/fileList.component.js index f932274..8f79148 100644 --- a/app/client/common/fileList.component.js +++ b/app/client/common/fileList.component.js @@ -122,7 +122,14 @@ export const FileRow = props => { <div className={"date " + util.carbon_date(date)}>{moment(date).format("YYYY-MM-DD")}</div> } {fields.has('datetime') && - <div className={"datetime " + util.carbon_date(date)}>{moment(date).format("YYYY-MM-DD h:mm a")}</div> + <div className={"datetime"}> + <span class={'date ' + util.carbon_date(date)}> + {moment(date).format("YYYY-MM-DD")} + </span> + <span class={'time ' + util.carbon_time(date)}> + {moment(date).format("H:mm")} + </span> + </div> } {fields.has('size') && <div className={"size " + size[0]}>{size[1]}</div> diff --git a/app/client/common/fileViewer.component.js b/app/client/common/fileViewer.component.js index bc71f20..b1cabd4 100644 --- a/app/client/common/fileViewer.component.js +++ b/app/client/common/fileViewer.component.js @@ -1,4 +1,7 @@ import { h, Component } from 'preact' +import { connect } from 'react-redux' + +import actions from '../actions' const image_types = { 'jpg': 'image/jpeg', @@ -18,33 +21,85 @@ const video_types = { 'mp4': 'video/mp4', } -export default function FileViewer({ file }) { - const { - error, - name, path, - date, size, - buf, - } = file - if (error) { - return <div className='fileViewer'>{error}</div> +class FileViewer extends Component { + state = { + loading: false, + stale: false, + buffer: {} + } + + fetch() { + const { file, path } = this.props + if (!file) return + if (this.state.loading) { + this.setState({ stale: true }) + return + } + const fn = [path || file.path, file.name].join('/').replace('//','/') + console.log('fetch file', fn) + const { tool: module } = this.props.app + this.setState({ buffer: null, loading: true }) + actions.socket.read_file({ module, fn }).then(buffer => { + console.log('fetched buffer') + const { stale } = this.state + this.setState({ buffer, loading: false, stale: false, }, () => { + if (stale) { + console.log('stale, fetching...') + this.fetch() + } + }) + }) + } + + componentDidMount(){ + this.fetch() } - if (!buf) { - return <div className='fileViewer'>File empty</div> + + componentDidUpdate(nextProps){ + if (this.props.file !== nextProps.file) { + this.fetch() + } } - const ext = name.split('.').slice(-1)[0].toLowerCase() - let tag; - if (ext in image_types) { - tag = <img src={getURLFor(buf, image_types[ext])} /> - } else if (ext in audio_types) { - tag = <audio src={getURLFor(buf, audio_types[ext])} controls autoplay /> - } else if (ext in video_types) { - tag = <video src={getURLFor(buf, audio_types[ext])} controls autoplay /> - } else { - tag = <div className='text'>{ab2str(buf)}</div> + + render() { + const { file } = this.props + if (!file) { + return <div className='fileViewer'></div> + } + const { loading, buffer } = this.state + if (loading) { + return <div className='fileViewer'>Loading...</div> + } + const { + error, + name, path, + date, size, + buf, + } = buffer + if (error) { + return <div className='fileViewer'>{error}</div> + } + if (!name) { + return <div className='fileViewer'></div> + } + if (!buf) { + return <div className='fileViewer'>File empty</div> + } + const ext = extension(name) + let tag; + if (ext in image_types) { + tag = <img src={getURLFor(buf, image_types[ext])} /> + } else if (ext in audio_types) { + tag = <audio src={getURLFor(buf, audio_types[ext])} controls autoplay /> + } else if (ext in video_types) { + tag = <video src={getURLFor(buf, video_types[ext])} controls autoplay /> + } else { + tag = <div className='text'>{ab2str(buf)}</div> + } + return ( + <div className='fileViewer'>{tag}</div> + ) } - return ( - <div className='fileViewer'>{tag}</div> - ) } const getURLFor = (buf, type) => { @@ -55,3 +110,11 @@ const getURLFor = (buf, type) => { } const ab2str = buf => String.fromCharCode.apply(null, new Uint8Array(buf)) + +const extension = fn => fn.split('.').slice(-1)[0].toLowerCase() + +const mapStateToProps = state => ({ + app: state.system.app, +}) + +export default connect(mapStateToProps)(FileViewer) |
