Merge pull request #2484 from lbryio/comicbook-reader

Comic-book reader
This commit is contained in:
Sean Yesmunt 2019-05-24 12:18:24 -04:00 committed by GitHub
commit d15a85eaaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 96 additions and 4 deletions

View file

@ -172,6 +172,7 @@
"three-full": "^17.1.0",
"tree-kill": "^1.1.0",
"video.js": "^7.2.2",
"villain": "btzr-io/Villain",
"wavesurfer.js": "^2.2.1",
"webpack": "^4.28.4",
"webpack-bundle-analyzer": "^3.1.0",

View file

@ -30,6 +30,11 @@ const PdfViewer = React.lazy<*>(() =>
);
// @if TARGET='app'
const ComicBookViewer = React.lazy<*>(() =>
import(/* webpackChunkName: "comicBookViewer" */
'component/viewers/comicBookViewer')
);
const ThreeViewer = React.lazy<*>(() =>
import(/* webpackChunkName: "threeViewer" */
'component/viewers/threeViewer')
@ -128,6 +133,7 @@ class FileRender extends React.PureComponent<Props> {
const mediaTypes = {
// @if TARGET='app'
'3D-file': <ThreeViewer source={{ fileType, downloadPath }} theme={currentTheme} />,
'comic-book': <ComicBookViewer source={{ fileType, downloadPath }} theme={currentTheme} />,
// @endif
application: !source.url ? null : (

View file

@ -351,7 +351,6 @@ class MediaPlayer extends React.PureComponent<Props, State> {
render() {
const { mediaType, claim } = this.props;
const { fileSource } = this.state;
const isFileType = this.isSupportedFile();
const isFileReady = fileSource && isFileType;

View file

@ -0,0 +1,28 @@
// @flow
import * as React from 'react';
import Villain from 'villain';
import 'villain/dist/style.css';
type Props = {
source: {
fileType: string,
downloadPath: string,
},
};
const opts = {
workerPath: '/webworkers/worker-bundle.js',
allowFullScreen: false,
autoHideControls: true,
};
class ComicBookViewer extends React.PureComponent<Props> {
render() {
const { downloadPath } = this.props.source || {};
const file = `file://${downloadPath}`;
return <Villain file={file} width={'100%'} height={'100%'} options={opts} />;
}
}
export default ComicBookViewer;

View file

@ -56,6 +56,7 @@ class FilePage extends React.Component<Props> {
'script',
'document',
'3D-file',
'comic-book',
// Bypass unplayable files
// TODO: Find a better way to detect supported types
'application',

View file

@ -7,6 +7,7 @@ const formats = [
[/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'],
[/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'],
[/\.(stl|obj|fbx|gcode)$/i, '3D-file'],
[/\.(cbr|cbt|cbz)$/i, 'comic-book'],
];
export default function getMediaType(contentType, fileName) {

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -0,0 +1,10 @@
/*
This webworker bundle is part of the libarchive.js module,
so we need to make sure that it is available in the public (static) directory,
since it will not get bundled if you're using a bundler tool such as webpack
(it's all bundled up already) and specify the correct path in Archive.init() method.
https://github.com/nika-begiashvili/libarchivejs#how-to-use
*/
!function(){"use strict";const e={32768:"FILE",16384:"DIR",40960:"SYMBOLIC_LINK",49152:"SOCKET",8192:"CHARACTER_DEVICE",24576:"BLOCK_DEVICE",4096:"NAMED_PIPE"};class t{constructor(e){this._wasmModule=e,this._runCode=e.runCode,this._file=null}open(e){null!==this._file&&(console.warn("Closing previous file"),this.close());const{promise:t,resolve:r,reject:s}=this._promiseHandles();this._file=e;const i=new FileReader;return i.onload=(()=>this._loadFile(i.result,r,s)),i.readAsArrayBuffer(e),t}close(){this._runCode.closeArchive(this._archive),this._wasmModule._free(this._filePtr),this._file=null,this._filePtr=null,this._archive=null}*entries(t=!1,r=null){let s;for(this._archive=this._runCode.openArchive(this._filePtr,this._fileLength);0!==(s=this._runCode.getNextEntry(this._archive));){const i={size:this._runCode.getEntrySize(s),path:this._runCode.getEntryName(s),type:e[this._runCode.getEntryType(s)],ref:s};if("FILE"===i.type){let e=i.path.split("/");i.fileName=e[e.length-1]}if(t&&r!==i.path)this._runCode.skipEntry(this._archive);else{const e=this._runCode.getFileData(this._archive,i.size);if(e<0)throw new Error(this._runCode.getError(this._archive));i.fileData=this._wasmModule.HEAP8.slice(e,e+i.size),this._wasmModule._free(e)}yield i}}_loadFile(e,t,r){try{const s=new Uint8Array(e);this._fileLength=s.length,this._filePtr=this._runCode.malloc(this._fileLength),this._wasmModule.HEAP8.set(s,this._filePtr),t()}catch(e){r(e)}}_promiseHandles(){let e=null,t=null;return{promise:new Promise((r,s)=>{e=r,t=s}),resolve:e,reject:t}}}self.Module=new class{constructor(){this.preRun=[],this.postRun=[],this.totalDependencies=0}onRuntimeInitialized(){this.runCode={getVersion:Module.cwrap("get_version","string",[]),openArchive:Module.cwrap("archive_open","number",["number","number"]),getNextEntry:Module.cwrap("get_next_entry","number",["number"]),getFileData:Module.cwrap("get_filedata","number",["number","number"]),skipEntry:Module.cwrap("archive_read_data_skip","number",["number"]),closeArchive:Module.cwrap("archive_close",null,["number"]),getEntrySize:Module.cwrap("archive_entry_size","number",["number"]),getEntryName:Module.cwrap("archive_entry_pathname","string",["number"]),getEntryType:Module.cwrap("archive_entry_filetype","number",["number"]),getError:Module.cwrap("archive_error_string","string",["number"]),malloc:Module.cwrap("malloc","number",["number"]),free:Module.cwrap("free",null,["number"])},this.ready&&this.ready()}print(...e){console.log(e)}printErr(...e){console.error(e)}monitorRunDependencies(e){}locateFile(e,t=""){return`wasm-gen/${t}${e}`}},importScripts("wasm-gen/libarchive.js");let r=null,s=!1;self.Module.ready=(()=>{r=new t(self.Module),s=!1,self.postMessage({type:"READY"})}),self.onmessage=(async({data:e})=>{if(s)return void self.postMessage({type:"BUSY"});let t=!1;s=!0;try{switch(e.type){case"HELLO":break;case"OPEN":await r.open(e.file),self.postMessage({type:"OPENED"});break;case"LIST_FILES":t=!0;case"EXTRACT_FILES":for(const e of r.entries(t))self.postMessage({type:"ENTRY",entry:e});self.postMessage({type:"END"});break;case"EXTRACT_SINGLE_FILE":for(const t of r.entries(!0,e.target))t.fileData&&self.postMessage({type:"FILE",entry:t});break;default:throw new Error("Invalid Command")}}catch(e){self.postMessage({type:"ERROR",error:{message:e.message,name:e.name,stack:e.stack}})}finally{s=!1}})}();

View file

@ -762,7 +762,7 @@
pirates "^4.0.0"
source-map-support "^0.5.9"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.3":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
@ -2484,6 +2484,11 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
clsx@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.0.4.tgz#0c0171f6d5cb2fe83848463c15fcc26b4df8c2ec"
integrity sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg==
coa@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
@ -3226,6 +3231,11 @@ cyclist@~0.2.2:
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
d3-array@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f"
integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==
damerau-levenshtein@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz#780cf7144eb2e8dbd1c3bb83ae31100ccc31a414"
@ -6598,6 +6608,11 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
libarchive.js@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/libarchive.js/-/libarchive.js-1.1.0.tgz#8cc21a5a8ee59e5a02ce6eb966e140a7a44622bc"
integrity sha512-vh0dHBPK00ggbmTupqFWfws46a5QO/S5ZQ36Ymdyo4R93crXewXKJpYDpC/HROgOofvO8ogDdOLmU5MX8xGfmQ==
lie@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
@ -7893,6 +7908,11 @@ opener@^1.5.1:
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
openseadragon@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/openseadragon/-/openseadragon-2.4.0.tgz#d0b28b37a953602c82432a0dbd8a3779dadf756f"
integrity sha512-e2fsoEiCDkmwc3vyrv396lkYu4c9CGlpbSX4kYE07eW0ZlEF5DnLbeY2PhqPTskkC1jlsPu2TGZwaZ9VhaAn/w==
opn@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
@ -9340,7 +9360,17 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.1, rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@^16.8.2:
react-compound-slider@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/react-compound-slider/-/react-compound-slider-1.2.2.tgz#1cc6809bb2d0282ad90a06040e2b10635edfbea3"
integrity sha512-G2wD5CTjAOTjCnslpfjopB5qU6Kg0//3ChPifezSGtMali/1M/CRDCJAh6SQOgyDaQlNi/QV1Noo8Tvnjy2gcg==
dependencies:
"@babel/runtime" "^7.4.3"
d3-array "^1.2.4"
prop-types "^15.7.2"
warning "^3.0.0"
react-dom@^16.8.2, react-dom@^16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
@ -9468,7 +9498,7 @@ react-toggle@^4.0.2:
dependencies:
classnames "^2.2.5"
react@^16.8.2:
react@^16.8.2, react@^16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
@ -11774,6 +11804,18 @@ videostream@^2.5.1:
pump "^3.0.0"
range-slice-stream "^2.0.0"
villain@btzr-io/Villain:
version "0.0.7"
resolved "https://codeload.github.com/btzr-io/Villain/tar.gz/1f39a679cd78b08f8acc0b36615550eb91f6ee03"
dependencies:
clsx "^1.0.4"
libarchive.js "^1.1.0"
openseadragon "^2.4.0"
prop-types "^15.7.2"
react "^16.8.6"
react-compound-slider "^1.2.2"
react-dom "^16.8.6"
vm-browserify@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"