import { h, Component } from 'preact' import { connect } from 'react-redux' import actions from '../actions' const image_types = { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'gif': 'image/gif', } const audio_types = { 'wav': 'audio/wav', 'mp3': 'audio/mp3', 'flac': 'audio/flac', 'aiff': 'audio/aiff', } const video_types = { 'mp4': 'video/mp4', } const THROTTLE_FETCH_TIME = 200 class FileViewer extends Component { state = { loading: false, stale: false, buffer: {}, url: null, } componentDidMount(){ this.fetch() } componentDidUpdate(prevProps){ if (this.props.file !== prevProps.file) { this.deferFetch() } } componentWillUnmount(){ if (this.state.url) { window.URL.revokeObjectURL(this.state.url) } } deferFetch(){ clearTimeout(this.timeout) this.timeout = setTimeout(() => { this.fetch() }, THROTTLE_FETCH_TIME) } fetch() { const { file, path, thumbnail } = this.props if (!file) return if (this.state.loading) { this.setState({ stale: true }) return } const fn = [path || file.path, file.name].join('/').replace('//','/') const { tool: module } = this.props.app this.setState({ buffer: null, loading: true }) if (thumbnail) { // console.log('fetch thumbnail', fn) const size = parseInt(thumbnail) || 200 actions.socket .thumbnail({ module, fn, size }) .then(this.loadBuffer.bind(this)) } else { // console.log('fetch file', fn) actions.socket .read_file({ module, fn }) .then(this.loadBuffer.bind(this)) } } loadBuffer(buffer) { // console.log('fetched buffer', buffer) const { name, buf } = buffer const ext = extension(name) if (this.state.url) { window.URL.revokeObjectURL(this.state.url) } let url if (buf) { if (ext in image_types) { url = getURLFor(buf, image_types[ext]) } else if (ext in audio_types) { url = getURLFor(buf, audio_types[ext]) } else if (ext in video_types) { url = getURLFor(buf, video_types[ext]) } else { url = ab2str(buf) } } const { stale } = this.state this.setState({ ext, url, buffer, loading: false, stale: false, }, () => { // console.log('loaded') if (stale) { // console.log('stale, fetching...') this.fetch() } }) } render() { const { file } = this.props if (!file) { return
} const { loading, buffer, url, ext } = this.state if (loading) { return
Loading...
} const { error, name, path, date, size, buf, } = buffer if (error) { return
{error}
} if (!name) { return
} if (!buf || !url) { return
File empty
} let tag; if (ext in image_types) { tag = } else if (ext in audio_types) { tag =