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

235 lines
5.2 KiB
JavaScript
Raw Normal View History

2017-06-06 23:19:12 +02:00
import React from "react";
import { formatCredits, formatFullPrice } from "util/formatCredits";
2017-06-06 23:19:12 +02:00
import lbry from "../lbry.js";
2016-04-10 02:00:56 +02:00
2016-11-22 21:19:08 +01:00
//component/icon.js
2017-06-08 06:42:19 +02:00
export class Icon extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static propTypes = {
icon: React.PropTypes.string.isRequired,
2016-11-18 09:01:36 +01:00
className: React.PropTypes.string,
fixed: React.PropTypes.bool,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
render() {
2017-06-06 23:19:12 +02:00
const { fixed, className } = this.props;
const spanClassName =
"icon " +
("fixed" in this.props ? "icon-fixed-width " : "") +
this.props.icon +
" " +
(this.props.className || "");
return <span className={spanClassName} />;
2016-04-10 02:00:56 +02:00
}
2017-05-17 10:10:25 +02:00
}
2016-04-10 02:00:56 +02:00
2017-06-08 06:42:19 +02:00
export class TruncatedText extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static propTypes = {
lines: React.PropTypes.number,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
2017-05-19 18:17:19 +02:00
static defaultProps = {
2017-06-06 23:19:12 +02:00
lines: null,
};
2017-05-19 18:17:19 +02:00
2017-05-17 10:10:25 +02:00
render() {
2017-06-06 23:19:12 +02:00
return (
<span
className="truncated-text"
style={{ WebkitLineClamp: this.props.lines }}
>
{this.props.children}
</span>
);
2016-08-04 10:08:12 +02:00
}
2017-05-17 10:10:25 +02:00
}
2017-06-08 06:42:19 +02:00
export class BusyMessage extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static propTypes = {
message: React.PropTypes.string,
2017-06-06 23:19:12 +02:00
};
2016-08-04 10:08:12 +02:00
2017-05-17 10:10:25 +02:00
render() {
2017-06-06 23:19:12 +02:00
return (
<span>{this.props.message} <span className="busy-indicator" /></span>
);
}
2017-05-17 10:10:25 +02:00
}
2017-06-08 06:42:19 +02:00
export class CurrencySymbol extends React.PureComponent {
2017-05-17 10:10:25 +02:00
render() {
return <span>LBC</span>;
}
}
2017-06-08 06:42:19 +02:00
export class CreditAmount extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static 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,
showFullPrice: React.PropTypes.bool,
2017-08-20 23:42:00 +02:00
showPlus: React.PropTypes.bool,
2017-06-06 23:19:12 +02:00
look: React.PropTypes.oneOf(["indicator", "plain"]),
fee: React.PropTypes.bool,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
static defaultProps = {
precision: 2,
2017-05-17 10:10:25 +02:00
label: true,
2017-08-20 23:42:00 +02:00
showFree: false,
2017-06-06 23:19:12 +02:00
look: "indicator",
showFree: false,
showFullPrice: false,
2017-08-20 23:42:00 +02:00
showPlus: false,
fee: false,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
render() {
const minimumRenderableAmount = Math.pow(10, -1 * this.props.precision);
const { amount, precision, showFullPrice } = this.props;
let formattedAmount;
let fullPrice = formatFullPrice(amount, 2);
if (showFullPrice) {
formattedAmount = fullPrice;
} else {
formattedAmount = amount > 0 && amount < minimumRenderableAmount
? "<" + minimumRenderableAmount
: formatCredits(amount, precision);
}
let amountText;
if (this.props.showFree && parseFloat(this.props.amount) === 0) {
2017-06-06 23:19:12 +02:00
amountText = __("free");
} else {
2017-08-20 23:42:00 +02:00
if (this.props.label) {
amountText =
formattedAmount +
" " +
(parseFloat(amount) == 1 ? __("credit") : __("credits"));
} else {
amountText = formattedAmount;
}
if (this.props.showPlus && amount > 0) {
amountText = "+" + amountText;
}
}
2016-04-10 02:00:56 +02:00
return (
<span
className={`credit-amount credit-amount--${this.props.look} ${this.props
.fee
? " meta"
: ""}`}
title={fullPrice}
>
2017-04-13 20:52:26 +02:00
<span>
{amountText}
2017-04-13 20:52:26 +02:00
</span>
2017-06-06 23:19:12 +02:00
{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-05-17 10:10:25 +02:00
}
2017-05-17 10:10:25 +02:00
let addressStyle = {
2017-06-06 23:19:12 +02:00
fontFamily:
'"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace',
};
2017-06-08 06:42:19 +02:00
export class Address extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static propTypes = {
address: React.PropTypes.string,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
constructor(props) {
super(props);
this._inputElem = null;
}
render() {
return (
2017-06-06 23:19:12 +02:00
<input
className="input-copyable"
type="text"
ref={input => {
this._inputElem = input;
}}
onFocus={() => {
this._inputElem.select();
}}
style={addressStyle}
readOnly="readonly"
2017-07-16 18:29:46 +02:00
value={this.props.address || ""}
2017-06-06 23:19:12 +02:00
/>
);
}
2017-05-17 10:10:25 +02:00
}
2016-11-11 13:56:55 +01:00
2017-06-08 06:42:19 +02:00
export class Thumbnail extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static propTypes = {
src: React.PropTypes.string,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
handleError() {
2016-11-11 13:56:55 +01:00
if (this.state.imageUrl != this._defaultImageUri) {
this.setState({
imageUri: this._defaultImageUri,
});
}
2017-05-17 10:10:25 +02:00
}
constructor(props) {
super(props);
2017-06-06 23:19:12 +02:00
this._defaultImageUri = lbry.imagePath("default-thumb.svg");
this._maxLoadTime = 10000;
this._isMounted = false;
2017-05-17 10:10:25 +02:00
this.state = {
2016-11-11 13:56:55 +01:00
imageUri: this.props.src || this._defaultImageUri,
};
2017-05-17 10:10:25 +02:00
}
componentDidMount() {
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);
2017-05-17 10:10:25 +02:00
}
componentWillUnmount() {
this._isMounted = false;
2017-05-17 10:10:25 +02:00
}
render() {
2017-06-06 23:19:12 +02:00
const className = this.props.className ? this.props.className : "",
otherProps = Object.assign({}, this.props);
2017-04-17 14:27:39 +02:00
delete otherProps.className;
2017-06-06 23:19:12 +02:00
return (
<img
ref="img"
onError={() => {
this.handleError();
}}
{...otherProps}
className={className}
src={this.state.imageUri}
/>
);
2017-05-17 10:10:25 +02:00
}
}