lbry-desktop/ui/js/component/common.js

204 lines
5.6 KiB
JavaScript
Raw Normal View History

2016-11-22 21:19:08 +01:00
import React from 'react';
import lbry from '../lbry.js';
2017-02-10 00:29:22 +01:00
import $clamp from 'clamp-js-main';
2016-04-10 02:00:56 +02:00
2016-11-22 21:19:08 +01:00
//component/icon.js
export let Icon = React.createClass({
propTypes: {
icon: React.PropTypes.string.isRequired,
2016-11-18 09:01:36 +01:00
className: React.PropTypes.string,
fixed: React.PropTypes.bool,
},
2016-04-10 02:00:56 +02:00
render: function() {
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: {
lines: React.PropTypes.number,
height: React.PropTypes.string,
auto: React.PropTypes.bool,
2016-08-04 10:08:12 +02:00
},
getDefaultProps: function() {
return {
lines: null,
height: null,
auto: true,
2016-08-04 10:08:12 +02:00
}
},
componentDidMount: function() {
// Manually round up the line height, because clamp.js doesn't like fractional-pixel line heights.
// Need to work directly on the style object because setting the style prop doesn't update internal styles right away.
this.refs.span.style.lineHeight = Math.ceil(parseFloat(getComputedStyle(this.refs.span).lineHeight)) + 'px';
$clamp(this.refs.span, {
clamp: this.props.lines || this.props.height || 'auto',
});
},
2016-08-04 10:08:12 +02:00
render: function() {
return <span ref="span" className="truncated-text">{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({
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({
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,
isEstimate: React.PropTypes.bool,
label: React.PropTypes.bool,
showFree: React.PropTypes.bool,
look: React.PropTypes.oneOf(['indicator', 'plain']),
2017-04-13 20:52:26 +02:00
},
getDefaultProps: function() {
return {
precision: 1,
label: true,
showFree: false,
look: 'indicator',
2017-04-13 20:52:26 +02:00
}
2016-04-10 02:00:56 +02:00
},
render: function() {
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 (
<span className={`credit-amount credit-amount--${this.props.look}`}>
2017-04-13 20:52:26 +02:00
<span>
{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>
);
}
});
2017-04-13 20:52:26 +02:00
export let FilePrice = React.createClass({
_isMounted: false,
propTypes: {
uri: React.PropTypes.string.isRequired,
look: React.PropTypes.oneOf(['indicator', 'plain']),
},
getDefaultProps: function() {
return {
look: 'indicator',
}
2017-04-13 20:52:26 +02:00
},
componentWillMount: function() {
this.setState({
cost: null,
isEstimate: null,
});
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,
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() {
if (this.state.cost === null) {
return <span className={`credit-amount credit-amount--${this.props.look}`}>???</span>;
2017-04-13 20:52:26 +02:00
}
return <CreditAmount label={false} amount={this.state.cost} isEstimate={this.state.isEstimate} showFree={true} />
2017-04-13 20:52:26 +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({
_inputElem: null,
propTypes: {
address: React.PropTypes.string,
},
render: function() {
return (
<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-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,
_isMounted: false,
2016-11-11 13:56:55 +01:00
propTypes: {
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() {
this._isMounted = true;
2016-11-11 13:56:55 +01:00
setTimeout(() => {
if (this._isMounted && !this.refs.img.complete) {
2016-11-11 13:56:55 +01:00
this.setState({
imageUri: this._defaultImageUri,
});
}
}, this._maxLoadTime);
},
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
},
});