still not quite releasable, but much progress
This commit is contained in:
parent
da538a7a23
commit
5b11c2575a
5 changed files with 167 additions and 50 deletions
16
ui/js/app.js
16
ui/js/app.js
|
@ -145,12 +145,22 @@ var App = React.createClass({
|
|||
},
|
||||
onSearch: function(term) {
|
||||
this._storeHistoryOfNextRender = true;
|
||||
const isShow = term.startsWith('lbry://');
|
||||
this.setState({
|
||||
viewingPage: "search",
|
||||
appUrl: "?search=" + encodeURIComponent(term),
|
||||
viewingPage: isShow ? "show" : "search",
|
||||
appUrl: (isShow ? "?show=" : "?search=") + encodeURIComponent(term),
|
||||
pageArgs: term
|
||||
});
|
||||
},
|
||||
onSubmit: function(uri) {
|
||||
this._storeHistoryOfNextRender = true;
|
||||
this.setState({
|
||||
address: uri,
|
||||
appUrl: "?show=" + encodeURIComponent(uri),
|
||||
viewingPage: "show",
|
||||
pageArgs: uri
|
||||
})
|
||||
},
|
||||
handleUpgradeClicked: function() {
|
||||
// Make a new directory within temp directory so the filename is guaranteed to be available
|
||||
const dir = fs.mkdtempSync(app.getPath('temp') + require('path').sep);
|
||||
|
@ -265,7 +275,7 @@ var App = React.createClass({
|
|||
this._fullScreenPages.includes(this.state.viewingPage) ?
|
||||
mainContent :
|
||||
<div id="window">
|
||||
<Header onSearch={this.onSearch} address={address} wunderBarIcon={wunderBarIcon} viewingPage={this.state.viewingPage} />
|
||||
<Header onSearch={this.onSearch} onSubmit={this.onSubmit} address={address} wunderBarIcon={wunderBarIcon} viewingPage={this.state.viewingPage} />
|
||||
<div id="main-content">
|
||||
{mainContent}
|
||||
</div>
|
||||
|
|
|
@ -97,9 +97,6 @@ export let FileTileStream = React.createClass({
|
|||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
<FileActions uri={this.props.uri} outpoint={this.props.outpoint} metadata={metadata} contentType={this.props.contentType} />
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p className="file-tile__description">
|
||||
<TruncatedText lines={2}>
|
||||
|
@ -238,13 +235,10 @@ export let FileTile = React.createClass({
|
|||
claimInfo: null
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
|
||||
lbry.resolve({uri: this.props.uri}).then((resolutionInfo) => {
|
||||
resolve: function(uri) {
|
||||
lbry.resolve({uri: uri}).then((resolutionInfo) => {
|
||||
if (this._isMounted && resolutionInfo && resolutionInfo.claim && resolutionInfo.claim.value &&
|
||||
resolutionInfo.claim.value.stream && resolutionInfo.claim.value.stream.metadata) {
|
||||
resolutionInfo.claim.value.stream && resolutionInfo.claim.value.stream.metadata) {
|
||||
// In case of a failed lookup, metadata will be null, in which case the component will never display
|
||||
this.setState({
|
||||
claimInfo: resolutionInfo.claim,
|
||||
|
@ -252,6 +246,16 @@ export let FileTile = React.createClass({
|
|||
}
|
||||
});
|
||||
},
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
if (nextProps.uri != this.props.uri) {
|
||||
this.setState(this.getInitialState());
|
||||
this.resolve(nextProps.uri);
|
||||
}
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
this.resolve(this.props.uri);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
},
|
||||
|
@ -261,6 +265,10 @@ export let FileTile = React.createClass({
|
|||
return <FileCardStream outpoint={null} metadata={{title: this.props.uri, description: "Loading..."}} contentType={null} hidePrice={true}
|
||||
hasSignature={false} signatureIsValid={false} uri={this.props.uri} />
|
||||
}
|
||||
if (this.props.showEmpty)
|
||||
{
|
||||
return <div className="empty">Empty file tile for {this.props.uri}</div>
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import lbryuri from '../lbryuri.js';
|
||||
import {Link} from './link.js';
|
||||
import {Icon, CreditAmount} from './common.js';
|
||||
|
||||
|
@ -6,6 +7,11 @@ var Header = React.createClass({
|
|||
_balanceSubscribeId: null,
|
||||
_isMounted: false,
|
||||
|
||||
propTypes: {
|
||||
onSearch: React.PropTypes.func.isRequired,
|
||||
onSubmit: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
balance: 0
|
||||
|
@ -35,7 +41,7 @@ var Header = React.createClass({
|
|||
</div>
|
||||
<div className="header__item header__item--wunderbar">
|
||||
<WunderBar address={this.props.address} icon={this.props.wunderBarIcon}
|
||||
onSearch={this.props.onSearch} viewingPage={this.props.viewingPage} />
|
||||
onSearch={this.props.onSearch} onSubmit={this.props.onSubmit} viewingPage={this.props.viewingPage} />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link href="?wallet" button="text" icon="icon-bank" label={lbry.formatCredits(this.state.balance, 1)} ></Link>
|
||||
|
@ -57,9 +63,11 @@ let WunderBar = React.createClass({
|
|||
_userTypingTimer: null,
|
||||
_input: null,
|
||||
_stateBeforeSearch: null,
|
||||
_resetOnNextBlur: true,
|
||||
|
||||
propTypes: {
|
||||
onSearch: React.PropTypes.func.isRequired
|
||||
onSearch: React.PropTypes.func.isRequired,
|
||||
onSubmit: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -85,11 +93,12 @@ let WunderBar = React.createClass({
|
|||
let searchTerm = event.target.value;
|
||||
|
||||
this._userTypingTimer = setTimeout(() => {
|
||||
this._resetOnNextBlur = false;
|
||||
this.props.onSearch(searchTerm);
|
||||
}, 800); // 800ms delay, tweak for faster/slower
|
||||
},
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.viewingPage !== this.props.viewingPage) {
|
||||
if (nextProps.viewingPage !== this.props.viewingPage || nextProps.address != this.props.address) {
|
||||
this.setState({ address: nextProps.address, icon: nextProps.icon });
|
||||
}
|
||||
},
|
||||
|
@ -109,8 +118,15 @@ let WunderBar = React.createClass({
|
|||
this.setState(newState);
|
||||
},
|
||||
onBlur: function() {
|
||||
this.setState(Object.assign({}, this._stateBeforeSearch, { isActive: false }));
|
||||
this._input.value = this.state.address;
|
||||
let commonState = {isActive: false};
|
||||
if (this._resetOnNextBlur) {
|
||||
this.setState(Object.assign({}, this._stateBeforeSearch, commonState));
|
||||
this._input.value = this.state.address;
|
||||
} else {
|
||||
this._resetOnNextBlur = true;
|
||||
this._stateBeforeSearch = this.state;
|
||||
this.setState(commonState);
|
||||
}
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
this._input.value = this.state.address;
|
||||
|
@ -119,6 +135,12 @@ let WunderBar = React.createClass({
|
|||
this._focusPending = false;
|
||||
}
|
||||
},
|
||||
onKeyPress: function(event) {
|
||||
if (event.charCode == 13 && this._input.value) {
|
||||
clearTimeout(this._userTypingTimer);
|
||||
this.props.onSubmit(lbryuri.normalize(this._input.value));
|
||||
}
|
||||
},
|
||||
onReceiveRef: function(ref) {
|
||||
this._input = ref;
|
||||
},
|
||||
|
@ -131,6 +153,7 @@ let WunderBar = React.createClass({
|
|||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onChange={this.onChange}
|
||||
onKeyPress={this.onKeyPress}
|
||||
value={this.state.address}
|
||||
placeholder="Find movies, music, games, and more" />
|
||||
</div>
|
||||
|
|
|
@ -48,9 +48,22 @@ let SearchResults = React.createClass({
|
|||
|
||||
_isMounted: false,
|
||||
|
||||
search: function(term) {
|
||||
lighthouse.search(term).then(this.searchCallback);
|
||||
if (!this.state.searching) {
|
||||
this.setState({ searching: true })
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function () {
|
||||
this._isMounted = true;
|
||||
lighthouse.search(this.props.query).then(this.searchCallback);
|
||||
this.search(this.props.query);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
if (nextProps.query != this.props.query) {
|
||||
this.search(nextProps.query);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount: function () {
|
||||
|
@ -77,9 +90,9 @@ let SearchResults = React.createClass({
|
|||
render: function () {
|
||||
return this.state.searching ?
|
||||
<BusyMessage message="Looking up the Dewey Decimals" /> :
|
||||
(this.state.results.length ?
|
||||
(this.state.results && this.state.results.length ?
|
||||
<SearchResultList results={this.state.results} /> :
|
||||
<SearchNoResults query={thisprops.query} />);
|
||||
<SearchNoResults query={this.props.query} />);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -123,14 +136,22 @@ let SearchPage = React.createClass({
|
|||
|
||||
render: function() {
|
||||
return (
|
||||
<main>
|
||||
<main className="main--single-column">
|
||||
{ this.isValidUri(this.props.query) ?
|
||||
<div>
|
||||
<h3>lbry://{this.props.query}</h3>
|
||||
<div><BusyMessage message="Resolving the URL" /></div>
|
||||
</div> : '' }
|
||||
<h3>Search</h3>
|
||||
<SearchResults query={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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@ var FormatItem = React.createClass({
|
|||
const {thumbnail, author, title, description, language, license} = this.props.metadata;
|
||||
const mediaType = lbry.getMediaType(this.props.contentType);
|
||||
|
||||
if (!this.props.contentType && [author, language, license].filter().length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<table className="table-standard">
|
||||
<tbody>
|
||||
|
@ -42,12 +46,15 @@ var FormatItem = React.createClass({
|
|||
|
||||
let ShowPage = React.createClass({
|
||||
_uri: null,
|
||||
_isMounted: false,
|
||||
|
||||
propTypes: {
|
||||
uri: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
outpoint: null,
|
||||
metadata: null,
|
||||
contentType: null,
|
||||
hasSignature: false,
|
||||
|
@ -56,43 +63,91 @@ let ShowPage = React.createClass({
|
|||
costIncludesData: null,
|
||||
uriLookupComplete: null,
|
||||
isDownloaded: null,
|
||||
isFailed: false,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
if (nextProps.uri != this.props.uri) {
|
||||
this.loadUri(nextProps.uri);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._uri = lbryuri.normalize(this.props.uri);
|
||||
this.loadUri(this.props.uri);
|
||||
},
|
||||
|
||||
lbry.resolve({uri: this._uri}).then(({ claim: {txid, nout, has_signature, signature_is_valid, value: {stream: {metadata, source: {contentType}}}}}) => {
|
||||
const outpoint = txid + ':' + nout;
|
||||
loadUri: function(uri) {
|
||||
this._uri = lbryuri.normalize(uri);
|
||||
|
||||
lbry.file_list({outpoint}).then((fileInfo) => {
|
||||
this.setState({
|
||||
isDownloaded: fileInfo.length > 0,
|
||||
lbry.resolve({uri: this._uri}).then((resolveData) => {
|
||||
if (resolveData) {
|
||||
let {claim: {txid, nout, has_signature, signature_is_valid, value: {stream: {metadata, source: {contentType}}}}} = resolveData;
|
||||
const outpoint = txid + ':' + nout;
|
||||
|
||||
lbry.file_list({outpoint}).then((fileInfo) => {
|
||||
this.setState({
|
||||
isDownloaded: fileInfo.length > 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
lbry.setTitle(metadata.title ? metadata.title : this._uri)
|
||||
lbry.setTitle(metadata.title ? metadata.title : this._uri)
|
||||
|
||||
this.setState({
|
||||
outpoint: outpoint,
|
||||
metadata: metadata,
|
||||
hasSignature: has_signature,
|
||||
signatureIsValid: signature_is_valid,
|
||||
contentType: contentType,
|
||||
uriLookupComplete: true,
|
||||
});
|
||||
});
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
outpoint: outpoint,
|
||||
metadata: metadata,
|
||||
hasSignature: has_signature,
|
||||
signatureIsValid: signature_is_valid,
|
||||
contentType: contentType,
|
||||
uriLookupComplete: true,
|
||||
});
|
||||
}
|
||||
|
||||
lbry.getCostInfo(this._uri).then(({cost, includesData}) => {
|
||||
this.setState({
|
||||
cost: cost,
|
||||
costIncludesData: includesData,
|
||||
});
|
||||
lbry.getCostInfo(this._uri).then(({cost, includesData}) => {
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
cost: cost,
|
||||
costIncludesData: includesData,
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (this._isMounted) {
|
||||
this.setState(Object.assign({}, this.getInitialState(), {
|
||||
uriLookupComplete: true,
|
||||
isFailed: true
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const metadata = this.state.metadata;
|
||||
const title = metadata ? this.state.metadata.title : this._uri;
|
||||
|
||||
if (this.state.isFailed) {
|
||||
return <main className="main--single-column">
|
||||
<section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-identity"><h1>{this._uri}</h1></div>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p>
|
||||
This location is not yet in use.
|
||||
{ ' ' }
|
||||
<Link href="?publish" label="Put something here" />.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<section className="show-page-media">
|
||||
|
@ -107,7 +162,7 @@ let ShowPage = React.createClass({
|
|||
? <span style={{float: "right"}}><FilePrice uri={this._uri} metadata={this.state.metadata} /></span>
|
||||
: null}
|
||||
<h1>{title}</h1>
|
||||
{ this.state.uriLookupComplete ?
|
||||
{ this.state.uriLookupComplete && this.state.outpoint ?
|
||||
<div>
|
||||
<div className="card__subtitle">
|
||||
<UriIndicator uri={this._uri} hasSignature={this.state.hasSignature} signatureIsValid={this.state.signatureIsValid} />
|
||||
|
|
Loading…
Reference in a new issue