diff --git a/frontend/src/js/component/wb-collection-content.js b/frontend/src/js/component/wb-collection-content.js index ea419a0..05c3caa 100644 --- a/frontend/src/js/component/wb-collection-content.js +++ b/frontend/src/js/component/wb-collection-content.js @@ -75,9 +75,13 @@ class WBCollectionContent extends Component { }); } - prom_1 = prom_1.then(e => this.setState({ - 'mode': 'browsingReady' - })); + prom_1 = prom_1.then(() => manifestWorker.postMessage([ 'listDirectory', + '.' + this.props.collectionPath, true ])); + + prom_1 = prom_1.then(e => { + this.state.mode = 'browsingReady'; + this.prepareRows(e.data[1]); + }); return prom_1; }); diff --git a/frontend/src/js/misc/wb-manifest-worker-wrapper.js b/frontend/src/js/misc/wb-manifest-worker-wrapper.js index c165fd1..891ad55 100644 --- a/frontend/src/js/misc/wb-manifest-worker-wrapper.js +++ b/frontend/src/js/misc/wb-manifest-worker-wrapper.js @@ -9,13 +9,16 @@ class WBManifestWorkerWrapper { onMessage(e) { if (this.queue.length === 0) throw Error('Unexpected message from worker'); - const accept = this.queue.splice(0, 1)[0]; - accept(e); + const [msgType, accept, reject] = this.queue.splice(0, 1)[0]; + if (e.data[0] === msgType + 'Result') + accept(e); + else + reject(e); } postMessage(m) { - const prom = new Promise(accept => { - this.queue.push(accept); + const prom = new Promise((accept, reject) => { + this.queue.push([ m[0], accept, reject ]); this.worker.postMessage(m); }); return prom; diff --git a/frontend/src/js/worker/wb-manifest-worker.js b/frontend/src/js/worker/wb-manifest-worker.js index 65ba1bd..d9138ce 100644 --- a/frontend/src/js/worker/wb-manifest-worker.js +++ b/frontend/src/js/worker/wb-manifest-worker.js @@ -4,23 +4,28 @@ const streams = []; onmessage = function(e) { switch (e.data[0]) { - case 'precreatePaths': - precreatePaths(e.data[1]); - postMessage([ 'precreatePathsResult' ]); - break; - case 'parseStream': - parseStream(e.data[1]); - postMessage([ 'parseStreamResult' ]); - break; - case 'listDirectory': { - const lst = listDirectory(rootDir, e.data[1], e.data[2]); - postMessage([ 'listDirectoryResult', lst ]) - break; } - case 'getData': { - postMessage([ 'getDataResult', rootDir, streams ]); - break; } - default: - throw Error('Unknown verb: ' + e.data[0]); + case 'precreatePaths': + precreatePaths(e.data[1]); + postMessage([ 'precreatePathsResult' ]); + break; + case 'parseStream': + parseStream(e.data[1]); + postMessage([ 'parseStreamResult' ]); + break; + case 'listDirectory': { + const lst = listDirectory(rootDir, e.data[1], e.data[2]); + postMessage([ 'listDirectoryResult', lst ]) + break; } + case 'getData': + postMessage([ 'getDataResult', rootDir, streams ]); + break; + case 'getFile': + postMessage([ 'getFileResult', getFile(rootDir, streams, e.data[1]) ]); + break; + default: { + const err = Error('Unknown verb: ' + e.data[0]); + postMessage([ 'error', err.message ]); + throw err; } } } @@ -141,3 +146,41 @@ function listDirectory(rootDir, path, lenient=false) { res = res.concat(files.map(k => [ 'f', k, dir[k][1] ])); return res; } + +function getFile(rootDir, streams, path) { + if (typeof(path) === 'string') + path = path.split('/'); + + if (path.length < 2) + throw Error('Invalid file path'); + + const name = path[path.length - 1]; + + const dir = findDir(rootDir, path.slice(0, path.length - 1)); + + if (!(name in dir)) + throw Error('File not found'); + + if (!(dir[name] instanceof Array)) + throw Error('Path points to a directory not a file'); + + let file = dir[name]; + file = [ file[0].map(seg => { + const stm = streams[seg[0]]; + const used = stm.map(loc => !( loc[2] <= seg[1] || loc[1] >= seg[1] + seg[2] ) ); + const start = used.indexOf(true); + const end = used.lastIndexOf(true) + 1; + if (start === -1) + return []; + const res = []; + for (let i = start; i < end; i++) { + const loc = stm[i]; + res.push([ loc[0], Math.max(0, seg[1] - loc[1]), + Math.min(loc[2] - loc[1], seg[1] + seg[2] - loc[1]) ]); + } + return res; + }), file[1] ]; + file[0] = file[0].reduce((a, b) => a.concat(b)); + + return file; +}