// @flow import { remote } from 'electron'; import React, { Suspense, Fragment } from 'react'; import classnames from 'classnames'; import LoadingScreen from 'component/common/loading-screen'; import VideoViewer from 'component/viewers/videoViewer'; import ImageViewer from 'component/viewers/imageViewer'; import AppViewer from 'component/viewers/appViewer'; import Button from 'component/button'; import { withRouter } from 'react-router-dom'; import { formatLbryUrlForWeb } from 'util/url'; // @if TARGET='web' import { generateStreamUrl } from 'util/lbrytv'; // @endif import path from 'path'; import fs from 'fs'; import Yrbl from 'component/yrbl'; import DocumentViewer from 'component/viewers/documentViewer'; import PdfViewer from 'component/viewers/pdfViewer'; import HtmlViewer from 'component/viewers/htmlViewer'; // @if TARGET='app' import DocxViewer from 'component/viewers/docxViewer'; import ComicBookViewer from 'component/viewers/comicBookViewer'; import ThreeViewer from 'component/viewers/threeViewer'; // @endif type Props = { uri: string, mediaType: string, isText: true, streamingUrl: string, contentType: string, claim: StreamClaim, currentTheme: string, downloadPath: string, fileName: string, autoplay: boolean, nextFileToPlay: string, nextUnplayed: string, history: { push: string => void }, }; class FileRender extends React.PureComponent { constructor(props: Props) { super(props); (this: any).escapeListener = this.escapeListener.bind(this); (this: any).onEndedCb = this.onEndedCb.bind(this); } componentDidMount() { window.addEventListener('keydown', this.escapeListener, true); } componentWillUnmount() { window.removeEventListener('keydown', this.escapeListener, true); } escapeListener(e: SyntheticKeyboardEvent<*>) { if (e.keyCode === 27) { e.preventDefault(); this.exitFullscreen(); return false; } } exitFullscreen() { remote.getCurrentWindow().setFullScreen(false); } onEndedCb() { const { autoplay, nextUnplayed, history } = this.props; if (autoplay && nextUnplayed) { history.push(formatLbryUrlForWeb(nextUnplayed)); } } renderViewer() { const { mediaType, currentTheme, claim, contentType, downloadPath, fileName, streamingUrl, uri } = this.props; const fileType = fileName && path.extname(fileName).substring(1); // Ideally the lbrytv api server would just replace the streaming_url returned by the sdk so we don't need this check // https://github.com/lbryio/lbrytv/issues/51 const source = IS_WEB ? generateStreamUrl(claim.name, claim.claim_id) : streamingUrl; // Human-readable files (scripts and plain-text files) const readableFiles = ['text', 'document', 'script']; // Supported mediaTypes const mediaTypes = { // @if TARGET='app' '3D-file': , 'comic-book': , application: , // @endif video: , audio: , image: , // Add routes to viewer... }; // Supported contentTypes const contentTypes = { 'application/x-ext-mkv': ( ), 'video/x-matroska': ( ), 'application/pdf': , 'text/html': , 'text/htm': , }; // Supported fileType const fileTypes = { // @if TARGET='app' docx: , // @endif // Add routes to viewer... }; // Check for a valid fileType, mediaType, or contentType let viewer = (fileType && fileTypes[fileType]) || mediaTypes[mediaType] || contentTypes[contentType]; // Check for Human-readable files if (!viewer && readableFiles.includes(mediaType)) { viewer = ( fs.createReadStream(downloadPath, options), // @endif stream: source, fileType, contentType, }} theme={currentTheme} /> ); } // @if TARGET='web' // temp workaround to disabled paid content on web if (claim && claim.value.fee && Number(claim.value.fee.amount) > 0) { const paidMessage = __( 'Currently, only free content is available on lbry.tv. Try viewing it in the desktop app.' ); const paid = ; return paid; } // @endif const unsupported = IS_WEB ? (

{__('Good news, though! You can')}{' '}

) : (
); // Return viewer return viewer || unsupported; } render() { const { isText } = this.props; return (
}>{this.renderViewer()}
); } } export default withRouter(FileRender);