commit
1fc7c92524
9 changed files with 100 additions and 58 deletions
22
app/package-lock.json
generated
22
app/package-lock.json
generated
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "LBRY",
|
"name": "LBRY",
|
||||||
"version": "0.12.0rc6",
|
"version": "0.12.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": {
|
"commander": {
|
||||||
|
@ -63,11 +63,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.6.0.tgz",
|
||||||
"integrity": "sha1-Umao9J3Zib5Pn2gbbyoMVShdDZo="
|
"integrity": "sha1-Umao9J3Zib5Pn2gbbyoMVShdDZo="
|
||||||
},
|
},
|
||||||
"modify-filename": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE="
|
|
||||||
},
|
|
||||||
"npm": {
|
"npm": {
|
||||||
"version": "4.6.1",
|
"version": "4.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/npm/-/npm-4.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/npm/-/npm-4.6.1.tgz",
|
||||||
|
@ -1456,16 +1451,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"path-exists": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
|
||||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
|
||||||
},
|
|
||||||
"pupa": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pupa/-/pupa-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-mpVopa9+ZXuEYqbp1TKHQ1YM7/Y="
|
|
||||||
},
|
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||||
|
@ -1480,11 +1465,6 @@
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.1.0.tgz",
|
||||||
"integrity": "sha1-yWPc8DciiS7FnLpWnpQLcZVNFyk="
|
"integrity": "sha1-yWPc8DciiS7FnLpWnpQLcZVNFyk="
|
||||||
},
|
|
||||||
"unused-filename": {
|
|
||||||
"version": "0.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-0.1.0.tgz",
|
|
||||||
"integrity": "sha1-5fM7yeSmP4f2TTwR0xl53vXS5/s="
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export function doFetchCostInfoForUri(uri) {
|
||||||
claim = selectClaimsByUri(state)[uri],
|
claim = selectClaimsByUri(state)[uri],
|
||||||
isGenerous = selectSettingsIsGenerous(state);
|
isGenerous = selectSettingsIsGenerous(state);
|
||||||
|
|
||||||
if (!claim) return null
|
if (!claim) return null;
|
||||||
|
|
||||||
function begin() {
|
function begin() {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import {
|
import { connect } from "react-redux";
|
||||||
connect
|
import { doUserEmailNew } from "actions/user";
|
||||||
} from 'react-redux'
|
|
||||||
import {
|
|
||||||
doUserEmailNew
|
|
||||||
} from 'actions/user'
|
|
||||||
import {
|
import {
|
||||||
selectEmailNewIsPending,
|
selectEmailNewIsPending,
|
||||||
selectEmailNewErrorMessage,
|
selectEmailNewErrorMessage,
|
||||||
} from 'selectors/user'
|
} from "selectors/user";
|
||||||
import UserEmailNew from './view'
|
import UserEmailNew from "./view";
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = state => ({
|
||||||
isPending: selectEmailNewIsPending(state),
|
isPending: selectEmailNewIsPending(state),
|
||||||
errorMessage: selectEmailNewErrorMessage(state),
|
errorMessage: selectEmailNewErrorMessage(state),
|
||||||
})
|
});
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = dispatch => ({
|
||||||
addUserEmail: (email) => dispatch(doUserEmailNew(email))
|
addUserEmail: email => dispatch(doUserEmailNew(email)),
|
||||||
})
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserEmailNew)
|
export default connect(select, perform)(UserEmailNew);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const LoadingScreen = ({ status }) =>
|
const LoadingScreen = ({ status, spinner = true }) =>
|
||||||
<div className="video__loading-screen">
|
<div className="video__loading-screen">
|
||||||
<div>
|
<div>
|
||||||
<div className="video__loading-spinner" />
|
{spinner && <div className="video__loading-spinner" />}
|
||||||
|
|
||||||
<div className="video__loading-status">
|
<div className="video__loading-status">
|
||||||
{status}
|
{status}
|
||||||
|
|
|
@ -2,30 +2,97 @@ import React from "react";
|
||||||
import { Thumbnail } from "component/common";
|
import { Thumbnail } from "component/common";
|
||||||
import player from "render-media";
|
import player from "render-media";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import LoadingScreen from "./loading-screen";
|
||||||
|
|
||||||
class VideoPlayer extends React.PureComponent {
|
class VideoPlayer extends React.PureComponent {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
hasMetadata: false,
|
||||||
|
startedPlaying: false,
|
||||||
|
unplayable: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const elem = this.refs.media;
|
const container = this.refs.media;
|
||||||
|
const { mediaType } = this.props;
|
||||||
|
const loadedMetadata = e => {
|
||||||
|
this.setState({ hasMetadata: true, startedPlaying: true });
|
||||||
|
this.refs.media.children[0].play();
|
||||||
|
};
|
||||||
|
const renderMediaCallback = err => {
|
||||||
|
if (err) this.setState({ unplayable: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
player.append(
|
||||||
|
this.file(),
|
||||||
|
container,
|
||||||
|
{ autoplay: false, controls: true },
|
||||||
|
renderMediaCallback.bind(this)
|
||||||
|
);
|
||||||
|
|
||||||
|
const mediaElement = this.refs.media.children[0];
|
||||||
|
if (mediaElement) {
|
||||||
|
mediaElement.addEventListener(
|
||||||
|
"loadedmetadata",
|
||||||
|
loadedMetadata.bind(this),
|
||||||
|
{
|
||||||
|
once: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { mediaType, downloadCompleted } = this.props;
|
||||||
|
const { startedPlaying } = this.state;
|
||||||
|
|
||||||
|
if (this.playableType() && !startedPlaying && downloadCompleted) {
|
||||||
|
const container = this.refs.media.children[0];
|
||||||
|
|
||||||
|
player.render(this.file(), container, { autoplay: true, controls: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file() {
|
||||||
const { downloadPath, filename } = this.props;
|
const { downloadPath, filename } = this.props;
|
||||||
const file = {
|
|
||||||
|
return {
|
||||||
name: filename,
|
name: filename,
|
||||||
createReadStream: opts => {
|
createReadStream: opts => {
|
||||||
return fs.createReadStream(downloadPath, opts);
|
return fs.createReadStream(downloadPath, opts);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
player.append(file, elem, {
|
}
|
||||||
autoplay: true,
|
|
||||||
controls: true,
|
playableType() {
|
||||||
});
|
const { mediaType } = this.props;
|
||||||
|
|
||||||
|
return ["audio", "video"].indexOf(mediaType) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { downloadPath, mediaType, poster } = this.props;
|
const { mediaType, poster } = this.props;
|
||||||
|
const { hasMetadata, unplayable } = this.state;
|
||||||
|
const noMetadataMessage = "Waiting for metadata.";
|
||||||
|
const unplayableMessage = "Sorry, looks like we can't play this file.";
|
||||||
|
|
||||||
|
const needsMetadata = this.playableType();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{["audio", "application"].indexOf(mediaType) !== -1 &&
|
{["audio", "application"].indexOf(mediaType) !== -1 &&
|
||||||
|
(!this.playableType() || hasMetadata) &&
|
||||||
|
!unplayable &&
|
||||||
<Thumbnail src={poster} className="video-embedded" />}
|
<Thumbnail src={poster} className="video-embedded" />}
|
||||||
|
{this.playableType() &&
|
||||||
|
!hasMetadata &&
|
||||||
|
!unplayable &&
|
||||||
|
<LoadingScreen status={noMetadataMessage} />}
|
||||||
|
{unplayable &&
|
||||||
|
<LoadingScreen status={unplayableMessage} spinner={false} />}
|
||||||
<div ref="media" />
|
<div ref="media" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -68,6 +68,7 @@ class Video extends React.PureComponent {
|
||||||
poster={poster}
|
poster={poster}
|
||||||
downloadPath={fileInfo.download_path}
|
downloadPath={fileInfo.download_path}
|
||||||
mediaType={mediaType}
|
mediaType={mediaType}
|
||||||
|
downloadCompleted={fileInfo.completed}
|
||||||
/>)}
|
/>)}
|
||||||
{!isPlaying &&
|
{!isPlaying &&
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -22,9 +22,9 @@ reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
byId,
|
byId,
|
||||||
claimsByUri: byUri
|
claimsByUri: byUri,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
reducers[types.RESOLVE_URI_CANCELED] = function(state, action) {
|
reducers[types.RESOLVE_URI_CANCELED] = function(state, action) {
|
||||||
const uri = action.data.uri;
|
const uri = action.data.uri;
|
||||||
|
@ -42,9 +42,7 @@ reducers[types.FETCH_CLAIM_LIST_MINE_STARTED] = function(state, action) {
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
||||||
const {
|
const { claims } = action.data;
|
||||||
claims,
|
|
||||||
} = action.data;
|
|
||||||
const myClaims = new Set(state.myClaims);
|
const myClaims = new Set(state.myClaims);
|
||||||
const byUri = Object.assign({}, state.claimsByUri);
|
const byUri = Object.assign({}, state.claimsByUri);
|
||||||
const byId = Object.assign({}, state.byId);
|
const byId = Object.assign({}, state.byId);
|
||||||
|
@ -52,14 +50,14 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
||||||
claims.forEach(claim => {
|
claims.forEach(claim => {
|
||||||
myClaims.add(claim.claim_id);
|
myClaims.add(claim.claim_id);
|
||||||
byId[claim.claim_id] = claim;
|
byId[claim.claim_id] = claim;
|
||||||
})
|
});
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
isClaimListMinePending: false,
|
isClaimListMinePending: false,
|
||||||
myClaims: myClaims,
|
myClaims: myClaims,
|
||||||
byId,
|
byId,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// reducers[types.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) {
|
// reducers[types.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) {
|
||||||
// const {
|
// const {
|
||||||
|
|
|
@ -5,7 +5,7 @@ const _selectState = state => state.claims || {};
|
||||||
|
|
||||||
export const selectClaimsById = createSelector(
|
export const selectClaimsById = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.byId || {}
|
state => state.byId || {}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectClaimsByUri = createSelector(
|
export const selectClaimsByUri = createSelector(
|
||||||
|
@ -28,11 +28,11 @@ export const selectClaimsByUri = createSelector(
|
||||||
|
|
||||||
claims[uri] = claim;
|
claims[uri] = claim;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
return claims;
|
return claims;
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
export const selectAllClaimsByChannel = createSelector(
|
export const selectAllClaimsByChannel = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
|
@ -107,7 +107,7 @@ export const selectMyClaimsOutpoints = createSelector(
|
||||||
claimIds.forEach(claimId => {
|
claimIds.forEach(claimId => {
|
||||||
const claim = byId[claimId];
|
const claim = byId[claimId];
|
||||||
if (claim) outpoints.push(`${claim.txid}:${claim.nout}`);
|
if (claim) outpoints.push(`${claim.txid}:${claim.nout}`);
|
||||||
})
|
});
|
||||||
|
|
||||||
return outpoints;
|
return outpoints;
|
||||||
}
|
}
|
||||||
|
|
2
ui/package-lock.json
generated
2
ui/package-lock.json
generated
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "lbry-web-ui",
|
"name": "lbry-web-ui",
|
||||||
"version": "0.12.0rc6",
|
"version": "0.12.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
|
|
Loading…
Reference in a new issue