diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 8403ec135..035c1e0aa 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.11.4 +current_version = 0.11.5rc1 commit = True tag = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)((?P[a-z]+)(?P\d+))? diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a7f237d2..253d97ad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,10 @@ Web UI version numbers should always match the corresponding version of LBRY App * ### Fixed - * - * + * Eliminated instance of costs being double fetched + * Fixed issue preventing file re-download + * Fixed race condition that could prevent file playbac + * Fixed issue with batch actions and thunk ### Deprecated * diff --git a/app/package.json b/app/package.json index a3c2e86fd..d33d9adca 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "LBRY", - "version": "0.11.4", + "version": "0.11.5rc1", "main": "main.js", "description": "LBRY is a fully decentralized, open-source protocol facilitating the discovery, access, and (sometimes) purchase of data.", "author": { diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js index 023a3c65a..e09bd5ea1 100644 --- a/ui/js/actions/content.js +++ b/ui/js/actions/content.js @@ -214,22 +214,16 @@ export function doPurchaseUri(uri) { const state = getState() const balance = selectBalance(state) const fileInfo = selectFileInfoForUri(state, { uri }) - const costInfo = selectCostInfoForUri(state, { uri }) const downloadingByUri = selectUrisDownloading(state) const alreadyDownloading = !!downloadingByUri[uri] - const { cost } = costInfo - // BUG if you delete a file from the file system system you're going to be - // asked to pay for it again. We need to check if the file is in the blobs - // here and then dispatch doLoadVideo() which will reconstruct it again from - // the blobs. Or perhaps there's another way to see if a file was already - // purchased? + // 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)) - // we already fully downloaded the file. If completed is true but - // writtenBytes is false then we downloaded it before but deleted it again, - // which means it needs to be reconstructed from the blobs by dispatching - // doLoadVideo. - if (fileInfo && fileInfo.completed && !!fileInfo.writtenBytes) { return Promise.resolve() } @@ -238,6 +232,9 @@ export function doPurchaseUri(uri) { return Promise.resolve() } + const costInfo = selectCostInfoForUri(state, { uri }) + const { cost } = costInfo + // the file is free or we have partially downloaded it if (cost <= 0.01 || (fileInfo && fileInfo.download_directory)) { dispatch(doLoadVideo(uri)) diff --git a/ui/js/component/fileActions/index.js b/ui/js/component/fileActions/index.js index a570cd413..e9dc10705 100644 --- a/ui/js/component/fileActions/index.js +++ b/ui/js/component/fileActions/index.js @@ -16,6 +16,9 @@ import { import { selectCurrentModal, } from 'selectors/app' +import { + makeSelectCostInfoForUri, +} from 'selectors/cost_info' import { doCloseModal, doOpenModal, @@ -39,6 +42,7 @@ const makeSelect = () => { const selectFileInfoForUri = makeSelectFileInfoForUri() const selectIsAvailableForUri = makeSelectIsAvailableForUri() const selectDownloadingForUri = makeSelectDownloadingForUri() + const selectCostInfoForUri = makeSelectCostInfoForUri() const select = (state, props) => ({ fileInfo: selectFileInfoForUri(state, props), @@ -46,6 +50,7 @@ const makeSelect = () => { platform: selectPlatform(state), modal: selectCurrentModal(state), downloading: selectDownloadingForUri(state, props), + costInfo: selectCostInfoForUri(state, props), }) return select @@ -62,7 +67,7 @@ const perform = (dispatch) => ({ }, openModal: (modal) => dispatch(doOpenModal(modal)), startDownload: (uri) => dispatch(doPurchaseUri(uri)), - loadVideo: (uri) => dispatch(doLoadVideo(uri)) + loadVideo: (uri) => dispatch(doLoadVideo(uri)), }) export default connect(makeSelect, perform)(FileActions) \ No newline at end of file diff --git a/ui/js/component/fileActions/view.jsx b/ui/js/component/fileActions/view.jsx index 4924d059d..7f3c1d75c 100644 --- a/ui/js/component/fileActions/view.jsx +++ b/ui/js/component/fileActions/view.jsx @@ -62,6 +62,7 @@ class FileActions extends React.Component { openModal, closeModal, startDownload, + costInfo, } = this.props const deleteChecked = this.state.deleteChecked, @@ -99,8 +100,11 @@ class FileActions extends React.Component { } else if (fileInfo === null && !downloading) { - - content = { startDownload(uri) } } />; + if (!costInfo) { + content = + } else { + content = { startDownload(uri) } } />; + } } else if (fileInfo && fileInfo.download_path) { content = openInShell(fileInfo)} />; diff --git a/ui/js/component/filePrice/index.js b/ui/js/component/filePrice/index.js index 726ceb3ee..65e870a58 100644 --- a/ui/js/component/filePrice/index.js +++ b/ui/js/component/filePrice/index.js @@ -7,14 +7,17 @@ import { } from 'actions/cost_info' import { makeSelectCostInfoForUri, + makeSelectFetchingCostInfoForUri, } from 'selectors/cost_info' import FilePrice from './view' const makeSelect = () => { const selectCostInfoForUri = makeSelectCostInfoForUri() + const selectFetchingCostInfoForUri = makeSelectFetchingCostInfoForUri() const select = (state, props) => ({ costInfo: selectCostInfoForUri(state, props), + fetching: selectFetchingCostInfoForUri(state, props), }) return select diff --git a/ui/js/component/filePrice/view.jsx b/ui/js/component/filePrice/view.jsx index 4edc3a3e7..2a0872492 100644 --- a/ui/js/component/filePrice/view.jsx +++ b/ui/js/component/filePrice/view.jsx @@ -16,10 +16,11 @@ class FilePrice extends React.Component{ const { costInfo, fetchCostInfo, - uri + uri, + fetching, } = props - if (costInfo === undefined) { + if (costInfo === undefined && !fetching) { fetchCostInfo(uri) } } diff --git a/ui/js/component/video/view.jsx b/ui/js/component/video/view.jsx index 081396cab..760a728ad 100644 --- a/ui/js/component/video/view.jsx +++ b/ui/js/component/video/view.jsx @@ -43,9 +43,11 @@ class VideoPlayButton extends React.Component { } */ + const disabled = isLoading || fileInfo === undefined || (fileInfo === null && (!costInfo || costInfo.cost === undefined)) + return (
{ lbryio.enabled ? : '' }
, canvas) } diff --git a/ui/js/selectors/cost_info.js b/ui/js/selectors/cost_info.js index 242ec6b0d..84bbb5f02 100644 --- a/ui/js/selectors/cost_info.js +++ b/ui/js/selectors/cost_info.js @@ -17,3 +17,19 @@ export const makeSelectCostInfoForUri = () => { (costInfo) => costInfo ) } + +export const selectFetchingCostInfo = createSelector( + _selectState, + (state) => state.fetching || {} +) + +const selectFetchingCostInfoForUri = (state, props) => { + return selectFetchingCostInfo(state)[props.uri] +} + +export const makeSelectFetchingCostInfoForUri = () => { + return createSelector( + selectFetchingCostInfoForUri, + (fetching) => !!fetching + ) +} diff --git a/ui/package.json b/ui/package.json index 7ee6d6272..18519d144 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "lbry-web-ui", - "version": "0.11.4", + "version": "0.11.5rc1", "description": "LBRY UI", "scripts": { "test": "echo \"Error: no test specified\" && exit 1",