diff --git a/js/lbry.js b/js/lbry.js index 4be044fb0..9c013c0fa 100644 --- a/js/lbry.js +++ b/js/lbry.js @@ -1,3 +1,5 @@ +import lighthouse from './lighthouse.js'; + var lbry = { isConnected: false, rootPath: '.', @@ -179,14 +181,59 @@ lbry.getMyClaim = function(name, callback) { lbry.call('get_my_claim', { name: name }, callback); } -lbry.getCostEstimate = function(name, callback) { +lbry.getKeyFee = function(name, callback) { lbry.call('get_est_cost', { name: name }, callback); } +lbry.getTotalCost = function(name, size, callback) { + lbry.call('get_est_cost', { + name: name, + size: size, + }, callback); +} + lbry.getPeersForBlobHash = function(blobHash, callback) { lbry.call('get_peers_for_hash', { blob_hash: blobHash }, callback) } +lbry.getCostInfoForName = function(name, callback) { + /** + * Takes a LBRY name; will first try and calculate a total cost using + * Lighthouse. If Lighthouse can't be reached, it just retrives the + * key fee. + * + * Returns an object with members: + * - cost: Number; the calculated cost of the name + * - includes_data: Boolean; indicates whether or not the data fee info + * from Lighthouse is included. + */ + function getCostWithData(size, callback) { + lbry.getTotalCost(name, size, (cost) => { + callback({ + cost: cost, + includesData: true, + }); + }); + } + + function getCostNoData(name, callback) { + lbry.getKeyFee(name, (cost) => { + callback({ + cost: cost, + includesData: false, + }); + }); + } + + lighthouse.getSizeForName(name, (size) => { + getCostWithData(name, size, callback); + }, () => { + getCostNoData(name, callback); + }, () => { + getCostNoData(name, callback); + }); +} + lbry.getFileStatus = function(name, callback) { lbry.call('get_lbry_file', { 'name': name }, callback); } diff --git a/js/lighthouse.js b/js/lighthouse.js index 73315cabb..0c5d6934a 100644 --- a/js/lighthouse.js +++ b/js/lighthouse.js @@ -15,23 +15,31 @@ var lighthouse = { lbry.jsonrpc_call(this.server + this.path, method, params, callback, errorCallback, connectFailedCallback, timeout); }, - search: function(query, callback) { + search: function(query, callback, errorCallback, connectFailedCallback, timeout) { let handleSearchFailed = function(tryNum=0) { if (tryNum > lighthouse._max_search_tries) { - throw new Error(`Could not connect to Lighthouse server. Last server attempted: ${lighthouse.server}`); + if (connectFailedCallback) { + connectFailedCallback(); + } else { + throw new Error(`Could not connect to Lighthouse server. Last server attempted: ${lighthouse.server}`); + } } else { // Randomly choose one of the other search servers to switch to let otherServers = lighthouse.servers.slice(); otherServers.splice(otherServers.indexOf(lighthouse.server), 1); lighthouse.server = otherServers[Math.round(Math.random() * (otherServers.length - 1))]; - lighthouse.call('search', [query], callback, undefined, function() { + lighthouse.call('search', [query], callback, errorCallback, function() { handleSearchFailed(tryNum + 1); }, lighthouse._search_timeout); } } - lighthouse.call('search', [query], callback, undefined, function() { handleSearchFailed() }, lighthouse._search_timeout); + lighthouse.call('search', [query], callback, errorCallback, function() { handleSearchFailed() }, lighthouse._search_timeout); + }, + + getSizeForName: function(name, callback, errorCallback, connectFailedCallback, timeout) { + return lighthouse.call('get_size_for_name', [name], callback, errorCallback, connectFailedCallback, timeout); } }; diff --git a/js/page/discover.js b/js/page/discover.js index f533a3afb..77633ca84 100644 --- a/js/page/discover.js +++ b/js/page/discover.js @@ -46,8 +46,7 @@ var SearchResults = React.createClass({ var mediaType = lbry.getMediaType(result.value.content_type); rows.push( + description={result.value.description} nsfw={result.value.nsfw} mediaType={mediaType} /> ); }); return ( @@ -93,6 +92,8 @@ var SearchResultRow = React.createClass({ return { downloading: false, isHovered: false, + cost: null, + costIncludesData: null, } }, handleMouseOver: function() { @@ -105,6 +106,21 @@ var SearchResultRow = React.createClass({ isHovered: false, }); }, + componentWillMount: function() { + if ('cost' in this.props) { + this.setState({ + cost: this.props.cost, + costIncludesData: this.props.costIncludesData, + }); + } else { + lbry.getCostInfoForName(this.props.name, ({cost, includesData}) => { + this.setState({ + cost: cost, + costIncludesData: includesData, + }); + }); + } + }, render: function() { var obscureNsfw = !lbry.getClientSetting('showNsfw') && this.props.nsfw; if (!this.props.compact) { @@ -122,9 +138,11 @@ var SearchResultRow = React.createClass({
- - - + {this.state.cost !== null + ? + + + : null}
lbry://{this.props.name}

@@ -173,7 +191,7 @@ var FeaturedContentItem = React.createClass({ return { metadata: null, title: null, - amount: 0.0, + cost: null, overlayShowing: false, }; }, @@ -183,21 +201,18 @@ var FeaturedContentItem = React.createClass({ }, componentDidMount: function() { - this.resolveSearch = true; + this._isMounted = true; - lighthouse.search(this.props.name, function(results) { - var result = results[0]; - var metadata = result.value; - if (this.resolveSearch) - { - this.setState({ - metadata: metadata, - amount: result.cost, - available: result.available, - title: metadata && metadata.title ? metadata.title : ('lbry://' + this.props.name), - }); + lbry.resolveName(this.props.name, (metadata) => { + if (!this._isMounted) { + return; } - }.bind(this)); + + this.setState({ + metadata: metadata, + title: metadata && metadata.title ? metadata.title : ('lbry://' + this.props.name), + }); + }); }, render: function() { @@ -209,7 +224,7 @@ var FeaturedContentItem = React.createClass({ return (
+ nsfw={this.state.metadata.nsfw} compact />
); } }); diff --git a/js/page/show.js b/js/page/show.js index c7458a792..7486b0c93 100644 --- a/js/page/show.js +++ b/js/page/show.js @@ -16,9 +16,9 @@ var formatItemImgStyle = { var FormatItem = React.createClass({ propTypes: { claimInfo: React.PropTypes.object, - amount: React.PropTypes.number, + cost: React.PropTypes.number, name: React.PropTypes.string, - available: React.PropTypes.bool, + costIncludesData: React.PropTypes.bool, }, render: function() { @@ -31,8 +31,8 @@ var FormatItem = React.createClass({ var license = claimInfo.license; var fileContentType = (claimInfo.content_type || claimInfo['content-type']); var mediaType = lbry.getMediaType(fileContentType); - var available = this.props.available; - var amount = this.props.amount || 0.0; + var costIncludesData = this.props.costIncludesData; + var cost = this.props.cost || 0.0; return (
@@ -48,7 +48,7 @@ var FormatItem = React.createClass({ Content-Type{fileContentType} - Cost + Cost Author{author} @@ -78,9 +78,9 @@ var FormatItem = React.createClass({ var FormatsSection = React.createClass({ propTypes: { claimInfo: React.PropTypes.object, - amount: React.PropTypes.number, + cost: React.PropTypes.number, name: React.PropTypes.string, - available: React.PropTypes.bool, + costIncludesData: React.PropTypes.bool, }, render: function() { var name = this.props.name; @@ -102,7 +102,7 @@ var FormatsSection = React.createClass({ {/* In future, anticipate multiple formats, just a guess at what it could look like // var formats = this.props.claimInfo.formats // return ({formats.map(function(format,i){ */} - + {/* })}); */}
); } @@ -114,50 +114,44 @@ var DetailPage = React.createClass({ }, getInitialState: function() { return { - claimInfo: null, - amount: null, - searching: true, - matchFound: null, + metadata: null, + cost: null, + costIncludesData: null, + nameLookupComplete: null, }; }, componentWillMount: function() { document.title = 'lbry://' + this.props.name; - lighthouse.search(this.props.name, (results) => { - var result = results[0]; + lbry.resolveName(this.props.name, (metadata) => { + this.setState({ + metadata: metadata, + nameLookupComplete: true, + }); + }); - if (result.name != this.props.name) { - this.setState({ - searching: false, - matchFound: false, - }); - } else { - this.setState({ - amount: result.cost, - available: result.available, - claimInfo: result.value, - searching: false, - matchFound: true, - }); - } + lbry.getCostInfoForName(this.props.name, ({cost, includesData}) => { + this.setState({ + cost: cost, + costIncludesData: includesData, + }); }); }, render: function() { - if (this.state.claimInfo == null && this.state.searching) { - // Still waiting for metadata + if (this.state.metadata == null) { return null; } - var name = this.props.name; - var available = this.state.available; - var claimInfo = this.state.claimInfo; - var amount = this.state.amount; + const name = this.props.name; + const costIncludesData = this.state.costIncludesData; + const metadata = this.state.metadata; + const cost = this.state.cost; return (
- {this.state.matchFound ? ( - + {this.state.nameLookupComplete ? ( + ) : (

No content