mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-09-02 18:25:12 +00:00
bug fixes, file info and my claims refactor, list claims in channel
This commit is contained in:
parent
900c5cbc2b
commit
9d8fa102ee
26 changed files with 331 additions and 513 deletions
|
@ -43,7 +43,6 @@ export function doChangePath(path) {
|
||||||
path,
|
path,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +57,7 @@ export function doHistoryPush(params, title, relativeUrl) {
|
||||||
let pathParts = window.location.pathname.split('/')
|
let pathParts = window.location.pathname.split('/')
|
||||||
pathParts[pathParts.length - 1] = relativeUrl.replace(/^\//, '')
|
pathParts[pathParts.length - 1] = relativeUrl.replace(/^\//, '')
|
||||||
const url = pathParts.join('/')
|
const url = pathParts.join('/')
|
||||||
|
title += " - LBRY"
|
||||||
history.pushState(params, title, url)
|
history.pushState(params, title, url)
|
||||||
window.document.title = title
|
window.document.title = title
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from 'selectors/wallet'
|
} from 'selectors/wallet'
|
||||||
import {
|
import {
|
||||||
selectFileInfoForUri,
|
selectFileInfoForUri,
|
||||||
selectDownloadingByUri,
|
selectUrisDownloading,
|
||||||
} from 'selectors/file_info'
|
} from 'selectors/file_info'
|
||||||
import {
|
import {
|
||||||
selectResolvingUris
|
selectResolvingUris
|
||||||
|
@ -66,6 +66,7 @@ export function doCancelResolveUri(uri) {
|
||||||
|
|
||||||
export function doFetchFeaturedUris() {
|
export function doFetchFeaturedUris() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
|
return
|
||||||
const state = getState()
|
const state = getState()
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -81,22 +82,22 @@ export function doFetchFeaturedUris() {
|
||||||
featuredUris[category] = Uris[category]
|
featuredUris[category] = Uris[category]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
//
|
||||||
|
// dispatch({
|
||||||
|
// type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
||||||
|
// data: {
|
||||||
|
// categories: ["FOO"],
|
||||||
|
// uris: { FOO: ["lbry://gtasoc"]},
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
categories: ["FOO"],
|
categories: Categories,
|
||||||
uris: { FOO: ["lbry://gtasoc"]},
|
uris: featuredUris,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// dispatch({
|
|
||||||
// type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
|
||||||
// data: {
|
|
||||||
// categories: Categories,
|
|
||||||
// uris: featuredUris,
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const failure = () => {
|
const failure = () => {
|
||||||
|
@ -219,7 +220,7 @@ export function doPurchaseUri(uri) {
|
||||||
const balance = selectBalance(state)
|
const balance = selectBalance(state)
|
||||||
const fileInfo = selectFileInfoForUri(state, { uri })
|
const fileInfo = selectFileInfoForUri(state, { uri })
|
||||||
const costInfo = selectCostInfoForUri(state, { uri })
|
const costInfo = selectCostInfoForUri(state, { uri })
|
||||||
const downloadingByUri = selectDownloadingByUri(state)
|
const downloadingByUri = selectUrisDownloading(state)
|
||||||
const alreadyDownloading = !!downloadingByUri[uri]
|
const alreadyDownloading = !!downloadingByUri[uri]
|
||||||
const { cost } = costInfo
|
const { cost } = costInfo
|
||||||
|
|
||||||
|
@ -268,18 +269,28 @@ export function doFetchClaimsByChannel(uri) {
|
||||||
} = resolutionInfo ? resolutionInfo : { claims_in_channel: [] }
|
} = resolutionInfo ? resolutionInfo : { claims_in_channel: [] }
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.FETCH_CHANNEL_CLAIMS_STARTED,
|
type: types.FETCH_CHANNEL_CLAIMS_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
uri,
|
uri,
|
||||||
claims: claims_in_channel
|
claims: claims_in_channel
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).catch(() => {
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doClaimListMine() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
dispatch({
|
||||||
|
type: types.CLAIM_LIST_MINE_STARTED
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
lbry.claim_list_mine().then((claims) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.FETC,
|
type: types.CLAIM_LIST_MINE_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
uri,
|
claims
|
||||||
claims: []
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import * as types from 'constants/action_types'
|
import * as types from 'constants/action_types'
|
||||||
import lbry from 'lbry'
|
import lbry from 'lbry'
|
||||||
|
import {
|
||||||
|
doClaimListMine
|
||||||
|
} from 'actions/content'
|
||||||
import {
|
import {
|
||||||
selectClaimsByUri,
|
selectClaimsByUri,
|
||||||
|
selectClaimListMineIsPending,
|
||||||
} from 'selectors/claims'
|
} from 'selectors/claims'
|
||||||
import {
|
import {
|
||||||
selectIsFileListPending,
|
selectFileListIsPending,
|
||||||
selectAllFileInfos,
|
selectAllFileInfos,
|
||||||
selectLoadingByUri,
|
selectUrisLoading,
|
||||||
} from 'selectors/file_info'
|
} from 'selectors/file_info'
|
||||||
import {
|
import {
|
||||||
doCloseModal,
|
doCloseModal,
|
||||||
|
@ -21,7 +25,7 @@ export function doFetchFileInfo(uri) {
|
||||||
const state = getState()
|
const state = getState()
|
||||||
const claim = selectClaimsByUri(state)[uri]
|
const claim = selectClaimsByUri(state)[uri]
|
||||||
const outpoint = claim ? `${claim.txid}:${claim.nout}` : null
|
const outpoint = claim ? `${claim.txid}:${claim.nout}` : null
|
||||||
const alreadyFetching = !!selectLoadingByUri(state)[uri]
|
const alreadyFetching = !!selectUrisLoading(state)[uri]
|
||||||
|
|
||||||
if (!alreadyFetching) {
|
if (!alreadyFetching) {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -31,12 +35,13 @@ export function doFetchFileInfo(uri) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
lbry.file_list({outpoint: outpoint, full_status: true}).then(([fileInfo]) => {
|
lbry.file_list({outpoint: outpoint, full_status: true}).then(fileInfos => {
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.FETCH_FILE_INFO_COMPLETED,
|
type: types.FETCH_FILE_INFO_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
outpoint,
|
outpoint,
|
||||||
fileInfo,
|
fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -44,10 +49,10 @@ export function doFetchFileInfo(uri) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doFileList(uri) {
|
export function doFileList() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
const state = getState()
|
const state = getState()
|
||||||
const isPending = selectIsFileListPending(state)
|
const isPending = selectFileListIsPending(state)
|
||||||
|
|
||||||
if (!isPending) {
|
if (!isPending) {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -78,81 +83,39 @@ export function doOpenFileInFolder(fileInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doDeleteFile(uri, fileInfo, deleteFromComputer) {
|
export function doDeleteFile(outpoint, deleteFromComputer) {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.DELETE_FILE_STARTED,
|
type: types.FILE_DELETE,
|
||||||
data: {
|
data: {
|
||||||
uri,
|
outpoint
|
||||||
fileInfo,
|
|
||||||
deleteFromComputer,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const successCallback = () => {
|
lbry.file_delete({
|
||||||
dispatch({
|
outpoint: outpoint,
|
||||||
type: types.DELETE_FILE_COMPLETED,
|
delete_target_file: deleteFromComputer,
|
||||||
data: {
|
})
|
||||||
uri,
|
|
||||||
}
|
dispatch(doCloseModal())
|
||||||
})
|
}
|
||||||
dispatch(doCloseModal())
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function doFetchFileInfosAndPublishedClaims() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
const state = getState(),
|
||||||
|
isClaimListMinePending = selectClaimListMineIsPending(state),
|
||||||
|
isFileInfoListPending = selectFileListIsPending(state)
|
||||||
|
|
||||||
|
if (isClaimListMinePending === undefined) {
|
||||||
|
dispatch(doClaimListMine())
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.removeFile(fileInfo.outpoint, deleteFromComputer, successCallback)
|
if (isFileInfoListPending === undefined) {
|
||||||
}
|
dispatch(doFileList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function doFetchDownloadedContent() {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
const state = getState(),
|
|
||||||
fileInfos = selectAllFileInfos(state)
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: types.FETCH_DOWNLOADED_CONTENT_STARTED,
|
|
||||||
})
|
|
||||||
|
|
||||||
lbry.claim_list_mine().then((myClaimInfos) => {
|
|
||||||
|
|
||||||
const myClaimOutpoints = myClaimInfos.map(({txid, nout}) => txid + ':' + nout);
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: types.FETCH_DOWNLOADED_CONTENT_COMPLETED,
|
|
||||||
data: {
|
|
||||||
fileInfos: fileInfos.filter(({outpoint}) => !myClaimOutpoints.includes(outpoint)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doFetchPublishedContent() {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
const state = getState(),
|
|
||||||
fileInfos = selectAllFileInfos(state)
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: types.FETCH_PUBLISHED_CONTENT_STARTED,
|
|
||||||
})
|
|
||||||
|
|
||||||
lbry.claim_list_mine().then((claimInfos) => {
|
|
||||||
dispatch({
|
|
||||||
type: types.FETCH_MY_CLAIMS_COMPLETED,
|
|
||||||
data: {
|
|
||||||
claims: claimInfos,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const myClaimOutpoints = claimInfos.map(({txid, nout}) => txid + ':' + nout)
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: types.FETCH_PUBLISHED_CONTENT_COMPLETED,
|
|
||||||
data: {
|
|
||||||
fileInfos: fileInfos.filter(({outpoint}) => myClaimOutpoints.includes(outpoint)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
import {
|
import {
|
||||||
doCloseModal,
|
doCloseModal,
|
||||||
doOpenModal,
|
doOpenModal,
|
||||||
|
doHistoryBack,
|
||||||
} from 'actions/app'
|
} from 'actions/app'
|
||||||
import {
|
import {
|
||||||
doFetchAvailability
|
doFetchAvailability
|
||||||
|
@ -55,7 +56,10 @@ const perform = (dispatch) => ({
|
||||||
closeModal: () => dispatch(doCloseModal()),
|
closeModal: () => dispatch(doCloseModal()),
|
||||||
openInFolder: (fileInfo) => dispatch(doOpenFileInFolder(fileInfo)),
|
openInFolder: (fileInfo) => dispatch(doOpenFileInFolder(fileInfo)),
|
||||||
openInShell: (fileInfo) => dispatch(doOpenFileInShell(fileInfo)),
|
openInShell: (fileInfo) => dispatch(doOpenFileInShell(fileInfo)),
|
||||||
deleteFile: (fileInfo, deleteFromComputer) => dispatch(doDeleteFile(fileInfo, deleteFromComputer)),
|
deleteFile: (fileInfo, deleteFromComputer) => {
|
||||||
|
dispatch(doHistoryBack())
|
||||||
|
dispatch(doDeleteFile(fileInfo, deleteFromComputer))
|
||||||
|
},
|
||||||
openModal: (modal) => dispatch(doOpenModal(modal)),
|
openModal: (modal) => dispatch(doOpenModal(modal)),
|
||||||
startDownload: (uri) => dispatch(doPurchaseUri(uri)),
|
startDownload: (uri) => dispatch(doPurchaseUri(uri)),
|
||||||
loadVideo: (uri) => dispatch(doLoadVideo(uri))
|
loadVideo: (uri) => dispatch(doLoadVideo(uri))
|
||||||
|
|
|
@ -72,7 +72,19 @@ class FileActions extends React.Component {
|
||||||
|
|
||||||
let content
|
let content
|
||||||
|
|
||||||
if (!fileInfo && isAvailable === undefined) {
|
if (downloading) {
|
||||||
|
|
||||||
|
const
|
||||||
|
progress = (fileInfo && fileInfo.written_bytes) ? fileInfo.written_bytes / fileInfo.total_bytes * 100 : 0,
|
||||||
|
label = fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...',
|
||||||
|
labelWithIcon = <span className="button__content"><Icon icon="icon-download" /><span>{label}</span></span>;
|
||||||
|
|
||||||
|
content = <div className="faux-button-block file-actions__download-status-bar button-set-item">
|
||||||
|
<div className="faux-button-block file-actions__download-status-bar-overlay" style={{ width: progress + '%' }}>{labelWithIcon}</div>
|
||||||
|
{labelWithIcon}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
} else if (!fileInfo && isAvailable === undefined) {
|
||||||
|
|
||||||
content = <BusyMessage message="Checking availability" />
|
content = <BusyMessage message="Checking availability" />
|
||||||
|
|
||||||
|
@ -90,18 +102,6 @@ class FileActions extends React.Component {
|
||||||
|
|
||||||
content = <Link button="text" label="Download" icon="icon-download" onClick={() => { startDownload(uri) } } />;
|
content = <Link button="text" label="Download" icon="icon-download" onClick={() => { startDownload(uri) } } />;
|
||||||
|
|
||||||
} else if (downloading) {
|
|
||||||
|
|
||||||
const
|
|
||||||
progress = (fileInfo && fileInfo.written_bytes) ? fileInfo.written_bytes / fileInfo.total_bytes * 100 : 0,
|
|
||||||
label = fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...',
|
|
||||||
labelWithIcon = <span className="button__content"><Icon icon="icon-download" /><span>{label}</span></span>;
|
|
||||||
|
|
||||||
content = <div className="faux-button-block file-actions__download-status-bar button-set-item">
|
|
||||||
<div className="faux-button-block file-actions__download-status-bar-overlay" style={{ width: progress + '%' }}>{labelWithIcon}</div>
|
|
||||||
{labelWithIcon}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
} else if (fileInfo && fileInfo.download_path) {
|
} else if (fileInfo && fileInfo.download_path) {
|
||||||
content = <Link label="Open" button="text" icon="icon-folder-open" onClick={() => openInShell(fileInfo)} />;
|
content = <Link label="Open" button="text" icon="icon-folder-open" onClick={() => openInShell(fileInfo)} />;
|
||||||
} else {
|
} else {
|
||||||
|
@ -133,7 +133,7 @@ class FileActions extends React.Component {
|
||||||
contentLabel="Not enough credits"
|
contentLabel="Not enough credits"
|
||||||
type="confirm"
|
type="confirm"
|
||||||
confirmButtonLabel="Remove"
|
confirmButtonLabel="Remove"
|
||||||
onConfirmed={() => deleteFile(uri, fileInfo, deleteChecked)}
|
onConfirmed={() => deleteFile(fileInfo.outpoint, deleteChecked)}
|
||||||
onAborted={closeModal}>
|
onAborted={closeModal}>
|
||||||
<p>Are you sure you'd like to remove <cite>{title}</cite> from LBRY?</p>
|
<p>Are you sure you'd like to remove <cite>{title}</cite> from LBRY?</p>
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ class FileList extends React.Component {
|
||||||
handleSortChanged,
|
handleSortChanged,
|
||||||
fetching,
|
fetching,
|
||||||
fileInfos,
|
fileInfos,
|
||||||
hidePrices,
|
|
||||||
} = this.props
|
} = this.props
|
||||||
const {
|
const {
|
||||||
sortBy,
|
sortBy,
|
||||||
|
@ -72,7 +71,7 @@ class FileList extends React.Component {
|
||||||
contentName: fileInfo.name,
|
contentName: fileInfo.name,
|
||||||
channelName: fileInfo.channel_name,
|
channelName: fileInfo.channel_name,
|
||||||
})
|
})
|
||||||
content.push(<FileTile key={uri} uri={uri} hidePrice={hidePrices} hideOnRemove={true} showEmpty={""} />)
|
content.push(<FileTile key={uri} uri={uri} hidePrice={true} showEmpty={this.props.fileTileShowEmpty} />)
|
||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<section className="file-list__header">
|
<section className="file-list__header">
|
||||||
|
|
|
@ -4,14 +4,13 @@ import Link from 'component/link';
|
||||||
import Modal from 'component/modal';
|
import Modal from 'component/modal';
|
||||||
|
|
||||||
class VideoPlayButton extends React.Component {
|
class VideoPlayButton extends React.Component {
|
||||||
confirmPurchaseClick() {
|
onPurchaseConfirmed() {
|
||||||
this.props.closeModal()
|
this.props.closeModal()
|
||||||
this.props.startPlaying()
|
this.props.startPlaying()
|
||||||
this.props.loadVideo(this.props.uri)
|
this.props.loadVideo(this.props.uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
onWatchClick() {
|
onWatchClick() {
|
||||||
console.log(this)
|
|
||||||
this.props.purchaseUri(this.props.uri).then(() => {
|
this.props.purchaseUri(this.props.uri).then(() => {
|
||||||
if (!this.props.modal) {
|
if (!this.props.modal) {
|
||||||
this.props.startPlaying()
|
this.props.startPlaying()
|
||||||
|
@ -59,7 +58,7 @@ class VideoPlayButton extends React.Component {
|
||||||
type="confirm"
|
type="confirm"
|
||||||
isOpen={modal == 'affirmPurchase'}
|
isOpen={modal == 'affirmPurchase'}
|
||||||
contentLabel="Confirm Purchase"
|
contentLabel="Confirm Purchase"
|
||||||
onConfirmed={this.confirmPurchaseClick.bind(this)}
|
onConfirmed={this.onPurchaseConfirmed.bind(this)}
|
||||||
onAborted={closeModal}>
|
onAborted={closeModal}>
|
||||||
This will purchase <strong>{title}</strong> for <strong><FilePrice uri={uri} look="plain" /></strong> credits.
|
This will purchase <strong>{title}</strong> for <strong><FilePrice uri={uri} look="plain" /></strong> credits.
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -107,8 +106,8 @@ class Video extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"video " + this.props.className + (isPlaying || isReadyToPlay ? " video--active" : " video--hidden")}>{
|
<div className={"video " + this.props.className + (isPlaying ? " video--active" : " video--hidden")}>{
|
||||||
isPlaying || isReadyToPlay ?
|
isPlaying || isLoading ?
|
||||||
(!isReadyToPlay ?
|
(!isReadyToPlay ?
|
||||||
<span>this is the world's worst loading screen and we shipped our software with it anyway... <br /><br />{loadStatusMessage}</span> :
|
<span>this is the world's worst loading screen and we shipped our software with it anyway... <br /><br />{loadStatusMessage}</span> :
|
||||||
<VideoPlayer poster={metadata.thumbnail} autoplay={isPlaying} downloadPath={fileInfo.download_path} />) :
|
<VideoPlayer poster={metadata.thumbnail} autoplay={isPlaying} downloadPath={fileInfo.download_path} />) :
|
||||||
|
|
|
@ -38,12 +38,10 @@ export const RESOLVE_URI_COMPLETED = 'RESOLVE_URI_COMPLETED'
|
||||||
export const RESOLVE_URI_CANCELED = 'RESOLVE_URI_CANCELED'
|
export const RESOLVE_URI_CANCELED = 'RESOLVE_URI_CANCELED'
|
||||||
export const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'
|
export const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'
|
||||||
export const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'
|
export const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'
|
||||||
|
export const CLAIM_LIST_MINE_STARTED = 'CLAIM_LIST_MINE_STARTED'
|
||||||
|
export const CLAIM_LIST_MINE_COMPLETED = 'CLAIM_LIST_MINE_COMPLETED'
|
||||||
export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'
|
export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'
|
||||||
export const FILE_LIST_COMPLETED = 'FILE_LIST_COMPLETED'
|
export const FILE_LIST_COMPLETED = 'FILE_LIST_COMPLETED'
|
||||||
export const FETCH_DOWNLOADED_CONTENT_STARTED = 'FETCH_DOWNLOADED_CONTENT_STARTED'
|
|
||||||
export const FETCH_DOWNLOADED_CONTENT_COMPLETED = 'FETCH_DOWNLOADED_CONTENT_COMPLETED'
|
|
||||||
export const FETCH_PUBLISHED_CONTENT_STARTED = 'FETCH_PUBLISHED_CONTENT_STARTED'
|
|
||||||
export const FETCH_PUBLISHED_CONTENT_COMPLETED = 'FETCH_PUBLISHED_CONTENT_COMPLETED'
|
|
||||||
export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'
|
export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'
|
||||||
export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'
|
export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'
|
||||||
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'
|
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'
|
||||||
|
@ -57,9 +55,7 @@ export const DOWNLOADING_COMPLETED = 'DOWNLOADING_COMPLETED'
|
||||||
export const PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED'
|
export const PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED'
|
||||||
export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'
|
export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'
|
||||||
export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'
|
export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'
|
||||||
export const DELETE_FILE_STARTED = 'DELETE_FILE_STARTED'
|
export const FILE_DELETE = 'FILE_DELETE'
|
||||||
export const DELETE_FILE_COMPLETED = 'DELETE_FILE_COMPLETED'
|
|
||||||
export const FETCH_MY_CLAIMS_COMPLETED = 'FETCH_MY_CLAIMS_COMPLETED'
|
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
export const SEARCH_STARTED = 'SEARCH_STARTED'
|
export const SEARCH_STARTED = 'SEARCH_STARTED'
|
||||||
|
|
125
ui/js/lbry.js
125
ui/js/lbry.js
|
@ -7,6 +7,25 @@ import {getLocal, getSession, setSession, setLocal} from './utils.js';
|
||||||
const {remote, ipcRenderer} = require('electron');
|
const {remote, ipcRenderer} = require('electron');
|
||||||
const menu = remote.require('./menu/main-menu');
|
const menu = remote.require('./menu/main-menu');
|
||||||
|
|
||||||
|
let lbry = {
|
||||||
|
isConnected: false,
|
||||||
|
daemonConnectionString: 'http://localhost:5279/lbryapi',
|
||||||
|
webUiUri: 'http://localhost:5279',
|
||||||
|
peerListTimeout: 6000,
|
||||||
|
pendingPublishTimeout: 20 * 60 * 1000,
|
||||||
|
colors: {
|
||||||
|
primary: '#155B4A'
|
||||||
|
},
|
||||||
|
defaultClientSettings: {
|
||||||
|
showNsfw: false,
|
||||||
|
showUnavailable: true,
|
||||||
|
debug: false,
|
||||||
|
useCustomLighthouseServers: false,
|
||||||
|
customLighthouseServers: [],
|
||||||
|
showDeveloperMenu: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Records a publish attempt in local storage. Returns a dictionary with all the data needed to
|
* Records a publish attempt in local storage. Returns a dictionary with all the data needed to
|
||||||
* needed to make a dummy claim or file info object.
|
* needed to make a dummy claim or file info object.
|
||||||
|
@ -40,14 +59,14 @@ function removePendingPublishIfNeeded({name, channel_name, outpoint}) {
|
||||||
return pub.outpoint === outpoint || (pub.name === name && (!channel_name || pub.channel_name === channel_name));
|
return pub.outpoint === outpoint || (pub.name === name && (!channel_name || pub.channel_name === channel_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
setLocal('pendingPublishes', getPendingPublishes().filter(pub => !pubMatches(pub)));
|
setLocal('pendingPublishes', lbry.getPendingPublishes().filter(pub => !pubMatches(pub)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current list of pending publish attempts. Filters out any that have timed out and
|
* Gets the current list of pending publish attempts. Filters out any that have timed out and
|
||||||
* removes them from the list.
|
* removes them from the list.
|
||||||
*/
|
*/
|
||||||
function getPendingPublishes() {
|
lbry.getPendingPublishes = function() {
|
||||||
const pendingPublishes = getLocal('pendingPublishes') || [];
|
const pendingPublishes = getLocal('pendingPublishes') || [];
|
||||||
const newPendingPublishes = pendingPublishes.filter(pub => Date.now() - pub.time <= lbry.pendingPublishTimeout);
|
const newPendingPublishes = pendingPublishes.filter(pub => Date.now() - pub.time <= lbry.pendingPublishTimeout);
|
||||||
setLocal('pendingPublishes', newPendingPublishes);
|
setLocal('pendingPublishes', newPendingPublishes);
|
||||||
|
@ -59,7 +78,7 @@ function getPendingPublishes() {
|
||||||
* provided along withe the name. If no pending publish is found, returns null.
|
* provided along withe the name. If no pending publish is found, returns null.
|
||||||
*/
|
*/
|
||||||
function getPendingPublish({name, channel_name, outpoint}) {
|
function getPendingPublish({name, channel_name, outpoint}) {
|
||||||
const pendingPublishes = getPendingPublishes();
|
const pendingPublishes = lbry.getPendingPublishes();
|
||||||
return pendingPublishes.find(
|
return pendingPublishes.find(
|
||||||
pub => pub.outpoint === outpoint || (pub.name === name && (!channel_name || pub.channel_name === channel_name))
|
pub => pub.outpoint === outpoint || (pub.name === name && (!channel_name || pub.channel_name === channel_name))
|
||||||
) || null;
|
) || null;
|
||||||
|
@ -74,26 +93,6 @@ function pendingPublishToDummyFileInfo({name, outpoint, claim_id}) {
|
||||||
}
|
}
|
||||||
window.pptdfi = pendingPublishToDummyFileInfo;
|
window.pptdfi = pendingPublishToDummyFileInfo;
|
||||||
|
|
||||||
let lbry = {
|
|
||||||
isConnected: false,
|
|
||||||
rootPath: '.',
|
|
||||||
daemonConnectionString: 'http://localhost:5279/lbryapi',
|
|
||||||
webUiUri: 'http://localhost:5279',
|
|
||||||
peerListTimeout: 6000,
|
|
||||||
pendingPublishTimeout: 20 * 60 * 1000,
|
|
||||||
colors: {
|
|
||||||
primary: '#155B4A'
|
|
||||||
},
|
|
||||||
defaultClientSettings: {
|
|
||||||
showNsfw: false,
|
|
||||||
showUnavailable: true,
|
|
||||||
debug: false,
|
|
||||||
useCustomLighthouseServers: false,
|
|
||||||
customLighthouseServers: [],
|
|
||||||
showDeveloperMenu: false,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lbry.call = function (method, params, callback, errorCallback, connectFailedCallback) {
|
lbry.call = function (method, params, callback, errorCallback, connectFailedCallback) {
|
||||||
return jsonrpc.call(lbry.daemonConnectionString, method, params, callback, errorCallback, connectFailedCallback);
|
return jsonrpc.call(lbry.daemonConnectionString, method, params, callback, errorCallback, connectFailedCallback);
|
||||||
}
|
}
|
||||||
|
@ -159,12 +158,6 @@ lbry.sendToAddress = function(amount, address, callback, errorCallback) {
|
||||||
lbry.call("send_amount_to_address", { "amount" : amount, "address": address }, callback, errorCallback);
|
lbry.call("send_amount_to_address", { "amount" : amount, "address": address }, callback, errorCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.getMyClaim = function(name, callback) {
|
|
||||||
lbry.call('claim_list_mine', {}, (claims) => {
|
|
||||||
callback(claims.find((claim) => claim.name == name) || null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a LBRY URI; will first try and calculate a total cost using
|
* Takes a LBRY URI; will first try and calculate a total cost using
|
||||||
* Lighthouse. If Lighthouse can't be reached, it just retrives the
|
* Lighthouse. If Lighthouse can't be reached, it just retrives the
|
||||||
|
@ -218,40 +211,6 @@ lbry.getCostInfo = function(uri) {
|
||||||
return lbry.costPromiseCache[uri];
|
return lbry.costPromiseCache[uri];
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.getMyClaims = function(callback) {
|
|
||||||
lbry.call('get_name_claims', {}, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
lbry.removeFile = function(outpoint, deleteTargetFile=true, callback) {
|
|
||||||
this._removedFiles.push(outpoint);
|
|
||||||
// this._updateFileInfoSubscribers(outpoint);
|
|
||||||
|
|
||||||
lbry.file_delete({
|
|
||||||
outpoint: outpoint,
|
|
||||||
delete_target_file: deleteTargetFile,
|
|
||||||
}).then(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
lbry.getFileInfoWhenListed = function(name, callback, timeoutCallback, tryNum=0) {
|
|
||||||
function scheduleNextCheckOrTimeout() {
|
|
||||||
if (timeoutCallback && tryNum > 200) {
|
|
||||||
timeoutCallback();
|
|
||||||
} else {
|
|
||||||
setTimeout(() => lbry.getFileInfoWhenListed(name, callback, timeoutCallback, tryNum + 1), 250);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls callback with file info when it appears in the lbrynet file manager.
|
|
||||||
// If timeoutCallback is provided, it will be called if the file fails to appear.
|
|
||||||
lbry.file_list({name: name}).then(([fileInfo]) => {
|
|
||||||
if (fileInfo) {
|
|
||||||
callback(fileInfo);
|
|
||||||
} else {
|
|
||||||
scheduleNextCheckOrTimeout();
|
|
||||||
}
|
|
||||||
}, () => scheduleNextCheckOrTimeout());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publishes a file. The optional fileListedCallback is called when the file becomes available in
|
* Publishes a file. The optional fileListedCallback is called when the file becomes available in
|
||||||
* lbry.file_list() during the publish process.
|
* lbry.file_list() during the publish process.
|
||||||
|
@ -292,10 +251,6 @@ lbry.publish = function(params, fileListedCallback, publishedCallback, errorCall
|
||||||
fileListedCallback(true);
|
fileListedCallback(true);
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
//lbry.getFileInfoWhenListed(params.name, function(fileInfo) {
|
|
||||||
// fileListedCallback(fileInfo);
|
|
||||||
//});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -350,29 +305,10 @@ lbry.formatName = function(name) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.nameIsValid = function(name, checkCase=true) {
|
|
||||||
const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i');
|
|
||||||
return regexp.test(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
lbry.loadJs = function(src, type, onload)
|
|
||||||
{
|
|
||||||
var lbryScriptTag = document.getElementById('lbry'),
|
|
||||||
newScriptTag = document.createElement('script'),
|
|
||||||
type = type || 'text/javascript';
|
|
||||||
|
|
||||||
newScriptTag.src = src;
|
|
||||||
newScriptTag.type = type;
|
|
||||||
if (onload)
|
|
||||||
{
|
|
||||||
newScriptTag.onload = onload;
|
|
||||||
}
|
|
||||||
lbryScriptTag.parentNode.insertBefore(newScriptTag, lbryScriptTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
lbry.imagePath = function(file)
|
lbry.imagePath = function(file)
|
||||||
{
|
{
|
||||||
return lbry.rootPath + '/img/' + file;
|
return 'img/' + file;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.getMediaType = function(contentType, fileName) {
|
lbry.getMediaType = function(contentType, fileName) {
|
||||||
|
@ -406,17 +342,6 @@ lbry.stop = function(callback) {
|
||||||
lbry._subscribeIdCount = 0;
|
lbry._subscribeIdCount = 0;
|
||||||
lbry._balanceSubscribeCallbacks = {};
|
lbry._balanceSubscribeCallbacks = {};
|
||||||
lbry._balanceSubscribeInterval = 5000;
|
lbry._balanceSubscribeInterval = 5000;
|
||||||
lbry._removedFiles = [];
|
|
||||||
lbry._claimIdOwnershipCache = {};
|
|
||||||
|
|
||||||
lbry._updateClaimOwnershipCache = function(claimId) {
|
|
||||||
lbry.getMyClaims((claimInfos) => {
|
|
||||||
lbry._claimIdOwnershipCache[claimId] = !!claimInfos.reduce(function(match, claimInfo) {
|
|
||||||
return match || claimInfo.claim_id == claimId;
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
lbry._balanceUpdateInterval = null;
|
lbry._balanceUpdateInterval = null;
|
||||||
lbry._updateBalanceSubscribers = function() {
|
lbry._updateBalanceSubscribers = function() {
|
||||||
|
@ -493,7 +418,7 @@ lbry.file_list = function(params={}) {
|
||||||
lbry.call('file_list', params, (fileInfos) => {
|
lbry.call('file_list', params, (fileInfos) => {
|
||||||
removePendingPublishIfNeeded({name, channel_name, outpoint});
|
removePendingPublishIfNeeded({name, channel_name, outpoint});
|
||||||
|
|
||||||
const dummyFileInfos = getPendingPublishes().map(pendingPublishToDummyFileInfo);
|
const dummyFileInfos = lbry.getPendingPublishes().map(pendingPublishToDummyFileInfo);
|
||||||
resolve([...fileInfos, ...dummyFileInfos]);
|
resolve([...fileInfos, ...dummyFileInfos]);
|
||||||
}, reject, reject);
|
}, reject, reject);
|
||||||
});
|
});
|
||||||
|
@ -506,7 +431,7 @@ lbry.claim_list_mine = function(params={}) {
|
||||||
removePendingPublishIfNeeded({name, channel_name, outpoint: txid + ':' + nout});
|
removePendingPublishIfNeeded({name, channel_name, outpoint: txid + ':' + nout});
|
||||||
}
|
}
|
||||||
|
|
||||||
const dummyClaims = getPendingPublishes().map(pendingPublishToDummyClaim);
|
const dummyClaims = lbry.getPendingPublishes().map(pendingPublishToDummyClaim);
|
||||||
resolve([...claims, ...dummyClaims]);
|
resolve([...claims, ...dummyClaims]);
|
||||||
}, reject, reject)
|
}, reject, reject)
|
||||||
});
|
});
|
||||||
|
|
|
@ -175,6 +175,11 @@ lbryuri.isValid = function(uri) {
|
||||||
return parts && parts.name;
|
return parts && parts.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lbryuri.isValidName = function(name, checkCase=true) {
|
||||||
|
const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i');
|
||||||
|
return regexp.test(name);
|
||||||
|
}
|
||||||
|
|
||||||
lbryuri.isClaimable = function(uri) {
|
lbryuri.isClaimable = function(uri) {
|
||||||
let parts
|
let parts
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -34,13 +34,15 @@ window.addEventListener('contextmenu', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('popstate', (event) => {
|
window.addEventListener('popstate', (event, param) => {
|
||||||
const queryString = document.location.search
|
const queryString = document.location.search
|
||||||
const pathParts = document.location.pathname.split('/')
|
const pathParts = document.location.pathname.split('/')
|
||||||
const route = '/' + pathParts[pathParts.length - 1]
|
const route = '/' + pathParts[pathParts.length - 1]
|
||||||
|
|
||||||
if (route.match(/html$/)) return
|
if (route.match(/html$/)) return
|
||||||
|
|
||||||
|
console.log('title should be set here, but it is not in popstate? TODO')
|
||||||
|
|
||||||
app.store.dispatch(doChangePath(`${route}${queryString}`))
|
app.store.dispatch(doChangePath(`${route}${queryString}`))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,28 @@ import {
|
||||||
doFetchClaimsByChannel
|
doFetchClaimsByChannel
|
||||||
} from 'actions/content'
|
} from 'actions/content'
|
||||||
import {
|
import {
|
||||||
makeSelectClaimsForChannel
|
makeSelectClaimForUri,
|
||||||
|
makeSelectClaimsInChannelForUri
|
||||||
} from 'selectors/claims'
|
} from 'selectors/claims'
|
||||||
import ChannelPage from './view'
|
import ChannelPage from './view'
|
||||||
//
|
|
||||||
// const select = (state) => ({
|
import FilePage from './view'
|
||||||
// uri: selectCurrentUri(state),
|
|
||||||
// claim: selectCurrentUriClaim(state),
|
const makeSelect = () => {
|
||||||
// claims: selectCurrentUriClaims(state)
|
const selectClaim = makeSelectClaimForUri(),
|
||||||
// })
|
selectClaimsInChannel = makeSelectClaimsInChannelForUri()
|
||||||
|
|
||||||
|
const select = (state, props) => ({
|
||||||
|
claim: selectClaim(state, props),
|
||||||
|
claimsInChannel: selectClaimsInChannel(state, props)
|
||||||
|
})
|
||||||
|
|
||||||
|
return select
|
||||||
|
}
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
// fetchClaims: () => { console.log('fetch claims') }
|
||||||
fetchClaims: (uri) => dispatch(doFetchClaimsByChannel(uri))
|
fetchClaims: (uri) => dispatch(doFetchClaimsByChannel(uri))
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(null, perform)(ChannelPage)
|
export default connect(makeSelect, perform)(ChannelPage)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import lbryuri from 'lbryuri'
|
||||||
|
|
||||||
class ChannelPage extends React.Component{
|
class ChannelPage extends React.Component{
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -10,19 +11,19 @@ class ChannelPage extends React.Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchClaims(props) {
|
fetchClaims(props) {
|
||||||
if (props.claims === undefined) {
|
if (props.claimsInChannel === undefined) {
|
||||||
props.fetchClaims(props.uri)
|
props.fetchClaims(props.uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
claims,
|
claimsInChannel,
|
||||||
claim,
|
claim,
|
||||||
uri
|
uri
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
console.log(claims);
|
console.log(claimsInChannel);
|
||||||
return <main className="main--single-column">
|
return <main className="main--single-column">
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="card__inner">
|
<div className="card__inner">
|
||||||
|
@ -36,7 +37,9 @@ class ChannelPage extends React.Component{
|
||||||
</section>
|
</section>
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
{claims}
|
{claimsInChannel ?
|
||||||
|
claimsInChannel.map((claim) => <FileTile uri={lbryuri.build({name: claim.name, claimId: claim.claim_id})} /> )
|
||||||
|
: ''}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -3,11 +3,11 @@ import {
|
||||||
connect
|
connect
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
import {
|
import {
|
||||||
doFetchDownloadedContent,
|
doFetchFileInfosAndPublishedClaims,
|
||||||
} from 'actions/file_info'
|
} from 'actions/file_info'
|
||||||
import {
|
import {
|
||||||
selectDownloadedFileInfo,
|
selectFileInfosDownloaded,
|
||||||
selectFetchingDownloadedContent,
|
selectFileListDownloadedOrPublishedIsPending,
|
||||||
} from 'selectors/file_info'
|
} from 'selectors/file_info'
|
||||||
import {
|
import {
|
||||||
doNavigate,
|
doNavigate,
|
||||||
|
@ -15,13 +15,13 @@ import {
|
||||||
import FileListDownloaded from './view'
|
import FileListDownloaded from './view'
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
downloadedContent: selectDownloadedFileInfo(state),
|
fileInfos: selectFileInfosDownloaded(state),
|
||||||
fetching: selectFetchingDownloadedContent(state),
|
isPending: selectFileListDownloadedOrPublishedIsPending(state),
|
||||||
})
|
})
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
navigate: (path) => dispatch(doNavigate(path)),
|
navigate: (path) => dispatch(doNavigate(path)),
|
||||||
fetchFileListDownloaded: () => dispatch(doFetchDownloadedContent()),
|
fetchFileInfosDownloaded: () => dispatch(doFetchFileInfosAndPublishedClaims()),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(select, perform)(FileListDownloaded)
|
export default connect(select, perform)(FileListDownloaded)
|
||||||
|
|
|
@ -12,21 +12,21 @@ import SubHeader from 'component/subHeader'
|
||||||
|
|
||||||
class FileListDownloaded extends React.Component {
|
class FileListDownloaded extends React.Component {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this.props.fetchFileListDownloaded()
|
this.props.fetchFileInfosDownloaded()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
downloadedContent,
|
fileInfos,
|
||||||
fetching,
|
isPending,
|
||||||
navigate,
|
navigate,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
let content
|
let content
|
||||||
if (downloadedContent && downloadedContent.length > 0) {
|
if (fileInfos && fileInfos.length > 0) {
|
||||||
content = <FileList fileInfos={downloadedContent} fetching={fetching} hidePrices={true} />
|
content = <FileList fileInfos={fileInfos} fetching={isPending} />
|
||||||
} else {
|
} else {
|
||||||
if (fetching) {
|
if (isPending) {
|
||||||
content = <BusyMessage message="Loading" />
|
content = <BusyMessage message="Loading" />
|
||||||
} else {
|
} else {
|
||||||
content = <span>You haven't downloaded anything from LBRY yet. Go <Link onClick={() => navigate('/discover')} label="search for your first download" />!</span>
|
content = <span>You haven't downloaded anything from LBRY yet. Go <Link onClick={() => navigate('/discover')} label="search for your first download" />!</span>
|
||||||
|
|
|
@ -3,13 +3,11 @@ import {
|
||||||
connect
|
connect
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
import {
|
import {
|
||||||
doFetchPublishedContent,
|
doFetchFileInfosAndPublishedClaims,
|
||||||
} from 'actions/content'
|
} from 'actions/file_info'
|
||||||
import {
|
import {
|
||||||
selectFetchingPublishedContent,
|
selectFileInfosPublished,
|
||||||
} from 'selectors/content'
|
selectFileListDownloadedOrPublishedIsPending
|
||||||
import {
|
|
||||||
selectPublishedFileInfo,
|
|
||||||
} from 'selectors/file_info'
|
} from 'selectors/file_info'
|
||||||
import {
|
import {
|
||||||
doNavigate,
|
doNavigate,
|
||||||
|
@ -17,13 +15,13 @@ import {
|
||||||
import FileListPublished from './view'
|
import FileListPublished from './view'
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
publishedContent: selectPublishedFileInfo(state),
|
fileInfos: selectFileInfosPublished(state),
|
||||||
fetching: selectFetchingPublishedContent(state),
|
isPending: selectFileListDownloadedOrPublishedIsPending(state),
|
||||||
})
|
})
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
navigate: (path) => dispatch(doNavigate(path)),
|
navigate: (path) => dispatch(doNavigate(path)),
|
||||||
fetchFileListPublished: () => dispatch(doFetchPublishedContent()),
|
fetchFileListPublished: () => dispatch(doFetchFileInfosAndPublishedClaims()),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(select, perform)(FileListPublished)
|
export default connect(select, perform)(FileListPublished)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import lbry from 'lbry.js';
|
||||||
import lbryuri from 'lbryuri.js';
|
import lbryuri from 'lbryuri.js';
|
||||||
import Link from 'component/link';
|
import Link from 'component/link';
|
||||||
import {FormField} from 'component/form.js';
|
import {FormField} from 'component/form.js';
|
||||||
import {FileTile} from 'component/fileTile';
|
import FileTile from 'component/fileTile';
|
||||||
import rewards from 'rewards.js';
|
import rewards from 'rewards.js';
|
||||||
import lbryio from 'lbryio.js';
|
import lbryio from 'lbryio.js';
|
||||||
import {BusyMessage, Thumbnail} from 'component/common.js';
|
import {BusyMessage, Thumbnail} from 'component/common.js';
|
||||||
|
@ -16,7 +16,7 @@ class FileListPublished extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
if(this.props.publishedContent.length > 0) this._requestPublishReward()
|
if(this.props.fileInfos.length > 0) this._requestPublishReward()
|
||||||
}
|
}
|
||||||
|
|
||||||
_requestPublishReward() {
|
_requestPublishReward() {
|
||||||
|
@ -38,17 +38,17 @@ class FileListPublished extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
publishedContent,
|
fileInfos,
|
||||||
fetching,
|
isPending,
|
||||||
navigate,
|
navigate,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
let content
|
let content
|
||||||
|
|
||||||
if (publishedContent && publishedContent.length > 0) {
|
if (fileInfos && fileInfos.length > 0) {
|
||||||
content = <FileList fileInfos={publishedContent} fetching={fetching} hidePrices={true} />
|
content = <FileList fileInfos={fileInfos} fetching={isPending} fileTileShowEmpty={FileTile.SHOW_EMPTY_PENDING} />
|
||||||
} else {
|
} else {
|
||||||
if (fetching) {
|
if (isPending) {
|
||||||
content = <BusyMessage message="Loading" />
|
content = <BusyMessage message="Loading" />
|
||||||
} else {
|
} else {
|
||||||
content = <span>You haven't downloaded anything from LBRY yet. Go <Link onClick={() => navigate('/discover')} label="search for your first download" />!</span>
|
content = <span>You haven't downloaded anything from LBRY yet. Go <Link onClick={() => navigate('/discover')} label="search for your first download" />!</span>
|
||||||
|
|
|
@ -61,10 +61,10 @@ class FilePage extends React.Component{
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
claim,
|
claim,
|
||||||
|
fileInfo,
|
||||||
metadata,
|
metadata,
|
||||||
contentType,
|
contentType,
|
||||||
uri,
|
uri,
|
||||||
fileInfo,
|
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!claim || !metadata) {
|
if (!claim || !metadata) {
|
||||||
|
|
|
@ -24,9 +24,6 @@ var HelpPage = React.createClass({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
|
||||||
document.title = "Help";
|
|
||||||
},
|
|
||||||
render: function() {
|
render: function() {
|
||||||
let ver, osName, platform, newVerLink;
|
let ver, osName, platform, newVerLink;
|
||||||
if (this.state.versionInfo) {
|
if (this.state.versionInfo) {
|
||||||
|
|
|
@ -5,9 +5,13 @@ import {
|
||||||
import {
|
import {
|
||||||
doNavigate,
|
doNavigate,
|
||||||
} from 'actions/app'
|
} from 'actions/app'
|
||||||
|
import {
|
||||||
|
selectMyClaims
|
||||||
|
} from 'selectors/claims'
|
||||||
import PublishPage from './view'
|
import PublishPage from './view'
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
|
myClaims: selectMyClaims(state)
|
||||||
})
|
})
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbry from 'lbry';
|
import lbry from 'lbry';
|
||||||
|
import lbryuri from 'lbryuri'
|
||||||
import {FormField, FormRow} from 'component/form.js';
|
import {FormField, FormRow} from 'component/form.js';
|
||||||
import Link from 'component/link';
|
import Link from 'component/link';
|
||||||
import rewards from 'rewards';
|
import rewards from 'rewards';
|
||||||
|
@ -169,7 +170,7 @@ var PublishPage = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lbry.nameIsValid(rawName, false)) {
|
if (!lbryuri.isValidName(rawName, false)) {
|
||||||
this.refs.name.showError('LBRY names must contain only letters, numbers and dashes.');
|
this.refs.name.showError('LBRY names must contain only letters, numbers and dashes.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -182,50 +183,45 @@ var PublishPage = React.createClass({
|
||||||
myClaimExists: null,
|
myClaimExists: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
lbry.getMyClaim(name, (myClaimInfo) => {
|
const myClaimInfo = Object.values(this.props.myClaims).find(claim => claim.name === name)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
myClaimExists: !!myClaimInfo,
|
||||||
|
});
|
||||||
|
lbry.resolve({uri: name}).then((claimInfo) => {
|
||||||
if (name != this.state.name) {
|
if (name != this.state.name) {
|
||||||
// A new name has been typed already, so bail
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
if (!claimInfo) {
|
||||||
myClaimExists: !!myClaimInfo,
|
|
||||||
});
|
|
||||||
lbry.resolve({uri: name}).then((claimInfo) => {
|
|
||||||
if (name != this.state.name) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!claimInfo) {
|
|
||||||
this.setState({
|
|
||||||
nameResolved: false,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const topClaimIsMine = (myClaimInfo && myClaimInfo.claim.amount >= claimInfo.claim.amount);
|
|
||||||
const newState = {
|
|
||||||
nameResolved: true,
|
|
||||||
topClaimValue: parseFloat(claimInfo.claim.amount),
|
|
||||||
myClaimExists: !!myClaimInfo,
|
|
||||||
myClaimValue: myClaimInfo ? parseFloat(myClaimInfo.claim.amount) : null,
|
|
||||||
myClaimMetadata: myClaimInfo ? myClaimInfo.value : null,
|
|
||||||
topClaimIsMine: topClaimIsMine,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (topClaimIsMine) {
|
|
||||||
newState.bid = myClaimInfo.claim.amount;
|
|
||||||
} else if (this.state.myClaimMetadata) {
|
|
||||||
// Just changed away from a name we have a claim on, so clear pre-fill
|
|
||||||
newState.bid = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(newState);
|
|
||||||
}
|
|
||||||
}, () => { // Assume an error means the name is available
|
|
||||||
this.setState({
|
this.setState({
|
||||||
name: name,
|
|
||||||
nameResolved: false,
|
nameResolved: false,
|
||||||
myClaimExists: false,
|
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
const topClaimIsMine = (myClaimInfo && myClaimInfo.claim.amount >= claimInfo.claim.amount);
|
||||||
|
const newState = {
|
||||||
|
nameResolved: true,
|
||||||
|
topClaimValue: parseFloat(claimInfo.claim.amount),
|
||||||
|
myClaimExists: !!myClaimInfo,
|
||||||
|
myClaimValue: myClaimInfo ? parseFloat(myClaimInfo.claim.amount) : null,
|
||||||
|
myClaimMetadata: myClaimInfo ? myClaimInfo.value : null,
|
||||||
|
topClaimIsMine: topClaimIsMine,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (topClaimIsMine) {
|
||||||
|
newState.bid = myClaimInfo.claim.amount;
|
||||||
|
} else if (this.state.myClaimMetadata) {
|
||||||
|
// Just changed away from a name we have a claim on, so clear pre-fill
|
||||||
|
newState.bid = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(newState);
|
||||||
|
}
|
||||||
|
}, () => { // Assume an error means the name is available
|
||||||
|
this.setState({
|
||||||
|
name: name,
|
||||||
|
nameResolved: false,
|
||||||
|
myClaimExists: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -287,7 +283,7 @@ var PublishPage = React.createClass({
|
||||||
handleNewChannelNameChange: function (event) {
|
handleNewChannelNameChange: function (event) {
|
||||||
const newChannelName = (event.target.value.startsWith('@') ? event.target.value : '@' + event.target.value);
|
const newChannelName = (event.target.value.startsWith('@') ? event.target.value : '@' + event.target.value);
|
||||||
|
|
||||||
if (newChannelName.length > 1 && !lbry.nameIsValid(newChannelName.substr(1), false)) {
|
if (newChannelName.length > 1 && !lbryuri.isValidName(newChannelName.substr(1), false)) {
|
||||||
this.refs.newChannelName.showError('LBRY channel names must contain only letters, numbers and dashes.');
|
this.refs.newChannelName.showError('LBRY channel names must contain only letters, numbers and dashes.');
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import lbryuri from 'lbryuri'
|
||||||
import {
|
import {
|
||||||
BusyMessage,
|
BusyMessage,
|
||||||
} from 'component/common';
|
} from 'component/common';
|
||||||
|
import ChannelPage from 'page/channel'
|
||||||
import FilePage from 'page/filePage'
|
import FilePage from 'page/filePage'
|
||||||
|
|
||||||
class ShowPage extends React.Component{
|
class ShowPage extends React.Component{
|
||||||
|
@ -21,8 +23,6 @@ class ShowPage extends React.Component{
|
||||||
uri,
|
uri,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
console.log('show page resolve ' + uri)
|
|
||||||
console.log('isResolving: ' + isResolvingUri)
|
|
||||||
if(!isResolvingUri && claim === undefined && uri) {
|
if(!isResolvingUri && claim === undefined && uri) {
|
||||||
resolveUri(uri)
|
resolveUri(uri)
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,7 @@ class ShowPage extends React.Component{
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
else if (claim.name.length && claim.name[0] === '@') {
|
else if (claim.name.length && claim.name[0] === '@') {
|
||||||
innerContent = "channel"
|
innerContent = <ChannelPage uri={lbryuri.build({ name: claim.name, claimId: claim.claim_id })} />
|
||||||
// innerContent = <ChannelPage claim={claim} />
|
|
||||||
}
|
}
|
||||||
else if (claim) {
|
else if (claim) {
|
||||||
innerContent = <FilePage uri={uri} />
|
innerContent = <FilePage uri={uri} />
|
||||||
|
|
|
@ -39,6 +39,24 @@ reducers[types.RESOLVE_URI_CANCELED] = function(state, action) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
reducers[types.CLAIM_LIST_MINE_STARTED] = function(state, action) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
isClaimListMinePending: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
reducers[types.CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
||||||
|
const myClaims = Object.assign({}, state.myClaims)
|
||||||
|
action.data.claims.forEach((claim) => {
|
||||||
|
myClaims[claim.claim_id] = claim
|
||||||
|
})
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
isClaimListMinePending: false,
|
||||||
|
myClaims: myClaims
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
|
reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
|
||||||
const {
|
const {
|
||||||
uri,
|
uri,
|
||||||
|
@ -56,23 +74,6 @@ reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
reducers[types.FETCH_MY_CLAIMS_COMPLETED] = function(state, action) {
|
|
||||||
const {
|
|
||||||
claims,
|
|
||||||
} = action.data
|
|
||||||
const newMine = Object.assign({}, state.mine)
|
|
||||||
const newById = Object.assign({}, newMine.byId)
|
|
||||||
|
|
||||||
claims.forEach(claim => {
|
|
||||||
newById[claim.claim_id] = claim
|
|
||||||
})
|
|
||||||
newMine.byId = newById
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
mine: newMine,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
if (handler) return handler(state, action);
|
if (handler) return handler(state, action);
|
||||||
|
|
|
@ -64,22 +64,19 @@ reducers[types.DOWNLOADING_STARTED] = function(state, action) {
|
||||||
outpoint,
|
outpoint,
|
||||||
fileInfo,
|
fileInfo,
|
||||||
} = action.data
|
} = action.data
|
||||||
const newFileInfos = Object.assign({}, state.fileInfos)
|
|
||||||
const newDownloading = Object.assign({}, state.downloading)
|
|
||||||
const newDownloadingByUri = Object.assign({}, newDownloading.byUri)
|
|
||||||
const newLoading = Object.assign({}, state.loading)
|
|
||||||
const newLoadingByUri = Object.assign({}, newLoading)
|
|
||||||
|
|
||||||
newDownloadingByUri[uri] = true
|
const newFileInfos = Object.assign({}, state.fileInfos)
|
||||||
newDownloading.byUri = newDownloadingByUri
|
const newDownloading = Object.assign({}, state.urisDownloading)
|
||||||
|
const newLoading = Object.assign({}, state.urisLoading)
|
||||||
|
|
||||||
|
newDownloading[uri] = true
|
||||||
newFileInfos[outpoint] = fileInfo
|
newFileInfos[outpoint] = fileInfo
|
||||||
delete newLoadingByUri[uri]
|
delete newLoading[uri]
|
||||||
newLoading.byUri = newLoadingByUri
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
downloading: newDownloading,
|
urisDownloading: newDownloading,
|
||||||
|
urisLoading: newLoading,
|
||||||
fileInfos: newFileInfos,
|
fileInfos: newFileInfos,
|
||||||
loading: newLoading,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,15 +86,16 @@ reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) {
|
||||||
outpoint,
|
outpoint,
|
||||||
fileInfo,
|
fileInfo,
|
||||||
} = action.data
|
} = action.data
|
||||||
|
|
||||||
const newFileInfos = Object.assign({}, state.fileInfos)
|
const newFileInfos = Object.assign({}, state.fileInfos)
|
||||||
const newDownloading = Object.assign({}, state.downloading)
|
const newDownloading = Object.assign({}, state.urisDownloading)
|
||||||
|
|
||||||
newFileInfos[outpoint] = fileInfo
|
newFileInfos[outpoint] = fileInfo
|
||||||
newDownloading[uri] = true
|
newDownloading[uri] = true
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
fileInfos: newByUri,
|
fileInfos: newFileInfos,
|
||||||
downloading: newDownloading
|
urisDownloading: newDownloading
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,49 +105,29 @@ reducers[types.DOWNLOADING_COMPLETED] = function(state, action) {
|
||||||
outpoint,
|
outpoint,
|
||||||
fileInfo,
|
fileInfo,
|
||||||
} = action.data
|
} = action.data
|
||||||
|
|
||||||
const newFileInfos = Object.assign({}, state.fileInfos)
|
const newFileInfos = Object.assign({}, state.fileInfos)
|
||||||
const newDownloading = Object.assign({}, state.downloading)
|
const newDownloading = Object.assign({}, state.urisDownloading)
|
||||||
const newDownloadingByUri = Object.assign({}, newDownloading.byUri)
|
|
||||||
|
|
||||||
newFileInfos[outpoint] = fileInfo
|
newFileInfos[outpoint] = fileInfo
|
||||||
delete newDownloadingByUri[uri]
|
delete newDownloading[uri]
|
||||||
newDownloading.byUri = newDownloadingByUri
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
fileInfos: newFileInfos,
|
fileInfos: newFileInfos,
|
||||||
downloading: newDownloading,
|
urisDownloading: newDownloading,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
reducers[types.DELETE_FILE_STARTED] = function(state, action) {
|
reducers[types.FILE_DELETE] = function(state, action) {
|
||||||
const {
|
const {
|
||||||
outpoint
|
outpoint,
|
||||||
} = action.data
|
} = action.data
|
||||||
const newDeleting = Object.assign({}, state.deleting)
|
|
||||||
const newByUri = Object.assign({}, newDeleting.byUri)
|
|
||||||
|
|
||||||
newFileInfos[outpoint] = true
|
|
||||||
newDeleting.byUri = newFileInfos
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
deleting: newDeleting,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
reducers[types.DELETE_FILE_COMPLETED] = function(state, action) {
|
|
||||||
const {
|
|
||||||
uri,
|
|
||||||
} = action.data
|
|
||||||
const newDeleting = Object.assign({}, state.deleting)
|
|
||||||
const newDeletingByUri = Object.assign({}, newDeleting.byUri)
|
|
||||||
const newFileInfos = Object.assign({}, state.fileInfos)
|
const newFileInfos = Object.assign({}, state.fileInfos)
|
||||||
|
|
||||||
delete newDeletingByUri[uri]
|
|
||||||
newDeleting.byUri = newDeletingByUri
|
|
||||||
delete newFileInfos[outpoint]
|
delete newFileInfos[outpoint]
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
deleting: newDeleting,
|
|
||||||
fileInfos: newFileInfos,
|
fileInfos: newFileInfos,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -158,14 +136,13 @@ reducers[types.LOADING_VIDEO_STARTED] = function(state, action) {
|
||||||
const {
|
const {
|
||||||
uri,
|
uri,
|
||||||
} = action.data
|
} = action.data
|
||||||
const newLoading = Object.assign({}, state.loading)
|
|
||||||
const newFileInfos = Object.assign({}, newLoading.byUri)
|
|
||||||
|
|
||||||
newFileInfos[outpoint] = true
|
const newLoading = Object.assign({}, state.urisLoading)
|
||||||
newLoading.byUri = newFileInfos
|
|
||||||
|
newLoading[uri] = true
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
loading: newLoading,
|
urisLoading: newLoading,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,59 +150,16 @@ reducers[types.LOADING_VIDEO_FAILED] = function(state, action) {
|
||||||
const {
|
const {
|
||||||
uri,
|
uri,
|
||||||
} = action.data
|
} = action.data
|
||||||
const newLoading = Object.assign({}, state.loading)
|
|
||||||
const newFileInfos = Object.assign({}, newLoading.byUri)
|
|
||||||
|
|
||||||
delete newFileInfos[outpoint]
|
const newLoading = Object.assign({}, state.urisLoading)
|
||||||
newLoading.byUri = newFileInfos
|
|
||||||
|
delete newLoading[uri]
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
loading: newLoading,
|
urisLoading: newLoading,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
reducers[types.FETCH_DOWNLOADED_CONTENT_STARTED] = function(state, action) {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
fetchingDownloadedContent: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
reducers[types.FETCH_DOWNLOADED_CONTENT_COMPLETED] = function(state, action) {
|
|
||||||
const newFileInfos = Object.assign({}, state.fileInfos)
|
|
||||||
|
|
||||||
action.data.fileInfos.forEach(fileInfo => {
|
|
||||||
newFileInfos[fileInfo.outpoint] = fileInfo
|
|
||||||
})
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
fileInfos: newFileInfos,
|
|
||||||
fetchingDownloadedContent: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
reducers[types.FETCH_PUBLISHED_CONTENT_STARTED] = function(state, action) {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
fetchingPublishedContent: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
reducers[types.FETCH_PUBLISHED_CONTENT_COMPLETED] = function(state, action) {
|
|
||||||
const {
|
|
||||||
fileInfos
|
|
||||||
} = action.data
|
|
||||||
const newFileInfos = Object.assign({}, state.fileInfos)
|
|
||||||
|
|
||||||
fileInfos.forEach(fileInfo => {
|
|
||||||
newFileInfos[fileInfo.outpoint] = fileInfo
|
|
||||||
})
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
fileInfos: newFileInfos,
|
|
||||||
fetchingPublishedContent: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
|
|
|
@ -15,17 +15,6 @@ export const selectAllClaimsByChannel = createSelector(
|
||||||
(state) => state.claimsByChannel || {}
|
(state) => state.claimsByChannel || {}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectClaimsForChannel = (state, props) => {
|
|
||||||
return selectAllClaimsByChannel(state)[props.uri]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const makeSelectClaimsForChannel = () => {
|
|
||||||
return createSelector(
|
|
||||||
selectClaimsForChannel,
|
|
||||||
(claim) => claim
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectClaimForUri = (state, props) => {
|
const selectClaimForUri = (state, props) => {
|
||||||
const uri = lbryuri.normalize(props.uri)
|
const uri = lbryuri.normalize(props.uri)
|
||||||
return selectClaimsByUri(state)[uri]
|
return selectClaimsByUri(state)[uri]
|
||||||
|
@ -38,6 +27,17 @@ export const makeSelectClaimForUri = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const selectClaimsInChannelForUri = (state, props) => {
|
||||||
|
return selectAllClaimsByChannel(state)[props.uri]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const makeSelectClaimsInChannelForUri = () => {
|
||||||
|
return createSelector(
|
||||||
|
selectClaimsInChannelForUri,
|
||||||
|
(claims) => claims
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const selectMetadataForUri = (state, props) => {
|
const selectMetadataForUri = (state, props) => {
|
||||||
const claim = selectClaimForUri(state, props)
|
const claim = selectClaimForUri(state, props)
|
||||||
const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata
|
const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata
|
||||||
|
@ -73,26 +73,25 @@ export const makeSelectContentTypeForUri = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectMyClaims = createSelector(
|
export const selectClaimListMineIsPending = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.mine || {}
|
(state) => state.isClaimListMinePending
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectMyClaimsById = createSelector(
|
export const selectMyClaims = createSelector(
|
||||||
selectMyClaims,
|
_selectState,
|
||||||
(mine) => mine.byId || {}
|
(state) => state.myClaims || {}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectMyClaimsOutpoints = createSelector(
|
export const selectMyClaimsOutpoints = createSelector(
|
||||||
selectMyClaimsById,
|
selectMyClaims,
|
||||||
(byId) => {
|
(claims) => {
|
||||||
const outpoints = []
|
if (!claims) {
|
||||||
Object.keys(byId).forEach(key => {
|
return []
|
||||||
const claim = byId[key]
|
}
|
||||||
const outpoint = `${claim.txid}:${claim.nout}`
|
|
||||||
outpoints.push(outpoint)
|
|
||||||
})
|
|
||||||
|
|
||||||
return outpoints
|
return Object.values(claims).map((claim) => {
|
||||||
|
return `${claim.txid}:${claim.nout}`
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,69 +1,38 @@
|
||||||
|
import lbry from 'lbry'
|
||||||
import {
|
import {
|
||||||
createSelector,
|
createSelector,
|
||||||
} from 'reselect'
|
} from 'reselect'
|
||||||
import {
|
import {
|
||||||
selectClaimsByUri,
|
selectClaimsByUri,
|
||||||
|
selectClaimListMineIsPending,
|
||||||
selectMyClaimsOutpoints,
|
selectMyClaimsOutpoints,
|
||||||
} from 'selectors/claims'
|
} from 'selectors/claims'
|
||||||
|
|
||||||
export const _selectState = state => state.fileInfo || {}
|
export const _selectState = state => state.fileInfo || {}
|
||||||
|
|
||||||
export const selectIsFileListPending = createSelector(
|
|
||||||
_selectState,
|
|
||||||
(state) => state.isFileListPending
|
|
||||||
)
|
|
||||||
|
|
||||||
export const selectAllFileInfos = createSelector(
|
export const selectAllFileInfos = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.fileInfos || {}
|
(state) => state.fileInfos || {}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectDownloading = createSelector(
|
export const selectFileListIsPending = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.downloading || {}
|
(state) => state.isFileListPending
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectDownloadingByUri = createSelector(
|
export const selectFileListDownloadedOrPublishedIsPending = createSelector(
|
||||||
selectDownloading,
|
selectFileListIsPending,
|
||||||
(downloading) => downloading.byUri || {}
|
selectClaimListMineIsPending,
|
||||||
)
|
(isFileListPending, isClaimListMinePending) => isFileListPending || isClaimListMinePending
|
||||||
|
|
||||||
export const selectFetchingDownloadedContent = createSelector(
|
|
||||||
_selectState,
|
|
||||||
(state) => !!state.fetchingDownloadedContent
|
|
||||||
)
|
|
||||||
|
|
||||||
export const selectDownloadedContent = createSelector(
|
|
||||||
_selectState,
|
|
||||||
(state) => state.downloadedContent || {}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const selectDownloadedContentFileInfos = createSelector(
|
|
||||||
selectDownloadedContent,
|
|
||||||
(downloadedContent) => downloadedContent.fileInfos || []
|
|
||||||
)
|
|
||||||
|
|
||||||
export const selectFetchingPublishedContent = createSelector(
|
|
||||||
_selectState,
|
|
||||||
(state) => !!state.fetchingPublishedContent
|
|
||||||
)
|
|
||||||
|
|
||||||
export const selectPublishedContent = createSelector(
|
|
||||||
_selectState,
|
|
||||||
(state) => state.publishedContent || {}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectFileInfoForUri = (state, props) => {
|
export const selectFileInfoForUri = (state, props) => {
|
||||||
const claims = selectClaimsByUri(state),
|
const claims = selectClaimsByUri(state),
|
||||||
claim = claims[props.uri],
|
claim = claims[props.uri],
|
||||||
|
fileInfos = selectAllFileInfos(state),
|
||||||
outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined
|
outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined
|
||||||
|
|
||||||
console.log('select file info')
|
return outpoint && fileInfos ? fileInfos[outpoint] : undefined
|
||||||
console.log(claims)
|
|
||||||
console.log(claim)
|
|
||||||
console.log(outpoint)
|
|
||||||
console.log(selectAllFileInfos(state))
|
|
||||||
return outpoint ? selectAllFileInfos(state)[outpoint] : undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeSelectFileInfoForUri = () => {
|
export const makeSelectFileInfoForUri = () => {
|
||||||
|
@ -73,8 +42,13 @@ export const makeSelectFileInfoForUri = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const selectUrisDownloading = createSelector(
|
||||||
|
_selectState,
|
||||||
|
(state) => state.urisDownloading || {}
|
||||||
|
)
|
||||||
|
|
||||||
const selectDownloadingForUri = (state, props) => {
|
const selectDownloadingForUri = (state, props) => {
|
||||||
const byUri = selectDownloadingByUri(state)
|
const byUri = selectUrisDownloading(state)
|
||||||
return byUri[props.uri]
|
return byUri[props.uri]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,18 +59,13 @@ export const makeSelectDownloadingForUri = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectLoading = createSelector(
|
export const selectUrisLoading = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.loading || {}
|
(state) => state.urisLoading || {}
|
||||||
)
|
|
||||||
|
|
||||||
export const selectLoadingByUri = createSelector(
|
|
||||||
selectLoading,
|
|
||||||
(loading) => loading.byUri || {}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const selectLoadingForUri = (state, props) => {
|
const selectLoadingForUri = (state, props) => {
|
||||||
const byUri = selectLoadingByUri(state)
|
const byUri = selectUrisLoading(state)
|
||||||
return byUri[props.uri]
|
return byUri[props.uri]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,13 +76,13 @@ export const makeSelectLoadingForUri = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectDownloadedFileInfo = createSelector(
|
export const selectFileInfosDownloaded = createSelector(
|
||||||
selectAllFileInfos,
|
selectAllFileInfos,
|
||||||
(fileInfos) => {
|
selectMyClaimsOutpoints,
|
||||||
|
(fileInfos, myClaimOutpoints) => {
|
||||||
const fileInfoList = []
|
const fileInfoList = []
|
||||||
Object.keys(fileInfos).forEach(outpoint => {
|
Object.values(fileInfos).forEach(fileInfo => {
|
||||||
const fileInfo = fileInfos[outpoint]
|
if (fileInfo && myClaimOutpoints.indexOf(fileInfo.outpoint) === -1 && (fileInfo.completed || fileInfo.written_bytes)) {
|
||||||
if (fileInfo.completed || fileInfo.written_bytes) {
|
|
||||||
fileInfoList.push(fileInfo)
|
fileInfoList.push(fileInfo)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -121,20 +90,24 @@ export const selectDownloadedFileInfo = createSelector(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectPublishedFileInfo = createSelector(
|
export const selectFileInfosPendingPublish = createSelector(
|
||||||
selectAllFileInfos,
|
_selectState,
|
||||||
selectMyClaimsOutpoints,
|
(state) => {
|
||||||
(byUri, outpoints) => {
|
return lbry.getPendingPublishes()
|
||||||
const fileInfos = []
|
}
|
||||||
outpoints.forEach(outpoint => {
|
)
|
||||||
Object.keys(byUri).forEach(key => {
|
|
||||||
const fileInfo = byUri[key]
|
export const selectFileInfosPublished = createSelector(
|
||||||
if (fileInfo.outpoint == outpoint) {
|
selectAllFileInfos,
|
||||||
fileInfos.push(fileInfo)
|
selectFileInfosPendingPublish,
|
||||||
}
|
selectMyClaimsOutpoints,
|
||||||
})
|
(allFileInfos, pendingFileInfos, outpoints) => {
|
||||||
})
|
const fileInfos = []
|
||||||
|
outpoints.forEach(outpoint => {
|
||||||
return fileInfos
|
if (allFileInfos[outpoint]) {
|
||||||
|
fileInfos.push(allFileInfos[outpoint])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return [...fileInfos, ...pendingFileInfos]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue