diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js
index ed9324f77..a3005a374 100644
--- a/ui/js/actions/content.js
+++ b/ui/js/actions/content.js
@@ -322,38 +322,29 @@ export function doPurchaseUri(uri) {
const downloadingByOutpoint = selectDownloadingByOutpoint(state);
const alreadyDownloading =
fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
-
- // we already fully downloaded the file.
- if (fileInfo && fileInfo.completed) {
- // If written_bytes is false that means the user has deleted/moved the
- // file manually on their file system, so we need to dispatch a
- // doLoadVideo action to reconstruct the file from the blobs
- if (!fileInfo.written_bytes) dispatch(doLoadVideo(uri));
-
- return Promise.resolve();
- }
-
- // we are already downloading the file
- if (alreadyDownloading) {
- return Promise.resolve();
- }
-
const costInfo = makeSelectCostInfoForUri(uri)(state);
const { cost } = costInfo;
- // the file is free or we have partially downloaded it
- if (cost === 0 || (fileInfo && fileInfo.download_directory)) {
- dispatch(doLoadVideo(uri));
- return Promise.resolve();
+ if (
+ alreadyDownloading ||
+ (fileInfo && fileInfo.completed && fileInfo.written_bytes > 0)
+ ) {
+ return;
+ }
+
+ // we already fully downloaded the file.
+ if (
+ cost === 0 ||
+ (fileInfo && (fileInfo.completed || fileInfo.download_directory))
+ ) {
+ return dispatch(doLoadVideo(uri));
}
if (cost > balance) {
- dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS));
- } else {
- dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri }));
+ return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS));
}
- return Promise.resolve();
+ return dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri }));
};
}
@@ -420,6 +411,22 @@ export function doFetchClaimListMine() {
};
}
+export function doPlayUri(uri) {
+ return function(dispatch, getState) {
+ dispatch(doSetPlayingUri(uri));
+ dispatch(doPurchaseUri(uri));
+ };
+}
+
+export function doSetPlayingUri(uri) {
+ return function(dispatch, getState) {
+ dispatch({
+ type: types.SET_PLAYING_URI,
+ data: { uri },
+ });
+ };
+}
+
export function doFetchChannelListMine() {
return function(dispatch, getState) {
dispatch({
diff --git a/ui/js/component/fileActions/index.js b/ui/js/component/fileActions/index.js
index 75eaeff9a..68597a571 100644
--- a/ui/js/component/fileActions/index.js
+++ b/ui/js/component/fileActions/index.js
@@ -3,11 +3,7 @@ import { connect } from "react-redux";
import { makeSelectFileInfoForUri } from "selectors/file_info";
import { makeSelectCostInfoForUri } from "selectors/cost_info";
import { doOpenModal } from "actions/app";
-import { doFetchAvailability } from "actions/availability";
-import { doOpenFileInShell } from "actions/file_info";
import { makeSelectClaimIsMine } from "selectors/claims";
-import { doPurchaseUri, doStartDownload } from "actions/content";
-import { doNavigate } from "actions/navigation";
import FileActions from "./view";
const select = (state, props) => ({
@@ -18,12 +14,7 @@ const select = (state, props) => ({
});
const perform = dispatch => ({
- checkAvailability: uri => dispatch(doFetchAvailability(uri)),
- navigate: (path, params) => dispatch(doNavigate(path, params)),
- openInShell: fileInfo => dispatch(doOpenFileInShell(fileInfo)),
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
- startDownload: uri => dispatch(doPurchaseUri(uri)),
- restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)),
});
export default connect(select, perform)(FileActions);
diff --git a/ui/js/component/fileDownloadLink/index.js b/ui/js/component/fileDownloadLink/index.js
index f9657f17b..9843a1701 100644
--- a/ui/js/component/fileDownloadLink/index.js
+++ b/ui/js/component/fileDownloadLink/index.js
@@ -23,8 +23,7 @@ const select = (state, props) => ({
const perform = dispatch => ({
checkAvailability: uri => dispatch(doFetchAvailability(uri)),
openInShell: fileInfo => dispatch(doOpenFileInShell(fileInfo)),
- startDownload: uri =>
- dispatch(doPurchaseUri(uri, modals.CONFIRM_FILE_PURCHASE)),
+ purchaseUri: uri => dispatch(doPurchaseUri(uri)),
restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)),
});
diff --git a/ui/js/component/fileDownloadLink/view.jsx b/ui/js/component/fileDownloadLink/view.jsx
index 82bae5b8a..1a0a8dc1c 100644
--- a/ui/js/component/fileDownloadLink/view.jsx
+++ b/ui/js/component/fileDownloadLink/view.jsx
@@ -39,7 +39,7 @@ class FileDownloadLink extends React.PureComponent {
downloading,
uri,
openInShell,
- startDownload,
+ purchaseUri,
costInfo,
loading,
} = this.props;
@@ -81,7 +81,7 @@ class FileDownloadLink extends React.PureComponent {
label={__("Download")}
icon="icon-download"
onClick={() => {
- startDownload(uri);
+ purchaseUri(uri);
}}
/>
);
diff --git a/ui/js/component/video/index.js b/ui/js/component/video/index.js
index 36eeb3168..160816cef 100644
--- a/ui/js/component/video/index.js
+++ b/ui/js/component/video/index.js
@@ -1,9 +1,8 @@
import React from "react";
import { connect } from "react-redux";
-import { doCloseModal } from "actions/app";
import { doChangeVolume } from "actions/app";
-import { selectCurrentModal, selectVolume } from "selectors/app";
-import { doPurchaseUri, doLoadVideo } from "actions/content";
+import { selectVolume } from "selectors/app";
+import { doPlayUri } from "actions/content";
import {
makeSelectMetadataForUri,
makeSelectContentTypeForUri,
@@ -16,6 +15,7 @@ import {
import { makeSelectCostInfoForUri } from "selectors/cost_info";
import { selectShowNsfw } from "selectors/settings";
import Video from "./view";
+import { selectPlayingUri } from "selectors/content";
const select = (state, props) => ({
costInfo: makeSelectCostInfoForUri(props.uri)(state),
@@ -24,13 +24,13 @@ const select = (state, props) => ({
obscureNsfw: !selectShowNsfw(state),
isLoading: makeSelectLoadingForUri(props.uri)(state),
isDownloading: makeSelectDownloadingForUri(props.uri)(state),
+ playingUri: selectPlayingUri(state),
contentType: makeSelectContentTypeForUri(props.uri)(state),
volume: selectVolume(state),
});
const perform = dispatch => ({
- loadVideo: uri => dispatch(doLoadVideo(uri)),
- purchaseUri: uri => dispatch(doPurchaseUri(uri)),
+ play: uri => dispatch(doPlayUri(uri)),
changeVolume: volume => dispatch(doChangeVolume(volume)),
});
diff --git a/ui/js/component/video/internal/play-button.jsx b/ui/js/component/video/internal/play-button.jsx
index 23f9259aa..73905f298 100644
--- a/ui/js/component/video/internal/play-button.jsx
+++ b/ui/js/component/video/internal/play-button.jsx
@@ -17,18 +17,12 @@ class VideoPlayButton extends React.PureComponent {
"Space" === event.code
) {
event.preventDefault();
- this.onWatchClick();
+ this.watch();
}
}
- onWatchClick() {
- this.props.purchaseUri(this.props.uri).then(() => {
- if (!this.props.modal) {
- this.props.startPlaying();
- } else {
- alert("fix me set pending play");
- }
- });
+ watch() {
+ this.props.play(this.props.uri);
}
render() {
@@ -54,7 +48,7 @@ class VideoPlayButton extends React.PureComponent {
label={label ? label : ""}
className="video__play-button"
icon={icon}
- onClick={this.onWatchClick.bind(this)}
+ onClick={() => this.watch()}
/>
);
}
diff --git a/ui/js/component/video/view.jsx b/ui/js/component/video/view.jsx
index 4e396ddd4..0e6c35c6a 100644
--- a/ui/js/component/video/view.jsx
+++ b/ui/js/component/video/view.jsx
@@ -9,22 +9,10 @@ class Video extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
- isPlaying: false,
showNsfwHelp: false,
};
}
- componentWillReceiveProps(nextProps) {
- // reset playing state upon change path action
- if (
- !this.isMediaSame(nextProps) &&
- this.props.fileInfo &&
- this.state.isPlaying
- ) {
- this.state.isPlaying = false;
- }
- }
-
isMediaSame(nextProps) {
return (
this.props.fileInfo &&
@@ -33,12 +21,6 @@ class Video extends React.PureComponent {
);
}
- startPlaying() {
- this.setState({
- isPlaying: true,
- });
- }
-
handleMouseOver() {
if (
this.props.obscureNsfw &&
@@ -64,13 +46,15 @@ class Video extends React.PureComponent {
metadata,
isLoading,
isDownloading,
+ playingUri,
fileInfo,
contentType,
changeVolume,
volume,
+ uri,
} = this.props;
- const { isPlaying = false } = this.state;
+ const isPlaying = playingUri === uri;
const isReadyToPlay = fileInfo && fileInfo.written_bytes > 0;
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
const mediaType = lbry.getMediaType(
@@ -129,11 +113,7 @@ class Video extends React.PureComponent {
className="video__cover"
style={{ backgroundImage: 'url("' + metadata.thumbnail + '")' }}
>
-
+
}
{this.state.showNsfwHelp && }
diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js
index a4cb1afaa..140509461 100644
--- a/ui/js/constants/action_types.js
+++ b/ui/js/constants/action_types.js
@@ -70,6 +70,7 @@ export const CREATE_CHANNEL_COMPLETED = "CREATE_CHANNEL_COMPLETED";
export const PUBLISH_STARTED = "PUBLISH_STARTED";
export const PUBLISH_COMPLETED = "PUBLISH_COMPLETED";
export const PUBLISH_FAILED = "PUBLISH_FAILED";
+export const SET_PLAYING_URI = "PLAY_URI";
// Files
export const FILE_LIST_STARTED = "FILE_LIST_STARTED";
diff --git a/ui/js/modal/modalAffirmPurchase/index.js b/ui/js/modal/modalAffirmPurchase/index.js
index c42afc373..d0f4affa2 100644
--- a/ui/js/modal/modalAffirmPurchase/index.js
+++ b/ui/js/modal/modalAffirmPurchase/index.js
@@ -1,7 +1,7 @@
import React from "react";
import { connect } from "react-redux";
import { doCloseModal } from "actions/app";
-import { doLoadVideo } from "actions/content";
+import { doLoadVideo, doSetPlayingUri } from "actions/content";
import { makeSelectMetadataForUri } from "selectors/claims";
import ModalAffirmPurchase from "./view";
@@ -10,6 +10,10 @@ const select = (state, props) => ({
});
const perform = dispatch => ({
+ cancelPurchase: () => {
+ dispatch(doSetPlayingUri(null));
+ dispatch(doCloseModal());
+ },
closeModal: () => dispatch(doCloseModal()),
loadVideo: uri => dispatch(doLoadVideo(uri)),
});
diff --git a/ui/js/modal/modalAffirmPurchase/view.jsx b/ui/js/modal/modalAffirmPurchase/view.jsx
index a38e82f1c..96dd6c1c9 100644
--- a/ui/js/modal/modalAffirmPurchase/view.jsx
+++ b/ui/js/modal/modalAffirmPurchase/view.jsx
@@ -9,7 +9,7 @@ class ModalAffirmPurchase extends React.PureComponent {
}
render() {
- const { closeModal, metadata: { title }, uri } = this.props;
+ const { cancelPurchase, metadata: { title }, uri } = this.props;
return (
{__("This will purchase")} {title} {__("for")}{" "}
diff --git a/ui/js/reducers/content.js b/ui/js/reducers/content.js
index 9d8c5867e..8cb2eae2c 100644
--- a/ui/js/reducers/content.js
+++ b/ui/js/reducers/content.js
@@ -2,6 +2,7 @@ import * as types from "constants/action_types";
const reducers = {};
const defaultState = {
+ playingUri: null,
rewardedContentClaimIds: [],
channelPages: {},
};
@@ -58,6 +59,12 @@ reducers[types.RESOLVE_URI_CANCELED] = reducers[
});
};
+reducers[types.SET_PLAYING_URI] = (state, action) => {
+ return Object.assign({}, state, {
+ playingUri: action.data.uri,
+ });
+};
+
// reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
// const channelPages = Object.assign({}, state.channelPages);
// const { uri, claims } = action.data;
diff --git a/ui/js/selectors/content.js b/ui/js/selectors/content.js
index e8c0d42cc..0818134de 100644
--- a/ui/js/selectors/content.js
+++ b/ui/js/selectors/content.js
@@ -17,6 +17,11 @@ export const selectResolvingUris = createSelector(
state => state.resolvingUris || []
);
+export const selectPlayingUri = createSelector(
+ _selectState,
+ state => state.playingUri
+);
+
export const makeSelectIsUriResolving = uri => {
return createSelector(
selectResolvingUris,