2016-11-22 21:19:08 +01:00
|
|
|
import React from 'react';
|
|
|
|
import lbry from '../lbry.js';
|
2016-04-10 02:00:56 +02:00
|
|
|
|
2016-11-22 21:19:08 +01:00
|
|
|
//component/icon.js
|
|
|
|
export let Icon = React.createClass({
|
2016-04-15 12:41:01 +02:00
|
|
|
propTypes: {
|
2017-01-09 10:09:20 +01:00
|
|
|
icon: React.PropTypes.string.isRequired,
|
2016-11-18 09:01:36 +01:00
|
|
|
className: React.PropTypes.string,
|
2017-01-09 10:09:20 +01:00
|
|
|
fixed: React.PropTypes.bool,
|
2016-04-15 12:41:01 +02:00
|
|
|
},
|
2016-04-10 02:00:56 +02:00
|
|
|
render: function() {
|
2017-01-09 10:09:20 +01:00
|
|
|
const {fixed, className, ...other} = this.props;
|
|
|
|
const spanClassName = ('icon ' + ('fixed' in this.props ? 'icon-fixed-width ' : '') +
|
|
|
|
this.props.icon + ' ' + (this.props.className || ''));
|
|
|
|
return <span className={spanClassName} {... other}></span>
|
2016-04-10 02:00:56 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-11-22 21:19:08 +01:00
|
|
|
export let TruncatedText = React.createClass({
|
2016-08-04 10:08:12 +02:00
|
|
|
propTypes: {
|
2017-05-01 02:15:21 +02:00
|
|
|
lines: React.PropTypes.number
|
2016-08-04 10:08:12 +02:00
|
|
|
},
|
|
|
|
getDefaultProps: function() {
|
|
|
|
return {
|
2016-10-21 12:28:42 +02:00
|
|
|
lines: null,
|
2016-08-04 10:08:12 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
render: function() {
|
2017-05-01 02:15:21 +02:00
|
|
|
return <span className="truncated-text" style={{ WebkitLineClamp: this.props.lines }}>{this.props.children}</span>;
|
2016-08-04 10:08:12 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-11-22 21:19:08 +01:00
|
|
|
export let BusyMessage = React.createClass({
|
2016-08-21 16:55:32 +02:00
|
|
|
propTypes: {
|
|
|
|
message: React.PropTypes.string
|
|
|
|
},
|
|
|
|
render: function() {
|
|
|
|
return <span>{this.props.message} <span className="busy-indicator"></span></span>
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-11-22 21:19:08 +01:00
|
|
|
export let CurrencySymbol = React.createClass({
|
2016-08-08 02:20:14 +02:00
|
|
|
render: function() { return <span>LBC</span>; }
|
|
|
|
});
|
|
|
|
|
2016-11-22 21:19:08 +01:00
|
|
|
export let CreditAmount = React.createClass({
|
2016-04-10 02:00:56 +02:00
|
|
|
propTypes: {
|
2017-04-13 20:52:26 +02:00
|
|
|
amount: React.PropTypes.number.isRequired,
|
|
|
|
precision: React.PropTypes.number,
|
2017-04-17 22:22:08 +02:00
|
|
|
isEstimate: React.PropTypes.bool,
|
2017-04-17 09:59:06 +02:00
|
|
|
label: React.PropTypes.bool,
|
2017-04-17 11:10:45 +02:00
|
|
|
showFree: React.PropTypes.bool,
|
2017-04-17 09:59:06 +02:00
|
|
|
look: React.PropTypes.oneOf(['indicator', 'plain']),
|
2017-04-13 20:52:26 +02:00
|
|
|
},
|
|
|
|
getDefaultProps: function() {
|
|
|
|
return {
|
|
|
|
precision: 1,
|
|
|
|
label: true,
|
2017-04-17 11:10:45 +02:00
|
|
|
showFree: false,
|
2017-04-17 09:59:06 +02:00
|
|
|
look: 'indicator',
|
2017-04-13 20:52:26 +02:00
|
|
|
}
|
2016-04-10 02:00:56 +02:00
|
|
|
},
|
|
|
|
render: function() {
|
2017-04-17 11:10:45 +02:00
|
|
|
const formattedAmount = lbry.formatCredits(this.props.amount, this.props.precision);
|
|
|
|
let amountText;
|
|
|
|
if (this.props.showFree && parseFloat(formattedAmount) == 0) {
|
|
|
|
amountText = 'free';
|
|
|
|
} else if (this.props.label) {
|
|
|
|
amountText = formattedAmount + (parseFloat(formattedAmount) == 1 ? ' credit' : ' credits');
|
|
|
|
} else {
|
|
|
|
amountText = formattedAmount;
|
|
|
|
}
|
|
|
|
|
2016-04-10 02:00:56 +02:00
|
|
|
return (
|
2017-04-17 09:59:06 +02:00
|
|
|
<span className={`credit-amount credit-amount--${this.props.look}`}>
|
2017-04-13 20:52:26 +02:00
|
|
|
<span>
|
2017-04-17 11:10:45 +02:00
|
|
|
{amountText}
|
2017-04-13 20:52:26 +02:00
|
|
|
</span>
|
|
|
|
{ this.props.isEstimate ? <span className="credit-amount__estimate" title="This is an estimate and does not include data fees">*</span> : null }
|
2016-04-10 02:00:56 +02:00
|
|
|
</span>
|
|
|
|
);
|
|
|
|
}
|
2016-05-23 16:24:23 +02:00
|
|
|
});
|
2016-09-01 08:40:23 +02:00
|
|
|
|
2017-04-13 20:52:26 +02:00
|
|
|
export let FilePrice = React.createClass({
|
|
|
|
_isMounted: false,
|
|
|
|
|
|
|
|
propTypes: {
|
|
|
|
uri: React.PropTypes.string.isRequired,
|
2017-04-17 09:59:06 +02:00
|
|
|
look: React.PropTypes.oneOf(['indicator', 'plain']),
|
|
|
|
},
|
|
|
|
|
|
|
|
getDefaultProps: function() {
|
|
|
|
return {
|
|
|
|
look: 'indicator',
|
|
|
|
}
|
2017-04-13 20:52:26 +02:00
|
|
|
},
|
|
|
|
|
2017-04-17 11:10:45 +02:00
|
|
|
componentWillMount: function() {
|
|
|
|
this.setState({
|
2017-04-17 22:22:08 +02:00
|
|
|
cost: null,
|
|
|
|
isEstimate: null,
|
2017-04-17 11:10:45 +02:00
|
|
|
});
|
2017-04-13 20:52:26 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
componentDidMount: function() {
|
|
|
|
this._isMounted = true;
|
|
|
|
lbry.getCostInfo(this.props.uri).then(({cost, includesData}) => {
|
|
|
|
if (this._isMounted) {
|
|
|
|
this.setState({
|
|
|
|
cost: cost,
|
2017-04-17 22:22:08 +02:00
|
|
|
isEstimate: !includesData,
|
2017-04-13 20:52:26 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}, (err) => {
|
|
|
|
// If we get an error looking up cost information, do nothing
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
componentWillUnmount: function() {
|
|
|
|
this._isMounted = false;
|
|
|
|
},
|
|
|
|
|
|
|
|
render: function() {
|
2017-04-17 11:10:45 +02:00
|
|
|
if (this.state.cost === null) {
|
|
|
|
return <span className={`credit-amount credit-amount--${this.props.look}`}>???</span>;
|
2017-04-13 20:52:26 +02:00
|
|
|
}
|
2017-04-17 11:10:45 +02:00
|
|
|
|
2017-04-17 22:22:08 +02:00
|
|
|
return <CreditAmount label={false} amount={this.state.cost} isEstimate={this.state.isEstimate} showFree={true} />
|
2017-04-13 20:52:26 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-09-01 08:40:23 +02:00
|
|
|
var addressStyle = {
|
|
|
|
fontFamily: '"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace',
|
|
|
|
};
|
2016-11-22 21:19:08 +01:00
|
|
|
export let Address = React.createClass({
|
2017-04-20 16:45:39 +02:00
|
|
|
_inputElem: null,
|
2016-09-01 08:40:23 +02:00
|
|
|
propTypes: {
|
|
|
|
address: React.PropTypes.string,
|
|
|
|
},
|
|
|
|
render: function() {
|
|
|
|
return (
|
2017-04-20 16:45:39 +02:00
|
|
|
<input className="input-copyable" type="text" ref={(input) => { this._inputElem = input; }}
|
|
|
|
onFocus={() => { this._inputElem.select(); }} style={addressStyle} readOnly="readonly" value={this.props.address}></input>
|
2016-09-01 08:40:23 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
2016-11-11 13:56:55 +01:00
|
|
|
|
2016-11-22 21:19:08 +01:00
|
|
|
export let Thumbnail = React.createClass({
|
2017-02-08 22:15:45 +01:00
|
|
|
_defaultImageUri: lbry.imagePath('default-thumb.svg'),
|
2016-11-11 13:56:55 +01:00
|
|
|
_maxLoadTime: 10000,
|
2017-01-04 21:46:20 +01:00
|
|
|
_isMounted: false,
|
2016-11-11 13:56:55 +01:00
|
|
|
|
|
|
|
propTypes: {
|
2017-01-13 04:23:12 +01:00
|
|
|
src: React.PropTypes.string,
|
2016-11-11 13:56:55 +01:00
|
|
|
},
|
|
|
|
handleError: function() {
|
|
|
|
if (this.state.imageUrl != this._defaultImageUri) {
|
|
|
|
this.setState({
|
|
|
|
imageUri: this._defaultImageUri,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getInitialState: function() {
|
|
|
|
return {
|
|
|
|
imageUri: this.props.src || this._defaultImageUri,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
componentDidMount: function() {
|
2017-01-04 21:46:20 +01:00
|
|
|
this._isMounted = true;
|
2016-11-11 13:56:55 +01:00
|
|
|
setTimeout(() => {
|
2017-01-04 21:46:20 +01:00
|
|
|
if (this._isMounted && !this.refs.img.complete) {
|
2016-11-11 13:56:55 +01:00
|
|
|
this.setState({
|
|
|
|
imageUri: this._defaultImageUri,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}, this._maxLoadTime);
|
|
|
|
},
|
2017-01-04 21:46:20 +01:00
|
|
|
componentWillUnmount: function() {
|
|
|
|
this._isMounted = false;
|
|
|
|
},
|
2016-11-11 13:56:55 +01:00
|
|
|
render: function() {
|
2017-04-17 14:27:39 +02:00
|
|
|
const className = this.props.className ? this.props.className : '',
|
|
|
|
otherProps = Object.assign({}, this.props)
|
|
|
|
delete otherProps.className;
|
|
|
|
return <img ref="img" onError={this.handleError} {...otherProps} className={className} src={this.state.imageUri} />
|
2016-11-11 13:56:55 +01:00
|
|
|
},
|
|
|
|
});
|