Skip to content

Commit

Permalink
create AppViewer for .lbry files
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean Yesmunt committed Aug 6, 2019
1 parent 0b897c3 commit cb7fb90
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 121 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"jsmediatags": "^3.8.1",
"json-loader": "^0.5.4",
"lbry-format": "https://github.com/lbryio/lbry-format.git",
"lbry-redux": "lbryio/lbry-redux#66f70c7745d23e79f9e8ec9ca32ef9d3a576688e",
"lbry-redux": "lbryio/lbry-redux#d2c0d999d6909a6ebb80a318052d0358e12048ee",
"lbryinc": "lbryio/lbryinc#a93596c51c8fb0a226cb84df04c26a6bb60a45fb",
"lint-staged": "^7.0.2",
"localforage": "^1.7.1",
Expand Down
10 changes: 2 additions & 8 deletions src/ui/component/fileActions/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,18 @@ import React from 'react';
import Button from 'component/button';
import Tooltip from 'component/common/tooltip';

type FileInfo = {
claim_id: string,
};

type Props = {
uri: string,
claimId: string,
openModal: (id: string, { uri: string }) => void,
claimIsMine: boolean,
fileInfo: FileInfo,
fileInfo: FileListItem,
};

class FileActions extends React.PureComponent<Props> {
render() {
const { fileInfo, uri, openModal, claimIsMine, claimId } = this.props;
const showDelete = claimIsMine || (fileInfo && Object.keys(fileInfo).length > 0);
// fix me
// const showDelete = claimIsMine || (fileInfo && fileInfo.writtenBytes > 0 || fileInfo.blobs_completed;
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed === true));

return (
<React.Fragment>
Expand Down
5 changes: 2 additions & 3 deletions src/ui/component/fileDownloadLink/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@ import {
makeSelectDownloadingForUri,
makeSelectLoadingForUri,
makeSelectClaimIsMine,
makeSelectUriIsStreamable,
} from 'lbry-redux';
import { doOpenModal } from 'redux/actions/app';
import { doSetPlayingUri } from 'redux/actions/content';
import { doSetPlayingUri, doPlayUri } from 'redux/actions/content';
import FileDownloadLink from './view';

const select = (state, props) => ({
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
downloading: makeSelectDownloadingForUri(props.uri)(state),
loading: makeSelectLoadingForUri(props.uri)(state),
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
isStreamable: makeSelectUriIsStreamable(props.uri)(state),
});

const perform = dispatch => ({
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
pause: () => dispatch(doSetPlayingUri(null)),
download: uri => dispatch(doPlayUri(uri, false, true)),
});

export default connect(
Expand Down
23 changes: 18 additions & 5 deletions src/ui/component/fileDownloadLink/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ import Button from 'component/button';
import ToolTip from 'component/common/tooltip';

type Props = {
uri: string,
claimIsMine: boolean,
downloading: boolean,
loading: boolean,
isStreamable: boolean,
fileInfo: ?FileInfo,
fileInfo: ?FileListItem,
openModal: (id: string, { path: string }) => void,
pause: () => void,
download: string => void,
};

function FileDownloadLink(props: Props) {
const { fileInfo, downloading, loading, openModal, pause, claimIsMine, isStreamable } = props;
const { fileInfo, downloading, loading, openModal, pause, claimIsMine, download, uri } = props;

if (!isStreamable && (loading || downloading)) {
if (loading || downloading) {
const progress = fileInfo && fileInfo.written_bytes > 0 ? (fileInfo.written_bytes / fileInfo.total_bytes) * 100 : 0;
const label =
fileInfo && fileInfo.written_bytes > 0
Expand All @@ -32,6 +34,7 @@ function FileDownloadLink(props: Props) {
return (
<ToolTip label={__('Open file')}>
<Button
title="Remove from library"
button="link"
icon={ICONS.EXTERNAL}
onClick={() => {
Expand All @@ -41,9 +44,19 @@ function FileDownloadLink(props: Props) {
/>
</ToolTip>
);
} else {
return (
<ToolTip label={__('Add to your library')}>
<Button
button="link"
icon={ICONS.DOWNLOAD}
onClick={() => {
download(uri);
}}
/>
</ToolTip>
);
}

return null;
}

export default FileDownloadLink;
85 changes: 9 additions & 76 deletions src/ui/component/fileRender/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { remote } from 'electron';
import React, { Suspense } from 'react';
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 path from 'path';
import fs from 'fs';

Expand Down Expand Up @@ -59,13 +61,14 @@ const ThreeViewer = React.lazy<*>(() =>
// @endif

type Props = {
uri: string,
mediaType: string,
streamingUrl: string,
contentType: string,
claim: StreamClaim,
currentTheme: string,
downloadPath?: string,
fileName?: string,
downloadPath: string,
fileName: string,
};

class FileRender extends React.PureComponent<Props> {
Expand All @@ -77,64 +80,12 @@ class FileRender extends React.PureComponent<Props> {

componentDidMount() {
window.addEventListener('keydown', this.escapeListener, true);

// ugh
// const { claim, streamingUrl, fileStatus, fileName, downloadPath, downloadCompleted, contentType } = this.props;
// if(MediaPlayer.SANDBOX_TYPES.indexOf(contentType) > -1) {
// const outpoint = `${claim.txid}:${claim.nout}`;
// // Fetch unpacked url
// fetch(`${MediaPlayer.SANDBOX_SET_BASE_URL}${outpoint}`)
// .then(res => res.text())
// .then(url => {
// const source = {url: `${MediaPlayer.SANDBOX_CONTENT_BASE_URL}${url}`};
// this.setState({source});
// })
// .catch(err => {
// console.error(err);
// });
// } else {
// File to render
}

componentWillUnmount() {
window.removeEventListener('keydown', this.escapeListener, true);
}

// This should use React.createRef()
// processSandboxRef(element: any) {
// if (!element) {
// return;
// }

// window.sandbox = element;

// element.addEventListener('permissionrequest', e => {
// console.log('permissionrequest', e);
// });

// element.addEventListener('console-message', (e: { message: string }) => {
// if (/^\$LBRY_IPC:/.test(e.message)) {
// // Process command
// let message = {};
// try {
// // $FlowFixMe
// message = JSON.parse(/^\$LBRY_IPC:(.*)/.exec(e.message)[1]);
// } catch (err) {}
// console.log('IPC', message);
// } else {
// console.log('Sandbox:', e.message);
// }
// });

// element.addEventListener('enter-html-full-screen', () => {
// // stub
// });

// element.addEventListener('leave-html-full-screen', () => {
// // stub
// });
// }

escapeListener(e: SyntheticKeyboardEvent<*>) {
if (e.keyCode === 27) {
e.preventDefault();
Expand All @@ -150,7 +101,7 @@ class FileRender extends React.PureComponent<Props> {
}

renderViewer() {
const { mediaType, currentTheme, claim, contentType, downloadPath, fileName, streamingUrl } = this.props;
const { mediaType, currentTheme, claim, contentType, downloadPath, fileName, streamingUrl, uri } = this.props;

const fileType = fileName && path.extname(fileName).substring(1);

Expand All @@ -162,30 +113,12 @@ class FileRender extends React.PureComponent<Props> {
// @if TARGET='app'
'3D-file': <ThreeViewer source={{ fileType, downloadPath }} theme={currentTheme} />,
'comic-book': <ComicBookViewer source={{ fileType, downloadPath }} theme={currentTheme} />,
// application: !source.url ? null : (
// <webview
// ref={element => this.processSandboxRef(element)}
// title=""
// sandbox="allow-scripts allow-forms allow-pointer-lock"
// src={source.url}
// autosize="on"
// style={{ border: 0, width: '100%', height: '100%' }}
// useragent="Mozilla/5.0 AppleWebKit/537 Chrome/60 Safari/537"
// enableremotemodule="false"
// webpreferences="sandbox=true,contextIsolation=true,webviewTag=false,enableRemoteModule=false,devTools=false"
// />
// ),
application: <AppViewer uri={uri} />,
// @endif

video: <VideoViewer source={streamingUrl} contentType={contentType} />,
audio: <VideoViewer source={streamingUrl} contentType={contentType} />,
// audio: (
// <AudioViewer
// claim={claim}
// source={{ url: streamingUrl, downloadPath, downloadCompleted, status }}
// contentType={contentType}
// />
// ),
image: <ImageViewer source={streamingUrl} />,
// Add routes to viewer...
};

Expand All @@ -198,7 +131,7 @@ class FileRender extends React.PureComponent<Props> {
};

// Check for a valid fileType or mediaType
let viewer = fileTypes[fileType] || mediaTypes[mediaType];
let viewer = fileType ? fileTypes[fileType] : mediaTypes[mediaType];

// Check for Human-readable files
if (!viewer && readableFiles.includes(mediaType)) {
Expand Down
2 changes: 1 addition & 1 deletion src/ui/component/fileViewer/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Props = {
mediaType: string,
isLoading: boolean,
isPlaying: boolean,
fileInfo: FileInfo,
fileInfo: FileListItem,
uri: string,
obscurePreview: boolean,
insufficientCredits: boolean,
Expand Down
15 changes: 15 additions & 0 deletions src/ui/component/viewers/appViewer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectContentTypeForUri } from 'lbry-redux';
import AppViewer from './view';

const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
contentType: makeSelectContentTypeForUri(props.uri)(state),
});

const perform = dispatch => ({});

export default connect(
select,
perform
)(AppViewer);
61 changes: 61 additions & 0 deletions src/ui/component/viewers/appViewer/view.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// @flow
import React, { useState, useEffect } from 'react';
import LoadingScreen from 'component/common/loading-screen';

type Props = {
source: string,
claim: StreamClaim,
contentType: string,
};

const SANDBOX_TYPES = ['application/x-lbry', 'application/x-ext-lbry'];

// This server exists in src/platforms/electron/startSandBox.js
const SANDBOX_SET_BASE_URL = 'http://localhost:5278/set/';
const SANDBOX_CONTENT_BASE_URL = 'http://localhost:5278';

function AppViewer(props: Props) {
const { claim, contentType } = props;
const [loading, setLoading] = useState(true);
const [appUrl, setAppUrl] = useState(false);

const outpoint = `${claim.txid}:${claim.nout}`;
useEffect(() => {
if (SANDBOX_TYPES.indexOf(contentType) > -1) {
fetch(`${SANDBOX_SET_BASE_URL}${outpoint}`)
.then(res => res.text())
.then(url => {
const appUrl = `${SANDBOX_CONTENT_BASE_URL}${url}`;
setAppUrl(appUrl);
setLoading(false);
})
.catch(err => {
setLoading(false);
});
} else {
setLoading(false);
}
}, [outpoint, contentType, setAppUrl, setLoading]);

return (
<div className="file-render__viewer">
{!appUrl && (
<LoadingScreen status={loading ? __('Almost there') : __('Unable to view this file')} spinner={loading} />
)}
{appUrl && (
<webview
title=""
sandbox="allow-scripts allow-forms allow-pointer-lock"
src={appUrl}
autosize="on"
style={{ border: 0, width: '100%', height: '100%' }}
useragent="Mozilla/5.0 AppleWebKit/537 Chrome/60 Safari/537"
enableremotemodule="false"
webpreferences="sandbox=true,contextIsolation=true,webviewTag=false,enableRemoteModule=false,devTools=false"
/>
)}
</div>
);
}

export default AppViewer;
17 changes: 17 additions & 0 deletions src/ui/component/viewers/imageViewer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @flow
import React from 'react';

type Props = {
source: string,
};

function ImageViewer(props: Props) {
const { source } = props;
return (
<div className="file-render__viewer">
<img src={source} />
</div>
);
}

export default ImageViewer;
Loading

0 comments on commit cb7fb90

Please sign in to comment.