i'm making things better... right?

This commit is contained in:
Jeremy Kauffman 2017-05-14 23:50:59 -04:00
parent 0fad6864ec
commit 6783bcdfeb
35 changed files with 346 additions and 556 deletions

View file

@ -6,7 +6,6 @@ import {
selectUpgradeDownloadItem,
selectUpgradeFilename,
selectPageTitle,
selectCurrentPath,
} from 'selectors/app'
const {remote, ipcRenderer, shell} = require('electron');

View file

@ -1,39 +1,29 @@
import * as types from 'constants/action_types'
import lbry from 'lbry'
import {
selectCurrentUri,
} from 'selectors/app'
selectFetchingAvailability
} from 'selectors/availability'
export function doFetchUriAvailability(uri) {
return function(dispatch, getState) {
dispatch({
type: types.FETCH_AVAILABILITY_STARTED,
data: { uri }
})
const successCallback = (availability) => {
dispatch({
type: types.FETCH_AVAILABILITY_COMPLETED,
data: {
availability,
uri,
}
})
}
const errorCallback = () => {
console.debug('error')
}
lbry.get_availability({ uri }, successCallback, errorCallback)
}
}
export function doFetchCurrentUriAvailability() {
export function doFetchAvailability(uri) {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
const alreadyFetching = !!selectFetchingAvailability(state)[uri]
dispatch(doFetchUriAvailability(uri))
if (!alreadyFetching) {
dispatch({
type: types.FETCH_AVAILABILITY_STARTED,
data: {uri}
})
lbry.get_availability({uri}).then((availability) => {
dispatch({
type: types.FETCH_AVAILABILITY_COMPLETED,
data: {
availability,
uri,
}
})
})
}
}
}
}

View file

@ -3,18 +3,15 @@ import lbry from 'lbry'
import lbryio from 'lbryio'
import lbryuri from 'lbryuri'
import rewards from 'rewards'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectBalance,
} from 'selectors/wallet'
import {
selectCurrentUriFileInfo,
selectFileInfoForUri,
selectDownloadingByUri,
} from 'selectors/file_info'
import {
selectCurrentUriCostInfo,
selectCostInfoForUri,
} from 'selectors/cost_info'
import {
selectClaimsByUri,
@ -44,15 +41,6 @@ export function doResolveUri(uri) {
certificate,
}
})
}).catch(() => {
dispatch({
type: types.RESOLVE_URI_COMPLETED,
data: {
uri,
claim: null,
certificate: null,
}
})
})
}
}
@ -120,8 +108,6 @@ export function doFetchPublishedContent() {
export function doFetchFeaturedUris() {
return function(dispatch, getState) {
return
const state = getState()
dispatch({
@ -229,10 +215,9 @@ export function doDownloadFile(uri, streamInfo) {
}
}
export function doLoadVideo() {
export function doLoadVideo(uri) {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
dispatch({
type: types.LOADING_VIDEO_STARTED,
@ -259,13 +244,12 @@ export function doLoadVideo() {
}
}
export function doWatchVideo() {
export function doWatchVideo(uri) {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
const balance = selectBalance(state)
const fileInfo = selectCurrentUriFileInfo(state)
const costInfo = selectCurrentUriCostInfo(state)
const fileInfo = selectFileInfoForUri(state, { uri })
const costInfo = selectCostInfoForUri(state, { uri })
const downloadingByUri = selectDownloadingByUri(state)
const alreadyDownloading = !!downloadingByUri[uri]
const { cost } = costInfo
@ -287,8 +271,8 @@ export function doWatchVideo() {
}
// the file is free or we have partially downloaded it
if (cost <= 0.01 || fileInfo.download_directory) {
dispatch(doLoadVideo())
if (cost <= 0.01 || (fileInfo && fileInfo.download_directory)) {
dispatch(doLoadVideo(uri))
return Promise.resolve()
}
@ -302,7 +286,7 @@ export function doWatchVideo() {
}
}
export function doFetchChannelClaims(uri) {
export function doFetchClaimsByChannel(uri) {
return function(dispatch, getState) {
dispatch({
type: types.FETCH_CHANNEL_CLAIMS_STARTED,
@ -323,7 +307,7 @@ export function doFetchChannelClaims(uri) {
})
}).catch(() => {
dispatch({
type: types.FETCH_CHANNEL_CLAIMS_COMPLETED,
type: types.FETC,
data: {
uri,
claims: []

View file

@ -1,7 +1,4 @@
import * as types from 'constants/action_types'
import {
selectCurrentUri,
} from 'selectors/app'
import lbry from 'lbry'
export function doFetchCostInfoForUri(uri) {

View file

@ -1,11 +1,11 @@
import * as types from 'constants/action_types'
import lbry from 'lbry'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentUriClaimOutpoint,
selectClaimsByUri,
} from 'selectors/claims'
import {
selectLoadingByUri,
} from 'selectors/file_info'
import {
doCloseModal,
} from 'actions/app'
@ -14,29 +14,39 @@ const {
shell,
} = require('electron')
export function doFetchCurrentUriFileInfo() {
export function doFetchFileInfo(uri) {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
const outpoint = selectCurrentUriClaimOutpoint(state)
const claim = selectClaimsByUri(state)[uri]
const outpoint = claim ? `${claim.txid}:${claim.nout}` : null
const alreadyFetching = !!selectLoadingByUri(state)[uri]
dispatch({
type: types.FETCH_FILE_INFO_STARTED,
data: {
uri,
outpoint,
}
})
if (!outpoint) {
console.log(claim);
console.log(outpoint);
console.log(selectClaimsByUri(state))
throw new Error("Unable to get outpoint from claim for URI " + uri);
}
lbry.file_list({ outpoint: outpoint, full_status: true }).then(([fileInfo]) => {
if (!alreadyFetching) {
dispatch({
type: types.FETCH_FILE_INFO_COMPLETED,
type: types.FETCH_FILE_INFO_STARTED,
data: {
uri,
fileInfo,
outpoint,
}
})
})
lbry.file_list({outpoint: outpoint, full_status: true}).then(([fileInfo]) => {
dispatch({
type: types.FETCH_FILE_INFO_COMPLETED,
data: {
uri,
fileInfo,
}
})
})
}
}
}

View file

@ -2,30 +2,19 @@ import React from 'react';
import { connect } from 'react-redux'
import {
selectCurrentPage,
selectCurrentModal,
selectDrawerOpen,
selectHeaderLinks,
selectSearchTerm,
} from 'selectors/app'
import {
doCheckUpgradeAvailable,
doOpenModal,
doCloseModal,
} from 'actions/app'
import App from './view'
const select = (state) => ({
currentPage: selectCurrentPage(state),
modal: selectCurrentModal(state),
headerLinks: selectHeaderLinks(state),
searchTerm: selectSearchTerm(state)
})
const perform = (dispatch) => ({
checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()),
openModal: () => dispatch(doOpenModal()),
closeModal: () => dispatch(doCloseModal()),
})
export default connect(select, perform)(App)

View file

@ -20,7 +20,6 @@ class App extends React.Component {
render() {
const {
modal,
headerLinks,
} = this.props
return <div id="window">

View file

@ -3,8 +3,6 @@ import {
connect,
} from 'react-redux'
import {
selectObscureNsfw,
selectHidePrice,
selectHasSignature,
selectPlatform,
} from 'selectors/app'
@ -14,7 +12,7 @@ import {
makeSelectLoadingForUri,
} from 'selectors/file_info'
import {
makeSelectAvailabilityForUri,
makeSelectIsAvailableForUri,
} from 'selectors/availability'
import {
selectCurrentModal,
@ -23,6 +21,9 @@ import {
doCloseModal,
doOpenModal,
} from 'actions/app'
import {
doFetchAvailability
} from 'actions/availability'
import {
doOpenFileInShell,
doOpenFileInFolder,
@ -36,33 +37,29 @@ import FileActions from './view'
const makeSelect = () => {
const selectFileInfoForUri = makeSelectFileInfoForUri()
const selectAvailabilityForUri = makeSelectAvailabilityForUri()
const selectIsAvailableForUri = makeSelectIsAvailableForUri()
const selectDownloadingForUri = makeSelectDownloadingForUri()
const selectLoadingForUri = makeSelectLoadingForUri()
const select = (state, props) => ({
obscureNsfw: selectObscureNsfw(state),
hidePrice: selectHidePrice(state),
hasSignature: selectHasSignature(state),
fileInfo: selectFileInfoForUri(state, props),
availability: selectAvailabilityForUri(state, props),
isAvailable: selectIsAvailableForUri(state, props),
platform: selectPlatform(state),
modal: selectCurrentModal(state),
downloading: selectDownloadingForUri(state, props),
loading: selectLoadingForUri(state, props),
})
return select
}
const perform = (dispatch) => ({
checkAvailability: (uri) => dispatch(doFetchAvailability(uri)),
closeModal: () => dispatch(doCloseModal()),
openInFolder: (fileInfo) => dispatch(doOpenFileInFolder(fileInfo)),
openInShell: (fileInfo) => dispatch(doOpenFileInShell(fileInfo)),
deleteFile: (fileInfo, deleteFromComputer) => dispatch(doDeleteFile(fileInfo, deleteFromComputer)),
openModal: (modal) => dispatch(doOpenModal(modal)),
downloadClick: () => dispatch(doWatchVideo()),
loadVideo: () => dispatch(doLoadVideo())
startDownload: (uri) => dispatch(doWatchVideo(uri)),
loadVideo: (uri) => dispatch(doLoadVideo(uri))
})
export default connect(makeSelect, perform)(FileActions)
export default connect(makeSelect, perform)(FileActions)

View file

@ -1,7 +1,5 @@
import React from 'react';
import lbry from 'lbry';
import lbryuri from 'lbryuri';
import {Icon,} from 'component/common';
import {Icon,BusyMessage} from 'component/common';
import FilePrice from 'component/filePrice'
import {Modal} from 'component/modal';
import {FormField} from 'component/form';
@ -9,14 +7,36 @@ import Link from 'component/link';
import {ToolTip} from 'component/tooltip';
import {DropDownMenu, DropDownMenuItem} from 'component/menu';
class FileActionsRow extends React.Component {
class FileActions extends React.Component {
constructor(props) {
super(props)
this.state = {
forceShowActions: false,
deleteChecked: false,
}
}
componentWillMount() {
this.checkAvailability(this.props.uri)
}
componentWillReceiveProps(nextProps) {
this.checkAvailability(nextProps.uri)
}
checkAvailability(uri) {
if (!this._uri || uri !== this._uri) {
this._uri = uri;
this.props.checkAvailability(uri)
}
}
onShowFileActionsRowClicked() {
this.setState({
forceShowActions: true,
});
}
handleDeleteCheckboxClicked(event) {
this.setState({
deleteChecked: event.target.checked,
@ -25,65 +45,73 @@ class FileActionsRow extends React.Component {
onAffirmPurchase() {
this.props.closeModal()
this.props.loadVideo()
this.props.loadVideo(this.props.uri)
}
render() {
const {
fileInfo,
isAvailable,
platform,
downloading,
loading,
uri,
deleteFile,
openInFolder,
openInShell,
modal,
openModal,
affirmPurchase,
closeModal,
downloadClick,
startDownload,
} = this.props
const {
deleteChecked,
} = this.state
const deleteChecked = this.state.deleteChecked,
metadata = fileInfo ? fileInfo.metadata : null,
openInFolderMessage = platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
showMenu = fileInfo && Object.keys(fileInfo).length > 0,
title = metadata ? metadata.title : uri;
const metadata = fileInfo ? fileInfo.metadata : null
let content
if (!fileInfo)
{
return null;
}
if (fileInfo === undefined || isAvailable === undefined) {
const openInFolderMessage = platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
showMenu = Object.keys(fileInfo).length != 0;
content = <BusyMessage message="Checking availability" />
} else if (!isAvailable && !this.state.forceShowActions) {
content = <div>
<div className="button-set-item empty">Content unavailable.</div>
<ToolTip label="Why?"
body="The content on LBRY is hosted by its users. It appears there are no users connected that have this file at the moment."
className="button-set-item" />
<Link label="Try Anyway" onClick={this.onShowFileActionsRowClicked.bind(this)} className="button-text button-set-item" />
</div>
} else if (fileInfo === null && !downloading) {
content = <Link button="text" label="Download" icon="icon-download" onClick={() => { startDownload(uri) } } />;
} else if (downloading) {
let linkBlock;
if (Object.keys(fileInfo).length == 0 && !downloading && !loading) {
linkBlock = <Link button="text" label="Download" icon="icon-download" onClick={downloadClick} />;
} else if (downloading || loading) {
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>;
linkBlock = (
<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>
);
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) {
content = <Link label="Open" button="text" icon="icon-folder-open" onClick={() => openInShell(fileInfo)} />;
} else {
linkBlock = <Link label="Open" button="text" icon="icon-folder-open" onClick={() => openInShell(fileInfo)} />;
console.log('handle this case of file action props?');
console.log(this.props)
}
const title = metadata ? metadata.title : uri;
return (
<div>
{fileInfo !== null || fileInfo.isMine
? linkBlock
: null}
<section className="file-actions">
{ content }
{ showMenu ?
<DropDownMenu>
<DropDownMenuItem key={0} onClick={() => openInFolder(fileInfo)} label={openInFolderMessage} />
@ -102,62 +130,18 @@ class FileActionsRow extends React.Component {
LBRY was unable to download the stream <strong>{uri}</strong>.
</Modal>
<Modal isOpen={modal == 'confirmRemove'}
contentLabel="Not enough credits"
type="confirm"
confirmButtonLabel="Remove"
onConfirmed={() => deleteFile(uri, fileInfo, deleteChecked)}
onAborted={closeModal}>
contentLabel="Not enough credits"
type="confirm"
confirmButtonLabel="Remove"
onConfirmed={() => deleteFile(uri, fileInfo, deleteChecked)}
onAborted={closeModal}>
<p>Are you sure you'd like to remove <cite>{title}</cite> from LBRY?</p>
<label><FormField type="checkbox" checked={deleteChecked} onClick={this.handleDeleteCheckboxClicked.bind(this)} /> Delete this file from my computer</label>
</Modal>
</div>
</section>
);
}
}
class FileActions extends React.Component {
constructor(props) {
super(props)
this._isMounted = false
this._fileInfoSubscribeId = null
this.state = {
available: true,
forceShowActions: false,
fileInfo: null,
}
}
onShowFileActionsRowClicked() {
this.setState({
forceShowActions: true,
});
}
render() {
const {
fileInfo,
availability,
} = this.props
if (fileInfo === null) {
return null;
}
return (<section className="file-actions">
{
fileInfo || this.state.available || this.state.forceShowActions
? <FileActionsRow {...this.props} />
: <div>
<div className="button-set-item empty">Content unavailable.</div>
<ToolTip label="Why?"
body="The content on LBRY is hosted by its users. It appears there are no users connected that have this file at the moment."
className="button-set-item" />
<Link label="Try Anyway" onClick={this.onShowFileActionsRowClicked.bind(this)} className="button-text button-set-item" />
</div>
}
</section>);
}
}
export default FileActions

View file

@ -9,19 +9,17 @@ import {
doResolveUri,
} from 'actions/content'
import {
selectHidePrice,
selectObscureNsfw,
} from 'selectors/app'
import {
makeSelectClaimForUri,
makeSelectSourceForUri,
makeSelectMetadataForUri,
} from 'selectors/claims'
import {
makeSelectFileInfoForUri,
} from 'selectors/file_info'
import {
makeSelectResolvingUri,
makeSelectIsResolvingForUri,
} from 'selectors/content'
import FileCard from './view'
@ -29,17 +27,14 @@ const makeSelect = () => {
const selectClaimForUri = makeSelectClaimForUri()
const selectFileInfoForUri = makeSelectFileInfoForUri()
const selectMetadataForUri = makeSelectMetadataForUri()
const selectSourceForUri = makeSelectSourceForUri()
const selectResolvingUri = makeSelectResolvingUri()
const selectResolvingUri = makeSelectIsResolvingForUri()
const select = (state, props) => ({
claim: selectClaimForUri(state, props),
fileInfo: selectFileInfoForUri(state, props),
hidePrice: selectHidePrice(state),
obscureNsfw: selectObscureNsfw(state),
hasSignature: false,
metadata: selectMetadataForUri(state, props),
source: selectSourceForUri(state, props),
isResolvingUri: selectResolvingUri(state, props),
})

View file

@ -38,7 +38,6 @@ class FileCard extends React.Component {
metadata,
isResolvingUri,
navigate,
hidePrice,
} = this.props
const uri = lbryuri.normalize(this.props.uri);
@ -59,7 +58,7 @@ class FileCard extends React.Component {
<div className="card__title-identity">
<h5 title={title}><TruncatedText lines={1}>{title}</TruncatedText></h5>
<div className="card__subtitle">
{ !hidePrice ? <span style={{float: "right"}}><FilePrice uri={uri} /></span> : null}
<span style={{float: "right"}}><FilePrice uri={uri} /></span>
<UriIndicator uri={uri} />
</div>
</div>

View file

@ -10,41 +10,30 @@ import {
} from 'actions/content'
import {
makeSelectClaimForUri,
makeSelectSourceForUri,
makeSelectMetadataForUri,
} from 'selectors/claims'
import {
makeSelectFileInfoForUri,
} from 'selectors/file_info'
import {
makeSelectFetchingAvailabilityForUri,
makeSelectAvailabilityForUri,
} from 'selectors/availability'
import {
selectObscureNsfw,
} from 'selectors/app'
import {
makeSelectResolvingUri,
makeSelectIsResolvingForUri,
} from 'selectors/content'
import FileTile from './view'
const makeSelect = () => {
const selectClaimForUri = makeSelectClaimForUri()
const selectFileInfoForUri = makeSelectFileInfoForUri()
const selectFetchingAvailabilityForUri = makeSelectFetchingAvailabilityForUri()
const selectAvailabilityForUri = makeSelectAvailabilityForUri()
const selectMetadataForUri = makeSelectMetadataForUri()
const selectSourceForUri = makeSelectSourceForUri()
const selectResolvingUri = makeSelectResolvingUri()
const selectResolvingUri = makeSelectIsResolvingForUri()
const select = (state, props) => ({
claim: selectClaimForUri(state, props),
fileInfo: selectFileInfoForUri(state, props),
fetchingAvailability: selectFetchingAvailabilityForUri(state, props),
selectAvailabilityForUri: selectAvailabilityForUri(state, props),
obscureNsfw: selectObscureNsfw(state),
metadata: selectMetadataForUri(state, props),
source: selectSourceForUri(state, props),
isResolvingUri: selectResolvingUri(state, props),
})

View file

@ -97,7 +97,7 @@ class FileTile extends React.Component {
} else if (isResolvingUri) {
description = "Loading..."
} else if (showEmpty === FileTile.SHOW_EMPTY_PUBLISH) {
onClick = () => navigate('/publish')
onClick = () => navigate('/publish', { })
description = <span className="empty">
This location is unused. { ' ' }
{ isClaimable && <span className="button-text">Put something here!</span> }

View file

@ -2,14 +2,13 @@ import React from 'react';
import { connect } from 'react-redux';
import Router from './view.jsx';
import {
selectCurrentPage
selectCurrentPage,
selectCurrentParams,
} from 'selectors/app.js';
const select = (state) => ({
params: selectCurrentParams(state),
currentPage: selectCurrentPage(state)
})
const perform = {
}
export default connect(select, null)(Router);

View file

@ -25,25 +25,26 @@ const route = (page, routesMap) => {
const Router = (props) => {
const {
currentPage,
params,
} = props;
return route(currentPage, {
'settings': <SettingsPage {...props} />,
'help': <HelpPage {...props} />,
'report': <ReportPage {...props} />,
'downloaded': <FileListDownloaded {...props} />,
'published': <FileListPublished {...props} />,
'start': <StartPage {...props} />,
'wallet': <WalletPage {...props} />,
'send': <WalletPage {...props} />,
'receive': <WalletPage {...props} />,
'show': <ShowPage {...props} />,
'channel': <ChannelPage {...props} />,
'publish': <PublishPage {...props} />,
'developer': <DeveloperPage {...props} />,
'discover': <DiscoverPage {...props} />,
'rewards': <RewardsPage {...props} />,
'search': <SearchPage {...props} />,
'settings': <SettingsPage {...params} />,
'help': <HelpPage {...params} />,
'report': <ReportPage {...params} />,
'downloaded': <FileListDownloaded {...params} />,
'published': <FileListPublished {...params} />,
'start': <StartPage {...params} />,
'wallet': <WalletPage {...params} />,
'send': <WalletPage {...params} />,
'receive': <WalletPage {...params} />,
'show': <ShowPage {...params} />,
'channel': <ChannelPage {...params} />,
'publish': <PublishPage {...params} />,
'developer': <DeveloperPage {...params} />,
'discover': <DiscoverPage {...params} />,
'rewards': <RewardsPage {...params} />,
'search': <SearchPage {...params} />,
})
}

View file

@ -13,30 +13,42 @@ import {
doLoadVideo,
} from 'actions/content'
import {
selectLoadingCurrentUri,
selectCurrentUriFileReadyToPlay,
selectCurrentUriIsPlaying,
selectCurrentUriFileInfo,
selectDownloadingCurrentUri,
makeSelectMetadataForUri
} from 'selectors/claims'
import {
makeSelectFileInfoForUri,
makeSelectLoadingForUri,
makeSelectDownloadingForUri,
} from 'selectors/file_info'
import {
selectCurrentUriCostInfo,
makeSelectCostInfoForUri,
} from 'selectors/cost_info'
import Video from './view'
const select = (state) => ({
costInfo: selectCurrentUriCostInfo(state),
fileInfo: selectCurrentUriFileInfo(state),
modal: selectCurrentModal(state),
isLoading: selectLoadingCurrentUri(state),
readyToPlay: selectCurrentUriFileReadyToPlay(state),
isDownloading: selectDownloadingCurrentUri(state),
})
const makeSelect = () => {
const selectCostInfo = makeSelectCostInfoForUri()
const selectFileInfo = makeSelectFileInfoForUri()
const selectIsLoading = makeSelectLoadingForUri()
const selectIsDownloading = makeSelectDownloadingForUri()
const selectMetadata = makeSelectMetadataForUri()
const select = (state, props) => ({
costInfo: selectCostInfo(state, props),
fileInfo: selectFileInfo(state, props),
metadata: selectMetadata(state, props),
modal: selectCurrentModal(state),
isLoading: selectIsLoading(state, props),
isDownloading: selectIsDownloading(state, props),
})
return select
}
const perform = (dispatch) => ({
loadVideo: () => dispatch(doLoadVideo()),
watchVideo: (elem) => dispatch(doWatchVideo()),
loadVideo: (uri) => dispatch(doLoadVideo(uri)),
watchVideo: (uri) => dispatch(doWatchVideo(uri)),
closeModal: () => dispatch(doCloseModal()),
})
export default connect(select, perform)(Video)
export default connect(makeSelect, perform)(Video)

View file

@ -1,17 +1,13 @@
import React from 'react';
import {
Icon,
Thumbnail,
} from 'component/common';
import FilePrice from 'component/filePrice'
import Link from 'component/link';
import Modal from 'component/modal';
class WatchLink extends React.Component {
class VideoPlayButton extends React.Component {
confirmPurchaseClick() {
this.props.closeModal()
this.props.startPlaying()
this.props.loadVideo()
this.props.loadVideo(this.props.uri)
}
render() {
@ -32,9 +28,17 @@ class WatchLink extends React.Component {
fileInfo,
} = this.props
/*
title={
isLoading ? "Video is Loading" :
!costInfo ? "Waiting on cost info..." :
fileInfo === undefined ? "Waiting on file info..." : ""
}
*/
return (<div>
<Link button={ button ? button : null }
disabled={isLoading || !costInfo || costInfo.cost == undefined || fileInfo === undefined}
disabled={isLoading || !costInfo || costInfo.cost === undefined || fileInfo === undefined}
label={label ? label : ""}
className="video__play-button"
icon="icon-play"
@ -68,7 +72,7 @@ class Video extends React.Component {
}
onWatchClick() {
this.props.watchVideo().then(() => {
this.props.watchVideo(this.props.uri).then(() => {
if (!this.props.modal) {
this.setState({
isPlaying: true
@ -85,8 +89,6 @@ class Video extends React.Component {
render() {
const {
readyToPlay = false,
thumbnail,
metadata,
isLoading,
isDownloading,
@ -105,14 +107,14 @@ class Video extends React.Component {
}
return (
<div className={"video " + this.props.className + (isPlaying && readyToPlay ? " video--active" : " video--hidden")}>{
<div className={"video " + this.props.className + (isPlaying && fileInfo.isReadyToPlay ? " video--active" : " video--hidden")}>{
isPlaying ?
!readyToPlay ?
<span>this is the world's worst loading screen and we shipped our software with it anyway... <br /><br />{loadStatusMessage}</span> :
<VideoPlayer downloadPath={fileInfo.download_path} /> :
(!fileInfo.isReadyToPlay ?
<span>this is the world's worst loading screen and we shipped our software with it anyway... <br /><br />{loadStatusMessage}</span> :
<VideoPlayer downloadPath={fileInfo.download_path} />) :
<div className="video__cover" style={{backgroundImage: 'url("' + metadata.thumbnail + '")'}}>
<WatchLink icon="icon-play" onWatchClick={this.onWatchClick.bind(this)}
startPlaying={this.startPlaying.bind(this)} {...this.props}></WatchLink>
<VideoPlayButton onWatchClick={this.onWatchClick.bind(this)}
startPlaying={this.startPlaying.bind(this)} {...this.props} />
</div>
}</div>
);

View file

@ -642,7 +642,6 @@ lbry.claim_list_mine = function(params={}) {
const claimCacheKey = 'resolve_claim_cache';
lbry._claimCache = getSession(claimCacheKey, {});
lbry.resolve = function(params={}) {
console.log('resolve: ' + params.uri);
return new Promise((resolve, reject) => {
if (!params.uri) {
throw "Resolve has hacked cache on top of it that requires a URI"

View file

@ -36,7 +36,9 @@ window.addEventListener('popstate', (event) => {
})
ipcRenderer.on('open-uri-requested', (event, uri) => {
console.log('FIX ME do magic dispatch');
if (uri) {
console.log('FIX ME do magic dispatch: ' + uri);
}
});
const initialState = app.store.getState();

View file

@ -3,25 +3,21 @@ import {
connect
} from 'react-redux'
import {
doFetchChannelClaims
doFetchClaimsByChannel
} from 'actions/content'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentUriClaim,
selectCurrentUriClaims,
makeSelectClaimsForChannel
} from 'selectors/claims'
import ChannelPage from './view'
const select = (state) => ({
uri: selectCurrentUri(state),
claim: selectCurrentUriClaim(state),
claims: selectCurrentUriClaims(state)
})
//
// const select = (state) => ({
// uri: selectCurrentUri(state),
// claim: selectCurrentUriClaim(state),
// claims: selectCurrentUriClaims(state)
// })
const perform = (dispatch) => ({
fetchClaims: (uri) => dispatch(doFetchChannelClaims(uri))
fetchClaims: (uri) => dispatch(doFetchClaimsByChannel(uri))
})
export default connect(select, perform)(ChannelPage)
export default connect(null, perform)(ChannelPage)

View file

@ -3,33 +3,41 @@ import {
connect
} from 'react-redux'
import {
doFetchCurrentUriFileInfo
doFetchFileInfo,
} from 'actions/file_info'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentUriFileInfo,
selectCurrentUriIsDownloaded,
makeSelectFileInfoForUri,
} from 'selectors/file_info'
import {
selectCurrentUriClaim,
makeSelectClaimForUri,
makeSelectContentTypeForUri,
makeSelectMetadataForUri,
} from 'selectors/claims'
import {
selectCurrentUriCostInfo,
makeSelectCostInfoForUri,
} from 'selectors/cost_info'
import FilePage from './view'
const select = (state) => ({
claim: selectCurrentUriClaim(state),
uri: selectCurrentUri(state),
isDownloaded: selectCurrentUriIsDownloaded(state),
fileInfo: selectCurrentUriFileInfo(state),
costInfo: selectCurrentUriCostInfo(state),
})
const makeSelect = () => {
const selectClaim = makeSelectClaimForUri(),
selectContentType = makeSelectContentTypeForUri(),
selectFileInfo = makeSelectFileInfoForUri(),
selectCostInfo = makeSelectCostInfoForUri(),
selectMetadata = makeSelectMetadataForUri()
const select = (state, props) => ({
claim: selectClaim(state, props),
contentType: selectContentType(state, props),
costInfo: selectCostInfo(state, props),
metadata: selectMetadata(state, props),
fileInfo: selectFileInfo(state, props)
})
return select
}
const perform = (dispatch) => ({
fetchFileInfo: () => dispatch(doFetchCurrentUriFileInfo())
fetchFileInfo: (uri) => dispatch(doFetchFileInfo(uri))
})
export default connect(select, perform)(FilePage)
export default connect(makeSelect, perform)(FilePage)

View file

@ -1,12 +1,9 @@
import React from 'react';
import lbry from 'lbry.js';
import lighthouse from 'lighthouse.js';
import lbryuri from 'lbryuri.js';
import Video from 'component/video'
import {
TruncatedText,
Thumbnail,
BusyMessage,
} from 'component/common';
import FilePrice from 'component/filePrice'
import FileActions from 'component/fileActions';
@ -57,64 +54,50 @@ class FilePage extends React.Component{
fetchFileInfo(props) {
if (props.fileInfo === undefined) {
props.fetchFileInfo()
props.fetchFileInfo(props.uri)
}
}
render() {
const {
claim,
navigate,
claim: {
txid,
nout,
has_signature: hasSignature,
signature_is_valid: signatureIsValid,
value,
value: {
stream,
stream: {
metadata,
source,
metadata: {
title,
} = {},
source: {
contentType,
} = {},
} = {},
} = {},
},
metadata,
contentType,
uri,
isDownloaded,
fileInfo,
costInfo,
costInfo: {
cost,
includesData: costIncludesData,
} = {},
} = this.props
const outpoint = txid + ':' + nout;
const uriLookupComplete = !!claim && Object.keys(claim).length
if (!claim || !metadata) {
return <span className="empty">Empty claim or metadata info.</span>
}
const {
txid,
nout,
has_signature: hasSignature,
signature_is_valid: signatureIsValid,
value
} = claim
const outpoint = txid + ':' + nout
const title = metadata.title
const channelUriObj = lbryuri.parse(uri)
delete channelUriObj.path;
delete channelUriObj.contentName;
const channelUri = signatureIsValid && hasSignature && channelUriObj.isChannel ? lbryuri.build(channelUriObj, false) : null;
const channelUri = signatureIsValid && hasSignature && channelUriObj.isChannel ? lbryuri.build(channelUriObj, false) : null
const uriIndicator = <UriIndicator uri={uri} />
return (
<main className="main--single-column">
<section className="show-page-media">
{ contentType && contentType.startsWith('video/') ?
<Video className="video-embedded" uri={uri} metadata={metadata} outpoint={outpoint} /> :
<Video className="video-embedded" uri={uri} /> :
(metadata && metadata.thumbnail ? <Thumbnail src={metadata.thumbnail} /> : <Thumbnail />) }
</section>
<section className="card">
<div className="card__inner">
<div className="card__title-identity">
{isDownloaded === false
{!fileInfo || fileInfo.written_bytes <= 0
? <span style={{float: "right"}}><FilePrice uri={lbryuri.normalize(uri)} /></span>
: null}<h1>{title}</h1>
<div className="card__subtitle">
@ -123,7 +106,8 @@ class FilePage extends React.Component{
uriIndicator}
</div>
<div className="card__actions">
<FileActions uri={uri} /></div>
<FileActions uri={uri} />
</div>
</div>
<div className="card__content card__subtext card__subtext card__subtext--allow-newlines">
{metadata && metadata.description}
@ -131,8 +115,7 @@ class FilePage extends React.Component{
</div>
{ metadata ?
<div className="card__content">
<FormatItem metadata={metadata} contentType={contentType} cost={cost} uri={uri} outpoint={outpoint}
costIncludesData={costIncludesData} />
<FormatItem metadata={metadata} contentType={contentType} />
</div> : '' }
<div className="card__content">
<Link href="https://lbry.io/dmca" label="report" className="button-text-help" />

View file

@ -6,26 +6,27 @@ import {
doResolveUri,
} from 'actions/content'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentUriClaim,
selectCurrentUriChannelClaim,
makeSelectClaimForUri,
} from 'selectors/claims'
import {
selectCurrentUriIsResolving,
makeSelectIsResolvingForUri,
} from 'selectors/content'
import ShowPage from './view'
const select = (state, props) => ({
channelClaim: selectCurrentUriChannelClaim(state),
claim: selectCurrentUriClaim(state),
uri: selectCurrentUri(state),
isResolvingUri: selectCurrentUriIsResolving(state)
})
const makeSelect = () => {
const selectClaim = makeSelectClaimForUri(),
selectIsResolving = makeSelectIsResolvingForUri();
const select = (state, props) => ({
claim: selectClaim(state, props),
isResolvingUri: selectIsResolving(state, props)
})
return select
}
const perform = (dispatch) => ({
resolveUri: (uri) => dispatch(doResolveUri(uri))
})
export default connect(select, perform)(ShowPage)
export default connect(makeSelect, perform)(ShowPage)

View file

@ -28,7 +28,6 @@ class ShowPage extends React.Component{
render() {
const {
channelClaim,
claim,
uri,
isResolvingUri,
@ -36,7 +35,7 @@ class ShowPage extends React.Component{
let innerContent = "";
if (isResolvingUri || claim === null) {
if (isResolvingUri || !claim) {
innerContent = <section className="card">
<div className="card__inner">
<div className="card__title-identity"><h1>{uri}</h1></div>
@ -47,11 +46,12 @@ class ShowPage extends React.Component{
</div>
</section>
}
else if (channelClaim && claim && channelClaim.txid && channelClaim.txid === claim.txid) {
innerContent = <ChannelPage claim={claim} />
else if (claim.name.length && claim.name[0] === '@') {
innerContent = "channel"
// innerContent = <ChannelPage claim={claim} />
}
else if (claim) {
innerContent = <FilePage />
innerContent = <FilePage uri={uri} />
}
return (
@ -60,4 +60,4 @@ class ShowPage extends React.Component{
}
}
export default ShowPage
export default ShowPage

View file

@ -9,7 +9,6 @@ const defaultState = {
upgradeSkipped: sessionStorage.getItem('upgradeSkipped'),
daemonReady: false,
obscureNsfw: !lbry.getClientSetting('showNsfw'),
hidePrice: false,
hasSignature: false,
}

View file

@ -9,10 +9,8 @@ reducers[types.FETCH_AVAILABILITY_STARTED] = function(state, action) {
uri,
} = action.data
const newFetching = Object.assign({}, state.fetching)
const newByUri = Object.assign({}, newFetching.byUri)
newByUri[uri] = true
newFetching.byUri = newByUri
newFetching[uri] = true
return Object.assign({}, state, {
fetching: newFetching,
@ -24,12 +22,11 @@ reducers[types.FETCH_AVAILABILITY_COMPLETED] = function(state, action) {
uri,
availability,
} = action.data
const newFetching = Object.assign({}, state.fetching)
const newFetchingByUri = Object.assign({}, newFetching.byUri)
const newAvailabilityByUri = Object.assign({}, state.byUri)
delete newFetchingByUri[uri]
newFetching.byUri = newFetchingByUri
delete newFetching[uri]
newAvailabilityByUri[uri] = availability
return Object.assign({}, state, {

View file

@ -13,23 +13,22 @@ reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
} = action.data
const newClaims = Object.assign({}, state.claimsByUri)
const newChannelClaims = Object.assign({}, state.channelClaimsByUri)
if (claim !== undefined) {
newClaims[uri] = claim
}
//This needs a sanity boost...
if (certificate !== undefined) {
newChannelClaims[uri] = certificate
if (certificate !== undefined && claim === undefined) {
const uriParts = lbryuri.parse(uri);
// newChannelClaims[uri] = certificate
if (claim === undefined) {
newClaims[uri] = certificate
}
}
return Object.assign({}, state, {
claimsByUri: newClaims,
channelClaimsByUri: newChannelClaims
claimsByUri: newClaims
})
}

View file

@ -23,10 +23,17 @@ reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) {
uri,
fileInfo,
} = action.data
const newByUri = Object.assign({}, state.byUri)
const newFetching = Object.assign({}, state.fetching)
newByUri[uri] = fileInfo || {}
if (fileInfo) {
fileInfo.isReadyToPlay = fileInfo.written_bytes > 0
fileInfo.isDownloaded = fileInfo.completed && fileInfo.written_bytes > 0;
}
newByUri[uri] = fileInfo || null
delete newFetching[uri]
return Object.assign({}, state, {

View file

@ -31,22 +31,10 @@ export const selectCurrentParams = createSelector(
}
)
export const selectCurrentUri = createSelector(
selectCurrentPath,
(path) => {
if (path.match(/=/)) {
return path.split('=')[1]
}
else {
return undefined
}
}
)
export const selectPageTitle = createSelector(
selectCurrentPage,
selectCurrentUri,
(page, uri) => {
selectCurrentParams,
(page, params) => {
switch (page) {
case 'search':
return 'Search'
@ -62,7 +50,7 @@ export const selectPageTitle = createSelector(
case 'rewards':
return page.charAt(0).toUpperCase() + page.slice(1)
case 'show':
return lbryuri.normalize(uri)
return lbryuri.normalize(params.uri)
case 'downloaded':
return 'Downloads & Purchases'
case 'published':
@ -190,11 +178,6 @@ export const selectUpgradeDownloadItem = createSelector(
(state) => state.downloadItem
)
export const selectSearchTerm = createSelector(
_selectState,
(state) => state.searchTerm
)
export const selectError = createSelector(
_selectState,
(state) => state.error
@ -210,11 +193,6 @@ export const selectObscureNsfw = createSelector(
(state) => !!state.obscureNsfw
)
export const selectHidePrice = createSelector(
_selectState,
(state) => !!state.hidePrice
)
export const selectHasSignature = createSelector(
_selectState,
(state) => !!state.hasSignature

View file

@ -4,7 +4,6 @@ import {
import {
selectDaemonReady,
selectCurrentPage,
selectCurrentUri,
} from 'selectors/app'
const _selectState = state => state.availability
@ -14,29 +13,24 @@ export const selectAvailabilityByUri = createSelector(
(state) => state.byUri || {}
)
const selectAvailabilityForUri = (state, props) => {
return selectAvailabilityByUri(state)[props.uri]
}
export const makeSelectIsAvailableForUri = () => {
return createSelector(
selectAvailabilityForUri,
(availability) => availability === undefined ? undefined : availability > 0
)
}
export const selectFetchingAvailability = createSelector(
_selectState,
(state) => state.fetching || {}
)
export const selectFetchingAvailabilityByUri = createSelector(
selectFetchingAvailability,
(fetching) => fetching.byUri || {}
)
const selectAvailabilityForUri = (state, props) => {
return selectAvailabilityByUri(state)[props.uri]
}
export const makeSelectAvailabilityForUri = () => {
return createSelector(
selectAvailabilityForUri,
(availability) => availability
)
}
const selectFetchingAvailabilityForUri = (state, props) => {
return selectFetchingAvailabilityByUri(state)[props.uri]
return selectFetchingAvailability(state)[props.uri]
}
export const makeSelectFetchingAvailabilityForUri = () => {
@ -44,16 +38,4 @@ export const makeSelectFetchingAvailabilityForUri = () => {
selectFetchingAvailabilityForUri,
(fetching) => fetching
)
}
export const selectFetchingAvailabilityForCurrentUri = createSelector(
selectCurrentUri,
selectFetchingAvailabilityByUri,
(uri, byUri) => byUri[uri]
)
export const selectAvailabilityForCurrentUri = createSelector(
selectCurrentUri,
selectAvailabilityByUri,
(uri, byUri) => byUri[uri]
)
}

View file

@ -2,9 +2,6 @@ import {
createSelector,
} from 'reselect'
import lbryuri from 'lbryuri'
import {
selectCurrentUri,
} from 'selectors/app'
export const _selectState = state => state.claims || {}
@ -13,40 +10,21 @@ export const selectClaimsByUri = createSelector(
(state) => state.claimsByUri || {}
)
export const selectCurrentUriClaim = createSelector(
selectCurrentUri,
selectClaimsByUri,
(uri, byUri) => byUri[uri]
)
export const selectChannelClaimsByUri = createSelector(
_selectState,
(state) => state.channelClaimsByUri || {}
)
export const selectCurrentUriChannelClaim = createSelector(
selectCurrentUri,
selectChannelClaimsByUri,
(uri, byUri) => byUri[uri]
)
export const selectCurrentUriClaimOutpoint = createSelector(
selectCurrentUriClaim,
(claim) => {
return claim ? `${claim.txid}:${claim.nout}` : null
}
)
export const selectClaimsByChannel = createSelector(
export const selectAllClaimsByChannel = createSelector(
_selectState,
(state) => state.claimsByChannel || {}
)
export const selectCurrentUriClaims = createSelector(
selectCurrentUri,
selectClaimsByChannel,
(uri, byChannel) => byChannel[uri]
)
export const selectClaimsForChannel = (state, props) => {
return selectAllClaimsByChannel(state)[props.uri]
}
export const makeSelectClaimsForChannel = () => {
return createSelector(
selectClaimsForChannel,
(claim) => claim
)
}
const selectClaimForUri = (state, props) => {
const uri = lbryuri.normalize(props.uri)
@ -64,7 +42,7 @@ const selectMetadataForUri = (state, props) => {
const claim = selectClaimForUri(state, props)
const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata
return metadata ? metadata : undefined
return metadata ? metadata : (claim === undefined ? undefined : null)
}
export const makeSelectMetadataForUri = () => {
@ -78,7 +56,7 @@ const selectSourceForUri = (state, props) => {
const claim = selectClaimForUri(state, props)
const source = claim && claim.value && claim.value.stream && claim.value.stream.source
return source ? source : undefined
return source ? source : (claim === undefined ? undefined : null)
}
export const makeSelectSourceForUri = () => {
@ -88,6 +66,13 @@ export const makeSelectSourceForUri = () => {
)
}
export const makeSelectContentTypeForUri = () => {
return createSelector(
selectSourceForUri,
(source) => source ? source.contentType : source
)
}
export const selectMyClaims = createSelector(
_selectState,
(state) => state.mine || {}

View file

@ -2,7 +2,6 @@ import { createSelector } from 'reselect'
import {
selectDaemonReady,
selectCurrentPage,
selectCurrentUri,
} from 'selectors/app'
export const _selectState = state => state.content || {}
@ -17,10 +16,6 @@ export const selectFetchingFeaturedUris = createSelector(
(state) => !!state.fetchingFeaturedContent
)
export const selectFetchingFileInfos = createSelector(
_selectState,
(state) => state.fetchingFileInfos || {}
)
export const selectFetchingDownloadedContent = createSelector(
_selectState,
@ -47,24 +42,16 @@ export const selectPublishedContent = createSelector(
(state) => state.publishedContent || {}
)
export const selectResolvingUris = createSelector(
const selectResolvingUris = createSelector(
_selectState,
(state) => state.resolvingUris || []
)
export const selectCurrentUriIsResolving = createSelector(
selectCurrentUri,
selectResolvingUris,
(uri, resolvingUris) => resolvingUris.indexOf(uri) != -1
)
const selectResolvingUri = (state, props) => {
return selectResolvingUris(state).indexOf(props.uri) != -1
}
export const makeSelectResolvingUri = () => {
export const makeSelectIsResolvingForUri = () => {
return createSelector(
selectResolvingUri,
(resolving) => resolving

View file

@ -1,8 +1,4 @@
import { createSelector } from 'reselect'
import {
selectCurrentUri,
selectCurrentPage,
} from 'selectors/app'
export const _selectState = state => state.costInfo || {}
@ -11,24 +7,7 @@ export const selectAllCostInfoByUri = createSelector(
(state) => state.byUri || {}
)
export const selectCurrentUriCostInfo = createSelector(
selectCurrentUri,
selectAllCostInfoByUri,
(uri, byUri) => byUri[uri]
)
export const selectFetchingCostInfo = createSelector(
_selectState,
(state) => state.fetching || {}
)
export const selectFetchingCurrentUriCostInfo = createSelector(
selectCurrentUri,
selectFetchingCostInfo,
(uri, byUri) => !!byUri[uri]
)
const selectCostInfoForUri = (state, props) => {
export const selectCostInfoForUri = (state, props) => {
return selectAllCostInfoByUri(state)[props.uri]
}

View file

@ -1,10 +1,6 @@
import {
createSelector,
} from 'reselect'
import {
selectCurrentUri,
selectCurrentPage,
} from 'selectors/app'
import {
selectMyClaimsOutpoints,
} from 'selectors/claims'
@ -16,28 +12,6 @@ export const selectAllFileInfoByUri = createSelector(
(state) => state.byUri || {}
)
export const selectCurrentUriRawFileInfo = createSelector(
selectCurrentUri,
selectAllFileInfoByUri,
(uri, byUri) => byUri[uri]
)
export const selectCurrentUriFileInfo = createSelector(
selectCurrentUriRawFileInfo,
(fileInfo) => fileInfo
)
export const selectFetchingFileInfo = createSelector(
_selectState,
(state) => state.fetching || {}
)
export const selectFetchingCurrentUriFileInfo = createSelector(
selectCurrentUri,
selectFetchingFileInfo,
(uri, byUri) => !!byUri[uri]
)
export const selectDownloading = createSelector(
_selectState,
(state) => state.downloading || {}
@ -48,24 +22,7 @@ export const selectDownloadingByUri = createSelector(
(downloading) => downloading.byUri || {}
)
export const selectDownloadingCurrentUri = createSelector(
selectCurrentUri,
selectDownloadingByUri,
(uri, byUri) => !!byUri[uri]
)
export const selectCurrentUriIsDownloaded = createSelector(
selectCurrentUriFileInfo,
(fileInfo) => {
if (!fileInfo) return false
if (!fileInfo.completed) return false
if (!fileInfo.written_bytes > 0) return false
return true
}
)
const selectFileInfoForUri = (state, props) => {
export const selectFileInfoForUri = (state, props) => {
return selectAllFileInfoByUri(state)[props.uri]
}
@ -98,19 +55,6 @@ export const selectLoadingByUri = createSelector(
(loading) => loading.byUri || {}
)
export const selectLoadingCurrentUri = createSelector(
selectLoadingByUri,
selectCurrentUri,
(byUri, uri) => !!byUri[uri]
)
// TODO make this smarter so it doesn't start playing and immediately freeze
// while downloading more.
export const selectCurrentUriFileReadyToPlay = createSelector(
selectCurrentUriFileInfo,
(fileInfo) => (fileInfo || {}).written_bytes > 0
)
const selectLoadingForUri = (state, props) => {
const byUri = selectLoadingByUri(state)
return byUri[props.uri]

View file

@ -2,7 +2,6 @@ import { createSelector } from 'reselect'
import {
selectPageTitle,
selectCurrentPage,
selectCurrentUri
} from 'selectors/app'
export const _selectState = state => state.search || {}
@ -43,8 +42,7 @@ export const selectWunderBarAddress = createSelector(
export const selectWunderBarIcon = createSelector(
selectCurrentPage,
selectCurrentUri,
(page, uri) => {
(page) => {
switch (page) {
case 'search':
return 'icon-search'