mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-08-29 16:31:33 +00:00
Merge pull request #106 from lbryio/new-lighthouse
Update Discover and Show pages to use new Lighthouse cost reporting
This commit is contained in:
commit
5dbadeb941
4 changed files with 125 additions and 61 deletions
49
js/lbry.js
49
js/lbry.js
|
@ -1,3 +1,5 @@
|
||||||
|
import lighthouse from './lighthouse.js';
|
||||||
|
|
||||||
var lbry = {
|
var lbry = {
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
rootPath: '.',
|
rootPath: '.',
|
||||||
|
@ -179,14 +181,59 @@ lbry.getMyClaim = function(name, callback) {
|
||||||
lbry.call('get_my_claim', { name: 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.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.getPeersForBlobHash = function(blobHash, callback) {
|
||||||
lbry.call('get_peers_for_hash', { blob_hash: 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.getFileStatus = function(name, callback) {
|
||||||
lbry.call('get_lbry_file', { 'name': name }, callback);
|
lbry.call('get_lbry_file', { 'name': name }, callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,23 +15,31 @@ var lighthouse = {
|
||||||
lbry.jsonrpc_call(this.server + this.path, method, params, callback, errorCallback, connectFailedCallback, timeout);
|
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) {
|
let handleSearchFailed = function(tryNum=0) {
|
||||||
if (tryNum > lighthouse._max_search_tries) {
|
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 {
|
} else {
|
||||||
// Randomly choose one of the other search servers to switch to
|
// Randomly choose one of the other search servers to switch to
|
||||||
let otherServers = lighthouse.servers.slice();
|
let otherServers = lighthouse.servers.slice();
|
||||||
otherServers.splice(otherServers.indexOf(lighthouse.server), 1);
|
otherServers.splice(otherServers.indexOf(lighthouse.server), 1);
|
||||||
lighthouse.server = otherServers[Math.round(Math.random() * (otherServers.length - 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);
|
handleSearchFailed(tryNum + 1);
|
||||||
}, lighthouse._search_timeout);
|
}, 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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,7 @@ var SearchResults = React.createClass({
|
||||||
var mediaType = lbry.getMediaType(result.value.content_type);
|
var mediaType = lbry.getMediaType(result.value.content_type);
|
||||||
rows.push(
|
rows.push(
|
||||||
<SearchResultRow key={result.name} name={result.name} title={result.value.title} imgUrl={result.value.thumbnail}
|
<SearchResultRow key={result.name} name={result.name} title={result.value.title} imgUrl={result.value.thumbnail}
|
||||||
description={result.value.description} cost={result.cost} nsfw={result.value.nsfw}
|
description={result.value.description} nsfw={result.value.nsfw} mediaType={mediaType} />
|
||||||
mediaType={mediaType} />
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
@ -93,6 +92,8 @@ var SearchResultRow = React.createClass({
|
||||||
return {
|
return {
|
||||||
downloading: false,
|
downloading: false,
|
||||||
isHovered: false,
|
isHovered: false,
|
||||||
|
cost: null,
|
||||||
|
costIncludesData: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleMouseOver: function() {
|
handleMouseOver: function() {
|
||||||
|
@ -105,6 +106,21 @@ var SearchResultRow = React.createClass({
|
||||||
isHovered: false,
|
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() {
|
render: function() {
|
||||||
var obscureNsfw = !lbry.getClientSetting('showNsfw') && this.props.nsfw;
|
var obscureNsfw = !lbry.getClientSetting('showNsfw') && this.props.nsfw;
|
||||||
if (!this.props.compact) {
|
if (!this.props.compact) {
|
||||||
|
@ -122,9 +138,11 @@ var SearchResultRow = React.createClass({
|
||||||
<a href={'/?show=' + this.props.name}><Thumbnail src={this.props.imgUrl} alt={'Photo for ' + (this.props.title || this.props.name)} style={searchRowImgStyle} /></a>
|
<a href={'/?show=' + this.props.name}><Thumbnail src={this.props.imgUrl} alt={'Photo for ' + (this.props.title || this.props.name)} style={searchRowImgStyle} /></a>
|
||||||
</div>
|
</div>
|
||||||
<div className="span9">
|
<div className="span9">
|
||||||
<span style={searchRowCostStyle}>
|
{this.state.cost !== null
|
||||||
<CreditAmount amount={this.props.cost} isEstimate={!this.props.available}/>
|
? <span style={searchRowCostStyle}>
|
||||||
</span>
|
<CreditAmount amount={this.state.cost} isEstimate={!this.state.costIncludesData}/>
|
||||||
|
</span>
|
||||||
|
: null}
|
||||||
<div className="meta"><a href={'/?show=' + this.props.name}>lbry://{this.props.name}</a></div>
|
<div className="meta"><a href={'/?show=' + this.props.name}>lbry://{this.props.name}</a></div>
|
||||||
<h3 style={titleStyle}>
|
<h3 style={titleStyle}>
|
||||||
<a href={'/?show=' + this.props.name}>
|
<a href={'/?show=' + this.props.name}>
|
||||||
|
@ -173,7 +191,7 @@ var FeaturedContentItem = React.createClass({
|
||||||
return {
|
return {
|
||||||
metadata: null,
|
metadata: null,
|
||||||
title: null,
|
title: null,
|
||||||
amount: 0.0,
|
cost: null,
|
||||||
overlayShowing: false,
|
overlayShowing: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -183,21 +201,18 @@ var FeaturedContentItem = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this.resolveSearch = true;
|
this._isMounted = true;
|
||||||
|
|
||||||
lighthouse.search(this.props.name, function(results) {
|
lbry.resolveName(this.props.name, (metadata) => {
|
||||||
var result = results[0];
|
if (!this._isMounted) {
|
||||||
var metadata = result.value;
|
return;
|
||||||
if (this.resolveSearch)
|
|
||||||
{
|
|
||||||
this.setState({
|
|
||||||
metadata: metadata,
|
|
||||||
amount: result.cost,
|
|
||||||
available: result.available,
|
|
||||||
title: metadata && metadata.title ? metadata.title : ('lbry://' + this.props.name),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
|
||||||
|
this.setState({
|
||||||
|
metadata: metadata,
|
||||||
|
title: metadata && metadata.title ? metadata.title : ('lbry://' + this.props.name),
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -209,7 +224,7 @@ var FeaturedContentItem = React.createClass({
|
||||||
return (<div style={featuredContentItemContainerStyle}>
|
return (<div style={featuredContentItemContainerStyle}>
|
||||||
<SearchResultRow name={this.props.name} title={this.state.title} imgUrl={this.state.metadata.thumbnail}
|
<SearchResultRow name={this.props.name} title={this.state.title} imgUrl={this.state.metadata.thumbnail}
|
||||||
description={this.state.metadata.description} mediaType={lbry.getMediaType(this.state.metadata.content_type)}
|
description={this.state.metadata.description} mediaType={lbry.getMediaType(this.state.metadata.content_type)}
|
||||||
cost={this.state.amount} nsfw={this.state.metadata.nsfw} available={this.state.available} compact />
|
nsfw={this.state.metadata.nsfw} compact />
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,9 @@ var formatItemImgStyle = {
|
||||||
var FormatItem = React.createClass({
|
var FormatItem = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
claimInfo: React.PropTypes.object,
|
claimInfo: React.PropTypes.object,
|
||||||
amount: React.PropTypes.number,
|
cost: React.PropTypes.number,
|
||||||
name: React.PropTypes.string,
|
name: React.PropTypes.string,
|
||||||
available: React.PropTypes.bool,
|
costIncludesData: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ var FormatItem = React.createClass({
|
||||||
var license = claimInfo.license;
|
var license = claimInfo.license;
|
||||||
var fileContentType = (claimInfo.content_type || claimInfo['content-type']);
|
var fileContentType = (claimInfo.content_type || claimInfo['content-type']);
|
||||||
var mediaType = lbry.getMediaType(fileContentType);
|
var mediaType = lbry.getMediaType(fileContentType);
|
||||||
var available = this.props.available;
|
var costIncludesData = this.props.costIncludesData;
|
||||||
var amount = this.props.amount || 0.0;
|
var cost = this.props.cost || 0.0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row-fluid">
|
<div className="row-fluid">
|
||||||
|
@ -48,7 +48,7 @@ var FormatItem = React.createClass({
|
||||||
<td>Content-Type</td><td>{fileContentType}</td>
|
<td>Content-Type</td><td>{fileContentType}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Cost</td><td><CreditAmount amount={amount} isEstimate={!available}/></td>
|
<td>Cost</td><td><CreditAmount amount={cost} isEstimate={!costIncludesData}/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Author</td><td>{author}</td>
|
<td>Author</td><td>{author}</td>
|
||||||
|
@ -78,9 +78,9 @@ var FormatItem = React.createClass({
|
||||||
var FormatsSection = React.createClass({
|
var FormatsSection = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
claimInfo: React.PropTypes.object,
|
claimInfo: React.PropTypes.object,
|
||||||
amount: React.PropTypes.number,
|
cost: React.PropTypes.number,
|
||||||
name: React.PropTypes.string,
|
name: React.PropTypes.string,
|
||||||
available: React.PropTypes.bool,
|
costIncludesData: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var name = this.props.name;
|
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
|
{/* In future, anticipate multiple formats, just a guess at what it could look like
|
||||||
// var formats = this.props.claimInfo.formats
|
// var formats = this.props.claimInfo.formats
|
||||||
// return (<tbody>{formats.map(function(format,i){ */}
|
// return (<tbody>{formats.map(function(format,i){ */}
|
||||||
<FormatItem claimInfo={format} amount={this.props.amount} name={this.props.name} available={this.props.available} />
|
<FormatItem claimInfo={format} cost={this.props.cost} name={this.props.name} costIncludesData={this.props.costIncludesData} />
|
||||||
{/* })}</tbody>); */}
|
{/* })}</tbody>); */}
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
@ -114,50 +114,44 @@ var DetailPage = React.createClass({
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
claimInfo: null,
|
metadata: null,
|
||||||
amount: null,
|
cost: null,
|
||||||
searching: true,
|
costIncludesData: null,
|
||||||
matchFound: null,
|
nameLookupComplete: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
document.title = 'lbry://' + this.props.name;
|
document.title = 'lbry://' + this.props.name;
|
||||||
|
|
||||||
lighthouse.search(this.props.name, (results) => {
|
lbry.resolveName(this.props.name, (metadata) => {
|
||||||
var result = results[0];
|
this.setState({
|
||||||
|
metadata: metadata,
|
||||||
|
nameLookupComplete: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (result.name != this.props.name) {
|
lbry.getCostInfoForName(this.props.name, ({cost, includesData}) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
searching: false,
|
cost: cost,
|
||||||
matchFound: false,
|
costIncludesData: includesData,
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
amount: result.cost,
|
|
||||||
available: result.available,
|
|
||||||
claimInfo: result.value,
|
|
||||||
searching: false,
|
|
||||||
matchFound: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.state.claimInfo == null && this.state.searching) {
|
if (this.state.metadata == null) {
|
||||||
// Still waiting for metadata
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = this.props.name;
|
const name = this.props.name;
|
||||||
var available = this.state.available;
|
const costIncludesData = this.state.costIncludesData;
|
||||||
var claimInfo = this.state.claimInfo;
|
const metadata = this.state.metadata;
|
||||||
var amount = this.state.amount;
|
const cost = this.state.cost;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<section className="card">
|
<section className="card">
|
||||||
{this.state.matchFound ? (
|
{this.state.nameLookupComplete ? (
|
||||||
<FormatsSection name={name} claimInfo={claimInfo} amount={amount} available={available} />
|
<FormatsSection name={name} claimInfo={metadata} cost={cost} costIncludesData={costIncludesData} />
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<h2>No content</h2>
|
<h2>No content</h2>
|
||||||
|
|
Loading…
Add table
Reference in a new issue