165 lines
4.4 KiB
JavaScript
165 lines
4.4 KiB
JavaScript
import React from 'react';
|
|
import lbry from '../lbry.js';
|
|
import lbryio from '../lbryio.js';
|
|
import lbryuri from '../lbryuri.js';
|
|
import lighthouse from '../lighthouse.js';
|
|
import {FileTile, FileTileStream} from '../component/file-tile.js';
|
|
import {Link} from '../component/link';
|
|
import {ToolTip} from '../component/tooltip.js';
|
|
import {BusyMessage} from '../component/common.js';
|
|
|
|
var SearchNoResults = React.createClass({
|
|
render: function() {
|
|
return <section>
|
|
<span className="empty">
|
|
No one has checked anything in for {this.props.query} yet.
|
|
<Link label="Be the first" href="?publish" />
|
|
</span>
|
|
</section>;
|
|
}
|
|
});
|
|
|
|
var SearchResultList = React.createClass({
|
|
render: function() {
|
|
var rows = [],
|
|
seenNames = {}; //fix this when the search API returns claim IDs
|
|
|
|
for (let {name, claim, claim_id, channel_name, channel_id, txid, nout} of this.props.results) {
|
|
const uri = lbryuri.build({
|
|
channelName: channel_name,
|
|
contentName: name,
|
|
claimId: channel_id || claim_id,
|
|
});
|
|
|
|
rows.push(
|
|
<FileTileStream key={uri} uri={uri} outpoint={txid + ':' + nout} metadata={claim.stream.metadata} contentType={claim.stream.source.contentType} />
|
|
);
|
|
}
|
|
return (
|
|
<div>{rows}</div>
|
|
);
|
|
}
|
|
});
|
|
|
|
let SearchResults = React.createClass({
|
|
propTypes: {
|
|
query: React.PropTypes.string.isRequired
|
|
},
|
|
|
|
_isMounted: false,
|
|
|
|
search: function(term) {
|
|
lighthouse.search(term).then(this.searchCallback);
|
|
if (!this.state.searching) {
|
|
this.setState({ searching: true })
|
|
}
|
|
},
|
|
|
|
componentWillMount: function () {
|
|
this._isMounted = true;
|
|
this.search(this.props.query);
|
|
},
|
|
|
|
componentWillReceiveProps: function (nextProps) {
|
|
if (nextProps.query != this.props.query) {
|
|
this.search(nextProps.query);
|
|
}
|
|
},
|
|
|
|
componentWillUnmount: function () {
|
|
this._isMounted = false;
|
|
},
|
|
|
|
getInitialState: function () {
|
|
return {
|
|
results: [],
|
|
searching: true
|
|
};
|
|
},
|
|
|
|
searchCallback: function (results) {
|
|
if (this._isMounted) //could have canceled while results were pending, in which case nothing to do
|
|
{
|
|
this.setState({
|
|
results: results,
|
|
searching: false //multiple searches can be out, we're only done if we receive one we actually care about
|
|
});
|
|
}
|
|
},
|
|
|
|
render: function () {
|
|
return this.state.searching ?
|
|
<BusyMessage message="Looking up the Dewey Decimals" /> :
|
|
(this.state.results && this.state.results.length ?
|
|
<SearchResultList results={this.state.results} /> :
|
|
<SearchNoResults query={this.props.query} />);
|
|
}
|
|
});
|
|
|
|
let SearchPage = React.createClass({
|
|
|
|
_isMounted: false,
|
|
|
|
propTypes: {
|
|
query: React.PropTypes.string.isRequired
|
|
},
|
|
|
|
isValidUri: function(query) {
|
|
try {
|
|
lbryuri.parse(query);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
componentWillMount: function() {
|
|
this._isMounted = true;
|
|
lighthouse.search(this.props.query).then(this.searchCallback);
|
|
},
|
|
|
|
componentWillUnmount: function() {
|
|
this._isMounted = false;
|
|
},
|
|
|
|
getInitialState: function() {
|
|
return {
|
|
results: [],
|
|
searching: true
|
|
};
|
|
},
|
|
|
|
searchCallback: function(results) {
|
|
if (this._isMounted) //could have canceled while results were pending, in which case nothing to do
|
|
{
|
|
this.setState({
|
|
results: results,
|
|
searching: false //multiple searches can be out, we're only done if we receive one we actually care about
|
|
});
|
|
}
|
|
},
|
|
|
|
render: function() {
|
|
return (
|
|
<main className="main--single-column">
|
|
{ this.isValidUri(this.props.query) ?
|
|
<section className="section-spaced">
|
|
<h3 className="card-row__header">
|
|
Exact URL
|
|
<ToolTip label="?" body="This is the resolution of a LBRY URL and not controlled by LBRY Inc." className="tooltip--header"/>
|
|
</h3>
|
|
<FileTile uri={this.props.query} showEmpty={true} />
|
|
</section> : '' }
|
|
<section className="section-spaced">
|
|
<h3 className="card-row__header">
|
|
Search Results for {this.props.query}
|
|
<ToolTip label="?" body="These search results are provided by LBRY Inc." className="tooltip--header"/>
|
|
</h3>
|
|
<SearchResults query={this.props.query} />
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|
|
});
|
|
|
|
export default SearchPage;
|