i18n support
This commit is contained in:
parent
e761cd6f8a
commit
520b9a58d6
@ -10,6 +10,9 @@
|
||||
"d3": "^4.13.0",
|
||||
"deep-equal": "^1.0.1",
|
||||
"fuse": "^0.4.0",
|
||||
"i18next": "^13.0.1",
|
||||
"i18next-browser-languagedetector": "^2.2.4",
|
||||
"i18next-xhr-backend": "^1.5.1",
|
||||
"jazzicon": "^1.5.0",
|
||||
"node-sass": "^4.9.3",
|
||||
"npm": "^6.0.0",
|
||||
@ -19,6 +22,7 @@
|
||||
"react-dom": "^16.2.0",
|
||||
"react-ga": "^2.5.3",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-i18next": "^8.4.0",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-responsive": "^5.0.0",
|
||||
"react-router-dom": "^4.3.1",
|
||||
|
72
public/locales/en.json
Normal file
72
public/locales/en.json
Normal file
@ -0,0 +1,72 @@
|
||||
{
|
||||
"noWallet": "No Ethereum wallet found",
|
||||
"wrongNetwork": "You are on the wrong network",
|
||||
"switchNetwork": "Please switch to {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "Please visit us from a web3-enabled mobile browser such as Trust Wallet or Coinbase Wallet.",
|
||||
"installMetamask": "Please visit us after installing Metamask on Chrome or Brave.",
|
||||
"disconnected": "Disconnected",
|
||||
"swap": "Swap",
|
||||
"send": "Send",
|
||||
"pool": "Pool",
|
||||
"betaWarning": "This project is in beta. Use at your own risk.",
|
||||
"input": "Input",
|
||||
"output": "Output",
|
||||
"estimated": "estimated",
|
||||
"balance": "Balance: {{ balanceInput }}",
|
||||
"unlock": "Unlock",
|
||||
"pending": "Pending",
|
||||
"selectToken": "Select a token",
|
||||
"searchOrPaste": "Search Token or Paste Address",
|
||||
"noExchange": "No Exchange Found",
|
||||
"exchangeRate": "Exchange Rate",
|
||||
"enterValueCont": "Enter a {{ missingCurrencyValue }} value to continue.",
|
||||
"selectTokenCont": "Select a token to continue.",
|
||||
"noLiquidity": "No liquidity.",
|
||||
"unlockTokenCont": "Please unlock token to continue.",
|
||||
"transactionDetails": "Transaction Details",
|
||||
"youAreSelling": "You are selling",
|
||||
"orTransFail": "or the transaction will fail.",
|
||||
"youWillReceive": "You will receive at least",
|
||||
"youAreBuying": "You are buying",
|
||||
"itWillCost": "It will cost at most",
|
||||
"insufficientBalance": "Insufficient Balance",
|
||||
"inputNotValid": "Not a valid input value",
|
||||
"differentToken": "Must be different token.",
|
||||
"noRecipient": "Enter a wallet address to send to.",
|
||||
"invalidRecipient": "Please enter a valid wallet address recipient.",
|
||||
"recipientAddress": "Recipient Address",
|
||||
"youAreSending": "You are sending",
|
||||
"willReceive": "will receive at least",
|
||||
"to": "to",
|
||||
"addLiquidity": "Add Liquidity",
|
||||
"deposit": "Deposit",
|
||||
"currentPoolSize": "Current Pool Size",
|
||||
"yourPoolShare": "Your Pool Share",
|
||||
"noZero": "Amount cannot be zero.",
|
||||
"mustBeETH": "One of the input must be ETH.",
|
||||
"enterCurrencyOrLabelCont": "Enter a {{ inputCurrency }} or {{ label }} value to continue.",
|
||||
"youAreAdding": "You are adding between",
|
||||
"and": "and",
|
||||
"intoPool": "into the liquidity pool.",
|
||||
"outPool": "into the liquidity pool.",
|
||||
"youWillMint": "You will mint",
|
||||
"liquidityTokens": "liquidity tokens.",
|
||||
"totalSupplyIs": "Current total supply of liquidity tokens is",
|
||||
"tokenWorth": "At current exchange rate, each pool token is worth",
|
||||
"firstLiquidity": "You are the first person to add liquidity!",
|
||||
"initialExchangeRate": "The initial exchange rate will be set based on your deposits. Please make sure that your ETH and {{ label }} deposits have the same fiat value.",
|
||||
"removeLiquidity": "Remove Liquidity",
|
||||
"poolTokens": "Pool Tokens",
|
||||
"enterLabelCont": "Enter a {{ label }} value to continue.",
|
||||
"youAreRemoving": "You are removing between",
|
||||
"youWillRemove": "You will remove",
|
||||
"createExchange": "Create Exchange",
|
||||
"invalidTokenAddress": "Not a valid token address",
|
||||
"exchangeExists": "{{ label }} Exchange already exists!",
|
||||
"invalidSymbol": "Invalid symbol",
|
||||
"invalidDecimals": "Invalid decimals",
|
||||
"tokenAddress": "Token Address",
|
||||
"label": "Label",
|
||||
"decimals": "Decimals",
|
||||
"enterTokenCont": "Enter a token address to continue"
|
||||
}
|
72
public/locales/zh-CN.json
Normal file
72
public/locales/zh-CN.json
Normal file
@ -0,0 +1,72 @@
|
||||
{
|
||||
"noWallet": "未发现以太钱包",
|
||||
"wrongNetwork": "网络错误",
|
||||
"switchNetwork": "请切换到 {{ correctNetwork }}",
|
||||
"installWeb3MobileBrowser": "请从支持web3的移动端浏览器,如 Trust Wallet 或 Coinbase Wallet 访问。",
|
||||
"installMetamask": "请从安装了 Metamask 插件的 Chrome 或 Brave 访问。",
|
||||
"disconnected": "未连接",
|
||||
"swap": "交换",
|
||||
"send": "发送",
|
||||
"pool": "资金池",
|
||||
"betaWarning": "项目尚处于beta阶段。使用需自行承担风险。",
|
||||
"input": "输入",
|
||||
"output": "输出",
|
||||
"estimated": "估计",
|
||||
"balance": "余额: {{ balanceInput }}",
|
||||
"unlock": "解锁",
|
||||
"pending": "处理中",
|
||||
"selectToken": "选择代币",
|
||||
"searchOrPaste": "搜索代币或粘贴地址",
|
||||
"noExchange": "未找到交易所",
|
||||
"exchangeRate": "兑换率",
|
||||
"enterValueCont": "输入{{ missingCurrencyValue }}值继续。",
|
||||
"selectTokenCont": "选取代币继续。",
|
||||
"noLiquidity": "没有流动金。",
|
||||
"unlockTokenCont": "请解锁代币继续。",
|
||||
"transactionDetails": "交易明细",
|
||||
"youAreSelling": "你正在出售",
|
||||
"orTransFail": "或交易失败。",
|
||||
"youWillReceive": "你将收到至少",
|
||||
"youAreBuying": "你正在购买",
|
||||
"itWillCost": "它将花费至少",
|
||||
"insufficientBalance": "余额不足",
|
||||
"inputNotValid": "无效的输入值",
|
||||
"differentToken": "必须是不同的代币。",
|
||||
"noRecipient": "输入接收钱包地址。",
|
||||
"invalidRecipient": "请输入有效的接收钱包地址。",
|
||||
"recipientAddress": "接收地址",
|
||||
"youAreSending": "你正在发送",
|
||||
"willReceive": "将收到至少",
|
||||
"to": "到",
|
||||
"addLiquidity": "添加流动金",
|
||||
"deposit": "存入",
|
||||
"currentPoolSize": "当前资金池大小",
|
||||
"yourPoolShare": "你的资金池份额",
|
||||
"noZero": "金额不能为零。",
|
||||
"mustBeETH": "输入中必须有一个是 ETH。",
|
||||
"enterCurrencyOrLabelCont": "输入 {{ inputCurrency }} 或 {{ label }} 值继续。",
|
||||
"youAreAdding": "你将添加",
|
||||
"and": "和",
|
||||
"intoPool": "入流动资金池。",
|
||||
"outPool": "出流动资金池。",
|
||||
"youWillMint": "你将铸造",
|
||||
"liquidityTokens": "流动代币。",
|
||||
"totalSupplyIs": "当前流动代币的总量是",
|
||||
"tokenWorth": "当前兑换率下,每个资金池代币价值",
|
||||
"firstLiquidity": "你是第一个添加流动金的人!",
|
||||
"initialExchangeRate": "初始兑换率将由你的存入情况决定。请确保你存入的 ETH 和 {{ label }} 具有相同的法币价值。",
|
||||
"removeLiquidity": "删除流动金",
|
||||
"poolTokens": "资金池代币",
|
||||
"enterLabelCont": "输入 {{ label }} 值继续。",
|
||||
"youAreRemoving": "你正在移除",
|
||||
"youWillRemove": "你将移除",
|
||||
"createExchange": "创建交易所",
|
||||
"invalidTokenAddress": "代币地址无效",
|
||||
"exchangeExists": "{{ label }} 交易所已存在!",
|
||||
"invalidSymbol": "代币符号无效",
|
||||
"invalidDecimals": "小数位数无效",
|
||||
"tokenAddress": "代币地址",
|
||||
"label": "代币符号",
|
||||
"decimals": "小数位数",
|
||||
"enterTokenCont": "输入代币地址继续"
|
||||
}
|
@ -20,6 +20,7 @@ class AddressInputPanel extends Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
t,
|
||||
title,
|
||||
onChange,
|
||||
value,
|
||||
@ -34,7 +35,7 @@ class AddressInputPanel extends Component {
|
||||
<div className="address-input-panel__input-container">
|
||||
<div className="currency-input-panel__label-row">
|
||||
<div className="currency-input-panel__label-container">
|
||||
<span className="currency-input-panel__label">{title || 'Recipient Address'}</span>
|
||||
<span className="currency-input-panel__label">{title || t("recipientAddress")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="currency-input-panel__input-row">
|
||||
|
@ -32,10 +32,29 @@ class ContextualInfo extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="contextual-info__details">
|
||||
{this.props.renderTransactionDetails()}
|
||||
</div>
|
||||
)
|
||||
<Modal key="modal" onClose={() => this.setState({ showDetailModal: false })}>
|
||||
<CSSTransitionGroup
|
||||
transitionName="summary-modal"
|
||||
transitionAppear={true}
|
||||
transitionLeave={true}
|
||||
transitionAppearTimeout={200}
|
||||
transitionLeaveTimeout={200}
|
||||
transitionEnterTimeout={200}
|
||||
>
|
||||
<div className={c('contextual-info__summary-modal', modalClass)}>
|
||||
<div
|
||||
key="open-details"
|
||||
className="contextual-info__open-details-container contextual-info__modal-button"
|
||||
onClick={() => this.setState({showDetailModal: false})}
|
||||
>
|
||||
<span>{this.props.openModalText}</span>
|
||||
<img src={DropupBlue} />
|
||||
</div>
|
||||
{this.props.renderTransactionDetails()}
|
||||
</div>
|
||||
</CSSTransitionGroup>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import { CSSTransitionGroup } from "react-transition-group";
|
||||
import classnames from 'classnames';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import Fuse from '../../helpers/fuse';
|
||||
import Modal from '../Modal';
|
||||
import TokenLogo from '../TokenLogo';
|
||||
@ -105,6 +106,7 @@ class CurrencyInputPanel extends Component {
|
||||
const tokens = this.createTokenList();
|
||||
const { loadingExchange, searchQuery } = this.state;
|
||||
const {
|
||||
t,
|
||||
selectedTokens,
|
||||
disableTokenSelect,
|
||||
web3,
|
||||
@ -160,7 +162,7 @@ class CurrencyInputPanel extends Component {
|
||||
const { label } = selectors().getBalance(account, searchQuery);
|
||||
return [
|
||||
<div key="token-modal-no-exchange" className="token-modal__token-row token-modal__token-row--no-exchange">
|
||||
<div>No Exchange Found</div>
|
||||
<div>{t("noExchange")}</div>
|
||||
</div>,
|
||||
<div
|
||||
key="token-modal-create-exchange"
|
||||
@ -178,7 +180,7 @@ class CurrencyInputPanel extends Component {
|
||||
if (!results.length) {
|
||||
return (
|
||||
<div className="token-modal__token-row token-modal__token-row--no-exchange">
|
||||
<div>No Exchange Found</div>
|
||||
<div>{t("noExchange")}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -222,7 +224,7 @@ class CurrencyInputPanel extends Component {
|
||||
<div className="token-modal__search-container">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search Token or Paste Address"
|
||||
placeholder={this.props.t("searchOrPaste")}
|
||||
className="token-modal__search-input"
|
||||
onChange={e => {
|
||||
this.setState({ searchQuery: e.target.value });
|
||||
@ -241,6 +243,7 @@ class CurrencyInputPanel extends Component {
|
||||
|
||||
renderUnlockButton() {
|
||||
const {
|
||||
t,
|
||||
selectors,
|
||||
selectedTokenAddress,
|
||||
account,
|
||||
@ -276,7 +279,7 @@ class CurrencyInputPanel extends Component {
|
||||
className='currency-input-panel__sub-currency-select currency-input-panel__sub-currency-select--pending'
|
||||
>
|
||||
<div className="loader" />
|
||||
Pending
|
||||
{t("pending")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@ -296,13 +299,14 @@ class CurrencyInputPanel extends Component {
|
||||
});
|
||||
}}
|
||||
>
|
||||
Unlock
|
||||
{t("unlock")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
renderInput() {
|
||||
const {
|
||||
t,
|
||||
errorMessage,
|
||||
value,
|
||||
onValueChange,
|
||||
@ -358,7 +362,7 @@ class CurrencyInputPanel extends Component {
|
||||
)
|
||||
: null
|
||||
}
|
||||
{ TOKEN_ADDRESS_TO_LABEL[selectedTokenAddress] || 'Select a token' }
|
||||
{ TOKEN_ADDRESS_TO_LABEL[selectedTokenAddress] || t("selectToken") }
|
||||
<span className="currency-input-panel__dropdown-icon" />
|
||||
</button>
|
||||
</div>
|
||||
@ -416,5 +420,5 @@ export default withRouter(
|
||||
addPendingTx: opts => dispatch(addPendingTx(opts)),
|
||||
addApprovalTx: opts => dispatch(addApprovalTx(opts)),
|
||||
}),
|
||||
)(CurrencyInputPanel)
|
||||
)(withNamespaces()(CurrencyInputPanel))
|
||||
);
|
||||
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
import UAParser from 'ua-parser-js';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import Logo from '../Logo';
|
||||
import CoinbaseWalletLogo from '../../assets/images/coinbase-wallet-logo.png';
|
||||
import TrustLogo from '../../assets/images/trust-wallet-logo.svg';
|
||||
@ -77,6 +78,7 @@ function isMobile() {
|
||||
class BlockingWarning extends Component {
|
||||
render () {
|
||||
const {
|
||||
t,
|
||||
isConnected,
|
||||
initialized,
|
||||
networkId,
|
||||
@ -90,21 +92,21 @@ class BlockingWarning extends Component {
|
||||
|
||||
if (wrongNetwork && initialized) {
|
||||
content = [
|
||||
<div key="warning-title">You are on the wrong network</div>,
|
||||
<div key="warning-title">{t("wrongNetwork")}</div>,
|
||||
<div key="warning-desc" className="header__dialog__description">
|
||||
{`Please switch to ${correctNetwork}`}
|
||||
{t("switchNetwork", {correctNetwork})}
|
||||
</div>,
|
||||
];
|
||||
}
|
||||
|
||||
if (!isConnected && initialized) {
|
||||
content = [
|
||||
<div key="warning-title">No Ethereum wallet found</div>,
|
||||
<div key="warning-title">{t("noWallet")}</div>,
|
||||
<div key="warning-desc" className="header__dialog__description">
|
||||
{
|
||||
isMobile()
|
||||
? 'Please visit us from a web3-enabled mobile browser such as Trust Wallet or Coinbase Wallet.'
|
||||
: 'Please visit us after installing Metamask on Chrome or Brave.'
|
||||
? t("installWeb3MobileBrowser")
|
||||
: t("installMetamask")
|
||||
}
|
||||
</div>,
|
||||
<div key="warning-logos" className="header__download">
|
||||
@ -171,4 +173,4 @@ export default connect(
|
||||
web3: state.web3connect.web3,
|
||||
networkId: state.web3connect.networkId,
|
||||
}),
|
||||
)(Header);
|
||||
)(withNamespaces()(Header));
|
||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import { dismissBetaMessage } from '../../ducks/app';
|
||||
import {Tab, Tabs} from "../Tab";
|
||||
|
||||
@ -38,18 +39,18 @@ class NavigationTabs extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { showBetaMessage, className, dismissBetaMessage } = this.props;
|
||||
const { t, showBetaMessage, className, dismissBetaMessage } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Tabs className={className}>
|
||||
{ this.renderTab('Swap', '/swap', /swap/) }
|
||||
{ this.renderTab('Send', '/send', /send/) }
|
||||
{ this.renderTab('Pool', '/add-liquidity', /add-liquidity|remove-liquidity|create-exchange/) }
|
||||
{ this.renderTab(t("swap"), '/swap', /swap/) }
|
||||
{ this.renderTab(t("send"), '/send', /send/) }
|
||||
{ this.renderTab(t("pool"), '/add-liquidity', /add-liquidity|remove-liquidity|create-exchange/) }
|
||||
</Tabs>
|
||||
{
|
||||
showBetaMessage && (
|
||||
<div className="beta-message" onClick={dismissBetaMessage}>
|
||||
💀 This project is in beta. Use at your own risk.
|
||||
💀 {t("betaWarning")}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -66,5 +67,5 @@ export default withRouter(
|
||||
dispatch => ({
|
||||
dismissBetaMessage: () => dispatch(dismissBetaMessage()),
|
||||
}),
|
||||
)(NavigationTabs)
|
||||
)(withNamespaces()(NavigationTabs))
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ import classnames from 'classnames';
|
||||
import Web3 from 'web3';
|
||||
import Jazzicon from 'jazzicon';
|
||||
import { CSSTransitionGroup } from "react-transition-group";
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import './web3-status.scss';
|
||||
import Modal from '../Modal';
|
||||
|
||||
@ -35,7 +36,7 @@ class Web3Status extends Component {
|
||||
{transaction}
|
||||
</div>
|
||||
<div className="pending-modal__pending-indicator">
|
||||
<div className="loader" /> Pending
|
||||
<div className="loader" /> {this.props.t("pending")}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -69,7 +70,7 @@ class Web3Status extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { address, pending, confirmed } = this.props;
|
||||
const { t, address, pending, confirmed } = this.props;
|
||||
const hasPendingTransactions = !!pending.length;
|
||||
const hasConfirmedTransactions = !!confirmed.length;
|
||||
|
||||
@ -83,7 +84,7 @@ class Web3Status extends Component {
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
<div className="web3-status__text">
|
||||
{ hasPendingTransactions ? getPendingText(pending) : getText(address) }
|
||||
{hasPendingTransactions ? getPendingText(pending, t("pending")) : getText(address, t("disconnected")) }
|
||||
</div>
|
||||
<div
|
||||
className="web3-status__identicon"
|
||||
@ -108,18 +109,18 @@ class Web3Status extends Component {
|
||||
|
||||
|
||||
|
||||
function getPendingText(pendingTransactions) {
|
||||
function getPendingText(pendingTransactions, pendingLabel) {
|
||||
return (
|
||||
<div className="web3-status__pending-container">
|
||||
<div className="loader" />
|
||||
<span key="text">{pendingTransactions.length} Pending</span>
|
||||
<span key="text">{pendingTransactions.length} {pendingLabel}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getText(text) {
|
||||
function getText(text, disconnectedText) {
|
||||
if (!text || text.length < 42 || !Web3.utils.isHexStrict(text)) {
|
||||
return 'Disconnected';
|
||||
return disconnectedText;
|
||||
}
|
||||
|
||||
const address = Web3.utils.toChecksumAddress(text);
|
||||
@ -145,4 +146,4 @@ export default connect(
|
||||
confirmed: state.web3connect.transactions.confirmed,
|
||||
};
|
||||
}
|
||||
)(Web3Status);
|
||||
)(withNamespaces()(Web3Status));
|
||||
|
32
src/i18n.js
Normal file
32
src/i18n.js
Normal file
@ -0,0 +1,32 @@
|
||||
import i18n from "i18next";
|
||||
import Backend from 'i18next-xhr-backend';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import { reactI18nextModule } from "react-i18next";
|
||||
|
||||
const resources = {
|
||||
loadPath: `./locales/{{lng}}.json`
|
||||
}
|
||||
|
||||
i18n
|
||||
// load translation using xhr -> see /public/locales
|
||||
// learn more: https://github.com/i18next/i18next-xhr-backend
|
||||
.use(Backend)
|
||||
// detect user language
|
||||
// learn more: https://github.com/i18next/i18next-browser-languageDetector
|
||||
.use(LanguageDetector)
|
||||
// pass the i18n instance to react-i18next.
|
||||
.use(reactI18nextModule)
|
||||
// init i18next
|
||||
// for all options read: https://www.i18next.com/overview/configuration-options
|
||||
.init({
|
||||
backend: resources,
|
||||
fallbackLng: "en",
|
||||
|
||||
keySeparator: false,
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false
|
||||
}
|
||||
});
|
||||
|
||||
export default i18n;
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import ReactGA from 'react-ga';
|
||||
import './i18n';
|
||||
import App from './pages/App';
|
||||
import store from './store';
|
||||
|
||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from "classnames";
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import CurrencyInputPanel from '../../components/CurrencyInputPanel';
|
||||
import OversizedPanel from '../../components/OversizedPanel';
|
||||
import ContextualInfo from '../../components/ContextualInfo';
|
||||
@ -51,10 +52,11 @@ class AddLiquidity extends Component {
|
||||
};
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { isConnected, account, exchangeAddresses, balances, web3 } = this.props;
|
||||
const { t, isConnected, account, exchangeAddresses, balances, web3 } = this.props;
|
||||
const { inputValue, outputValue, inputCurrency, outputCurrency, lastEditedField } = this.state;
|
||||
|
||||
return isConnected !== nextProps.isConnected ||
|
||||
t != nextProps.t ||
|
||||
account !== nextProps.account ||
|
||||
exchangeAddresses !== nextProps.exchangeAddresses ||
|
||||
web3 !== nextProps.web3 ||
|
||||
@ -111,7 +113,7 @@ class AddLiquidity extends Component {
|
||||
};
|
||||
|
||||
getBalance(currency) {
|
||||
const { selectors, account } = this.props;
|
||||
const { t, selectors, account } = this.props;
|
||||
|
||||
if (!currency) {
|
||||
return '';
|
||||
@ -122,7 +124,8 @@ class AddLiquidity extends Component {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `Balance: ${value.dividedBy(10 ** decimals).toFixed(4)}`;
|
||||
const balanceInput = value.dividedBy(10 ** decimals).toFixed(4);
|
||||
return t("balance", { balanceInput });
|
||||
}
|
||||
|
||||
isUnapproved() {
|
||||
@ -271,7 +274,7 @@ class AddLiquidity extends Component {
|
||||
}
|
||||
|
||||
validate() {
|
||||
const { selectors, account } = this.props;
|
||||
const { t, selectors, account } = this.props;
|
||||
const {
|
||||
inputValue, outputValue,
|
||||
inputCurrency, outputCurrency,
|
||||
@ -291,11 +294,11 @@ class AddLiquidity extends Component {
|
||||
const { value: tokenValue, decimals } = selectors().getBalance(account, outputCurrency);
|
||||
|
||||
if (ethValue.isLessThan(BN(inputValue * 10 ** 18))) {
|
||||
inputError = 'Insufficient Balance';
|
||||
inputError = t("insufficientBalance");
|
||||
}
|
||||
|
||||
if (tokenValue.isLessThan(BN(outputValue * 10 ** decimals))) {
|
||||
outputError = 'Insufficient Balance';
|
||||
outputError = t("insufficientBalance");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -306,18 +309,19 @@ class AddLiquidity extends Component {
|
||||
}
|
||||
|
||||
renderInfo() {
|
||||
const t = this.props.t;
|
||||
const blank = (
|
||||
<div className="pool__summary-panel">
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="pool__exchange-rate">Exchange Rate</span>
|
||||
<span className="pool__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Current Pool Size</span>
|
||||
<span className="swap__exchange-rate">{t("currentPoolSize")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Your Pool Share</span>
|
||||
<span className="swap__exchange-rate">{t("yourPoolShare")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
</div>
|
||||
@ -353,16 +357,16 @@ class AddLiquidity extends Component {
|
||||
return (
|
||||
<div className="pool__summary-panel">
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="pool__exchange-rate">Exchange Rate</span>
|
||||
<span className="pool__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span>{`1 ETH = ${rateText} ${label}`}</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Current Pool Size</span>
|
||||
<span className="swap__exchange-rate">{t("currentPoolSize")}</span>
|
||||
<span>{` ${ethValue.dividedBy(10 ** 18).toFixed(2)} ${eth} + ${tokenValue.dividedBy(10 ** decimals).toFixed(2)} ${label}`}</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">
|
||||
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%)
|
||||
{t("yourPoolShare")} ({ownership.multipliedBy(100).toFixed(2)}%)
|
||||
</span>
|
||||
<span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
|
||||
</div>
|
||||
@ -377,16 +381,16 @@ class AddLiquidity extends Component {
|
||||
return (
|
||||
<div className="pool__summary-panel">
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="pool__exchange-rate">Exchange Rate</span>
|
||||
<span className="pool__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span>{`1 ETH = ${tokenValue.multipliedBy(10 ** (18 - decimals)).dividedBy(ethValue).toFixed(4)} ${label}`}</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Current Pool Size</span>
|
||||
<span className="swap__exchange-rate">{t("currentPoolSize")}</span>
|
||||
<span>{` ${ethValue.dividedBy(10 ** 18).toFixed(2)} ${eth} + ${tokenValue.dividedBy(10 ** decimals).toFixed(2)} ${label}`}</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">
|
||||
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%)
|
||||
{t("yourPoolShare")} ({ownership.multipliedBy(100).toFixed(2)}%)
|
||||
</span>
|
||||
<span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
|
||||
</div>
|
||||
@ -395,7 +399,7 @@ class AddLiquidity extends Component {
|
||||
}
|
||||
|
||||
renderSummary(inputError, outputError) {
|
||||
const { selectors, exchangeAddresses: { fromToken } } = this.props;
|
||||
const { t, selectors, exchangeAddresses: { fromToken } } = this.props;
|
||||
const {
|
||||
inputValue,
|
||||
outputValue,
|
||||
@ -412,22 +416,23 @@ class AddLiquidity extends Component {
|
||||
contextualInfo = inputError || outputError;
|
||||
isError = true;
|
||||
} else if (!inputCurrency || !outputCurrency) {
|
||||
contextualInfo = 'Select a token to continue.';
|
||||
contextualInfo = t("selectTokenCont");
|
||||
} else if (inputCurrency === outputCurrency) {
|
||||
contextualInfo = 'Must be different token.';
|
||||
contextualInfo = t("differentToken");
|
||||
} else if (![inputCurrency, outputCurrency].includes('ETH')) {
|
||||
contextualInfo = 'One of the input must be ETH.';
|
||||
contextualInfo = t("mustBeETH");
|
||||
} else if (inputIsZero || outputIsZero) {
|
||||
contextualInfo = 'Amount cannot be zero.';
|
||||
contextualInfo = t("noZero");
|
||||
} else if (this.isUnapproved()) {
|
||||
contextualInfo = 'Please unlock token to continue.';
|
||||
contextualInfo = t("unlockTokenCont");
|
||||
} else if (!inputValue || !outputValue) {
|
||||
contextualInfo = `Enter a ${inputCurrency} or ${label} value to continue.`;
|
||||
contextualInfo = t("enterCurrencyOrLabelCont", {inputCurrency, label});
|
||||
}
|
||||
|
||||
return (
|
||||
<ContextualInfo
|
||||
key="context-info"
|
||||
openModalText={t("transactionDetails")}
|
||||
contextualInfo={contextualInfo}
|
||||
isError={isError}
|
||||
renderTransactionDetails={this.renderTransactionDetails}
|
||||
@ -436,7 +441,7 @@ class AddLiquidity extends Component {
|
||||
}
|
||||
|
||||
renderTransactionDetails = () => {
|
||||
const { selectors, exchangeAddresses: { fromToken }, account } = this.props;
|
||||
const { t, selectors, exchangeAddresses: { fromToken }, account } = this.props;
|
||||
const {
|
||||
inputValue,
|
||||
outputValue,
|
||||
@ -474,16 +479,17 @@ class AddLiquidity extends Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="pool__summary-item">You are adding between {b(`${+BN(inputValue).toFixed(7)} ETH`)} and {b(`${+minOutput.toFixed(7)} - ${+maxOutput.toFixed(7)} ${label}`)} into the liquidity pool.</div>
|
||||
<div className="pool__summary-item">You will mint {b(+liquidityMinted.toFixed(7))} liquidity tokens.</div>
|
||||
<div className="pool__summary-item">Current total supply of liquidity tokens is {b(+adjTotalSupply.toFixed(7))}</div>
|
||||
<div className="pool__summary-item">At current exchange rate, each pool token is worth {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH and {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
|
||||
<div className="pool__summary-modal__item">{t("youAreAdding")} {b(`${+BN(inputValue).toFixed(7)} ETH`)} {t("and")} {b(`${+minOutput.toFixed(7)} - ${+maxOutput.toFixed(7)} ${label}`)} {t("intoPool")}</div>
|
||||
<div className="pool__summary-modal__item">{t("youWillMint")} {b(+liquidityMinted.toFixed(7))} {t("liquidityTokens")}</div>
|
||||
<div className="pool__summary-modal__item">{t("totalSupplyIs")} {b(+adjTotalSupply.toFixed(7))}</div>
|
||||
<div className="pool__summary-modal__item">{t("tokenWorth")} {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH {t("and")} {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
t,
|
||||
isConnected,
|
||||
exchangeAddresses: { fromToken },
|
||||
selectors,
|
||||
@ -516,18 +522,18 @@ class AddLiquidity extends Component {
|
||||
? (
|
||||
<div className="pool__new-exchange-warning">
|
||||
<div className="pool__new-exchange-warning-text">
|
||||
🚰 You are the first person to add liquidity!
|
||||
🚰 {t("firstLiquidity")}
|
||||
</div>
|
||||
<div className="pool__new-exchange-warning-text">
|
||||
{`The initial exchange rate will be set based on your deposits. Please make sure that your ETH and ${label} deposits have the same fiat value.`}
|
||||
{ t("initialExchangeRate", { label }) }
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<ModeSelector title="Add Liquidity" />
|
||||
<ModeSelector title={t("addLiquidity")}/>
|
||||
<CurrencyInputPanel
|
||||
title="Deposit"
|
||||
title={t("deposit")}
|
||||
extraText={this.getBalance(inputCurrency)}
|
||||
onValueChange={this.onInputChange}
|
||||
selectedTokenAddress="ETH"
|
||||
@ -541,8 +547,8 @@ class AddLiquidity extends Component {
|
||||
</div>
|
||||
</OversizedPanel>
|
||||
<CurrencyInputPanel
|
||||
title="Deposit"
|
||||
description={this.isNewExchange() ? '(estimated)' : ''}
|
||||
title={t("deposit")}
|
||||
description={this.isNewExchange() ? `(${t("estimated")})` : ''}
|
||||
extraText={this.getBalance(outputCurrency)}
|
||||
selectedTokenAddress={outputCurrency}
|
||||
onCurrencySelected={currency => {
|
||||
@ -568,7 +574,7 @@ class AddLiquidity extends Component {
|
||||
disabled={!isValid}
|
||||
onClick={this.onAddLiquidity}
|
||||
>
|
||||
Add Liquidity
|
||||
{t("addLiquidity")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -588,7 +594,7 @@ export default connect(
|
||||
selectors: () => dispatch(selectors()),
|
||||
addPendingTx: id => dispatch(addPendingTx(id)),
|
||||
})
|
||||
)(AddLiquidity);
|
||||
)(withNamespaces()(AddLiquidity));
|
||||
|
||||
function b(text) {
|
||||
return <span className="swap__highlight-text">{text}</span>
|
||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import {selectors, addPendingTx} from "../../ducks/web3connect";
|
||||
import classnames from "classnames";
|
||||
import NavigationTabs from "../../components/NavigationTabs";
|
||||
@ -39,6 +40,7 @@ class CreateExchange extends Component {
|
||||
validate() {
|
||||
const { tokenAddress } = this.state;
|
||||
const {
|
||||
t,
|
||||
web3,
|
||||
account,
|
||||
selectors,
|
||||
@ -59,7 +61,7 @@ class CreateExchange extends Component {
|
||||
if (web3 && web3.utils && !web3.utils.isAddress(tokenAddress)) {
|
||||
return {
|
||||
isValid: false,
|
||||
errorMessage: 'Not a valid token address',
|
||||
errorMessage: t("invalidTokenAddress"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -74,15 +76,15 @@ class CreateExchange extends Component {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
errorMessage = `${label} Exchange already exists!`;
|
||||
errorMessage = t("exchangeExists", { label });
|
||||
}
|
||||
|
||||
if (!label) {
|
||||
errorMessage = 'Invalid symbol';
|
||||
errorMessage = t("invalidSymbol");
|
||||
}
|
||||
|
||||
if (!decimals) {
|
||||
errorMessage = 'Invalid decimals';
|
||||
errorMessage = t("invalidDecimals");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -141,7 +143,7 @@ class CreateExchange extends Component {
|
||||
if (!tokenAddress) {
|
||||
return (
|
||||
<div className="create-exchange__summary-panel">
|
||||
<div className="create-exchange__summary-text">Enter a token address to continue</div>
|
||||
<div className="create-exchange__summary-text">{this.props.t("enterTokenCont")}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -159,7 +161,7 @@ class CreateExchange extends Component {
|
||||
|
||||
render() {
|
||||
const { tokenAddress } = this.state;
|
||||
const { isConnected, account, selectors, web3 } = this.props;
|
||||
const { t, isConnected, account, selectors, web3 } = this.props;
|
||||
const { isValid, errorMessage } = this.validate();
|
||||
let label, decimals;
|
||||
|
||||
@ -181,9 +183,9 @@ class CreateExchange extends Component {
|
||||
'header--inactive': !isConnected,
|
||||
})}
|
||||
/>
|
||||
<ModeSelector title="Create Exchange" />
|
||||
<ModeSelector title={t("createExchange")} />
|
||||
<AddressInputPanel
|
||||
title="Token Address"
|
||||
title={t("tokenAddress")}
|
||||
value={tokenAddress}
|
||||
onChange={this.onChange}
|
||||
errorMessage={errorMessage}
|
||||
@ -191,11 +193,11 @@ class CreateExchange extends Component {
|
||||
<OversizedPanel hideBottom>
|
||||
<div className="pool__summary-panel">
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="pool__exchange-rate">Label</span>
|
||||
<span className="pool__exchange-rate">{t("label")}</span>
|
||||
<span>{label || ' - '}</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Decimals</span>
|
||||
<span className="swap__exchange-rate">{t("decimals")}</span>
|
||||
<span>{decimals || ' - '}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -209,7 +211,7 @@ class CreateExchange extends Component {
|
||||
disabled={!isValid}
|
||||
onClick={this.onCreateExchange}
|
||||
>
|
||||
Create Exchange
|
||||
{t("createExchange")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -232,5 +234,5 @@ export default withRouter(
|
||||
addExchange: opts => dispatch(addExchange(opts)),
|
||||
addPendingTx: id => dispatch(addPendingTx(id)),
|
||||
})
|
||||
)(CreateExchange)
|
||||
)(withNamespaces()(CreateExchange))
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import OversizedPanel from "../../components/OversizedPanel";
|
||||
import Dropdown from "../../assets/images/dropdown-blue.svg";
|
||||
import Modal from "../../components/Modal";
|
||||
@ -55,19 +56,19 @@ class ModeSelector extends Component {
|
||||
className="pool-modal__item"
|
||||
onClick={() => this.changeView(ADD)}
|
||||
>
|
||||
{ADD}
|
||||
{this.props.t("addLiquidity")}
|
||||
</div>
|
||||
<div
|
||||
className="pool-modal__item"
|
||||
onClick={() => this.changeView(REMOVE)}
|
||||
>
|
||||
{REMOVE}
|
||||
{this.props.t("removeLiquidity")}
|
||||
</div>
|
||||
<div
|
||||
className="pool-modal__item"
|
||||
onClick={() => this.changeView(CREATE)}
|
||||
>
|
||||
{CREATE}
|
||||
{this.props.t("createExchange")}
|
||||
</div>
|
||||
</div>
|
||||
</CSSTransitionGroup>
|
||||
@ -93,4 +94,4 @@ class ModeSelector extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(ModeSelector);
|
||||
export default withRouter(withNamespaces()(ModeSelector));
|
||||
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import classnames from "classnames";
|
||||
import { connect } from 'react-redux';
|
||||
import { BigNumber as BN } from 'bignumber.js';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import NavigationTabs from "../../components/NavigationTabs";
|
||||
import ModeSelector from "./ModeSelector";
|
||||
import CurrencyInputPanel from "../../components/CurrencyInputPanel";
|
||||
@ -40,7 +41,7 @@ class RemoveLiquidity extends Component {
|
||||
|
||||
validate() {
|
||||
const { tokenAddress, value } = this.state;
|
||||
const { account, selectors, exchangeAddresses: { fromToken }, web3 } = this.props;
|
||||
const { t, account, selectors, exchangeAddresses: { fromToken }, web3 } = this.props;
|
||||
const exchangeAddress = fromToken[tokenAddress];
|
||||
|
||||
if (!web3 || !exchangeAddress || !account || !value) {
|
||||
@ -54,7 +55,7 @@ class RemoveLiquidity extends Component {
|
||||
const { value: liquidityBalance, decimals: liquidityDecimals } = getBalance(account, exchangeAddress);
|
||||
|
||||
if (liquidityBalance.isLessThan(BN(value).multipliedBy(10 ** liquidityDecimals))) {
|
||||
return { isValid: false, errorMessage: 'Insufficient balance' };
|
||||
return { isValid: false, errorMessage: t("insufficientBalance") };
|
||||
}
|
||||
|
||||
return {
|
||||
@ -159,7 +160,7 @@ class RemoveLiquidity extends Component {
|
||||
};
|
||||
|
||||
renderSummary(errorMessage) {
|
||||
const { selectors, exchangeAddresses: { fromToken } } = this.props;
|
||||
const { t, selectors, exchangeAddresses: { fromToken } } = this.props;
|
||||
const {
|
||||
value: input,
|
||||
tokenAddress,
|
||||
@ -172,17 +173,18 @@ class RemoveLiquidity extends Component {
|
||||
contextualInfo = errorMessage;
|
||||
isError = true;
|
||||
} else if (!tokenAddress) {
|
||||
contextualInfo = 'Select a token to continue.';
|
||||
contextualInfo = t("selectTokenCont");
|
||||
} else if (inputIsZero) {
|
||||
contextualInfo = 'Amount cannot be zero.';
|
||||
contextualInfo = t("noZero");
|
||||
} else if (!input) {
|
||||
const { label } = selectors().getTokenBalance(tokenAddress, fromToken[tokenAddress]);
|
||||
contextualInfo = `Enter a ${label} value to continue.`;
|
||||
contextualInfo = t("enterLabelCont", { label });
|
||||
}
|
||||
|
||||
return (
|
||||
<ContextualInfo
|
||||
key="context-info"
|
||||
openModalText={t("transactionDetails")}
|
||||
contextualInfo={contextualInfo}
|
||||
isError={isError}
|
||||
renderTransactionDetails={this.renderTransactionDetails}
|
||||
@ -193,6 +195,7 @@ class RemoveLiquidity extends Component {
|
||||
renderTransactionDetails = () => {
|
||||
const { tokenAddress, value: input, totalSupply } = this.state;
|
||||
const {
|
||||
t,
|
||||
exchangeAddresses: { fromToken },
|
||||
web3,
|
||||
selectors,
|
||||
@ -228,16 +231,24 @@ class RemoveLiquidity extends Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<<<<<<< HEAD
|
||||
<div className="pool__summary-item">You are removing between {b(`${+BN(ethWithdrawn).toFixed(7)} ETH`)} and {b(`${+minTokenWithdrawn} - ${+maxTokenWithdrawn} ${label}`)} into the liquidity pool.</div>
|
||||
<div className="pool__summary-item">You will remove {b(+input)} liquidity tokens.</div>
|
||||
<div className="pool__summary-item">Current total supply of liquidity tokens is {b(+adjTotalSupply.toFixed(7))}</div>
|
||||
<div className="pool__summary-item">At current exchange rate, each pool token is worth {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH and {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
|
||||
=======
|
||||
<div className="pool__summary-modal__item">{t("youAreRemoving")} {b(`${+BN(ethWithdrawn).toFixed(7)} ETH`)} {t("and")} {b(`${+minTokenWithdrawn} - ${+maxTokenWithdrawn} ${label}`)} {t("outPool")}</div>
|
||||
<div className="pool__summary-modal__item">{t("youWillRemove")} {b(+input)} {t("liquidityTokens")}</div>
|
||||
<div className="pool__summary-modal__item">{t("totalSupplyIs")} {b(+adjTotalSupply.toFixed(7))}</div>
|
||||
<div className="pool__summary-modal__item">{t("tokenWorth")} {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH {t("and")} {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
|
||||
>>>>>>> 30eade0... i18n support
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderOutput() {
|
||||
const {
|
||||
t,
|
||||
exchangeAddresses: { fromToken },
|
||||
account,
|
||||
web3,
|
||||
@ -250,8 +261,8 @@ class RemoveLiquidity extends Component {
|
||||
const blank = [
|
||||
<CurrencyInputPanel
|
||||
key="remove-liquidity-input"
|
||||
title="Output"
|
||||
description="(estimated)"
|
||||
title={t("output")}
|
||||
description={`(${t("estimated")})`}
|
||||
renderInput={() => (
|
||||
<div className="remove-liquidity__output"></div>
|
||||
)}
|
||||
@ -261,15 +272,15 @@ class RemoveLiquidity extends Component {
|
||||
<OversizedPanel key="remove-liquidity-input-under" hideBottom>
|
||||
<div className="pool__summary-panel">
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="pool__exchange-rate">Exchange Rate</span>
|
||||
<span className="pool__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Current Pool Size</span>
|
||||
<span className="swap__exchange-rate">{t("currentPoolSize")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Your Pool Share</span>
|
||||
<span className="swap__exchange-rate">{t("yourPoolShare")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
</div>
|
||||
@ -299,8 +310,8 @@ class RemoveLiquidity extends Component {
|
||||
|
||||
return [
|
||||
<CurrencyInputPanel
|
||||
title="Output"
|
||||
description="(estimated)"
|
||||
title={t("output")}
|
||||
description={`(${t("estimated")})`}
|
||||
key="remove-liquidity-input"
|
||||
renderInput={() => input
|
||||
? (
|
||||
@ -322,18 +333,18 @@ class RemoveLiquidity extends Component {
|
||||
<OversizedPanel key="remove-liquidity-input-under" hideBottom>
|
||||
<div className="pool__summary-panel">
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="pool__exchange-rate">Exchange Rate</span>
|
||||
<span className="pool__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span>
|
||||
{`1 ETH = ${exchangeRate.toFixed(4)} ${label}`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Current Pool Size</span>
|
||||
<span className="swap__exchange-rate">{t("currentPoolSize")}</span>
|
||||
<span>{`${ethReserve.dividedBy(10 ** 18).toFixed(2)} ETH + ${tokenReserve.dividedBy(10 ** tokenDecimals).toFixed(2)} ${label}`}</span>
|
||||
</div>
|
||||
<div className="pool__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">
|
||||
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%)
|
||||
{t("yourPoolShare")} ({ownership.multipliedBy(100).toFixed(2)}%)
|
||||
</span>
|
||||
<span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
|
||||
</div>
|
||||
@ -343,7 +354,7 @@ class RemoveLiquidity extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isConnected } = this.props;
|
||||
const { t, isConnected } = this.props;
|
||||
const { tokenAddress, value } = this.state;
|
||||
const { isValid, errorMessage } = this.validate();
|
||||
|
||||
@ -359,9 +370,9 @@ class RemoveLiquidity extends Component {
|
||||
'header--inactive': !isConnected,
|
||||
})}
|
||||
/>
|
||||
<ModeSelector title="Remove Liquidity" />
|
||||
<ModeSelector title={t("removeLiquidity")} />
|
||||
<CurrencyInputPanel
|
||||
title="Pool Tokens"
|
||||
title={t("poolTokens")}
|
||||
extraText={this.getBalance(tokenAddress)}
|
||||
onValueChange={this.onInputChange}
|
||||
value={value}
|
||||
@ -386,7 +397,7 @@ class RemoveLiquidity extends Component {
|
||||
disabled={!isValid}
|
||||
onClick={this.onRemoveLiquidity}
|
||||
>
|
||||
Remove Liquidity
|
||||
{t("removeLiquidity")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -406,7 +417,7 @@ export default connect(
|
||||
selectors: () => dispatch(selectors()),
|
||||
addPendingTx: id => dispatch(addPendingTx(id)),
|
||||
})
|
||||
)(RemoveLiquidity);
|
||||
)(withNamespaces()(RemoveLiquidity));
|
||||
|
||||
function b(text) {
|
||||
return <span className="swap__highlight-text">{text}</span>
|
||||
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import {BigNumber as BN} from "bignumber.js";
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import { selectors, addPendingTx } from '../../ducks/web3connect';
|
||||
import Header from '../../components/Header';
|
||||
import NavigationTabs from '../../components/NavigationTabs';
|
||||
@ -87,11 +88,11 @@ class Send extends Component {
|
||||
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
|
||||
|
||||
if (inputBalance.isLessThan(BN(inputValue * 10 ** inputDecimals))) {
|
||||
inputError = 'Insufficient Balance';
|
||||
inputError = this.props.t("insufficientBalance");
|
||||
}
|
||||
|
||||
if (inputValue === 'N/A') {
|
||||
inputError = 'Not a valid input value';
|
||||
inputError = this.props.t("inputNotValid");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -535,7 +536,7 @@ class Send extends Component {
|
||||
outputCurrency,
|
||||
recipient,
|
||||
} = this.state;
|
||||
const { web3 } = this.props;
|
||||
const { t, web3 } = this.props;
|
||||
|
||||
const { selectors, account } = this.props;
|
||||
const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
|
||||
@ -551,24 +552,25 @@ class Send extends Component {
|
||||
contextualInfo = inputError || outputError;
|
||||
isError = true;
|
||||
} else if (!inputCurrency || !outputCurrency) {
|
||||
contextualInfo = 'Select a token to continue.';
|
||||
contextualInfo = t("selectTokenCont");
|
||||
} else if (inputCurrency === outputCurrency) {
|
||||
contextualInfo = 'Must be different token.';
|
||||
contextualInfo = t("differentToken");
|
||||
} else if (!inputValue || !outputValue) {
|
||||
const missingCurrencyValue = !inputValue ? inputLabel : outputLabel;
|
||||
contextualInfo = `Enter a ${missingCurrencyValue} value to continue.`;
|
||||
contextualInfo = t("enterValueCont", {missingCurrencyValue});
|
||||
} else if (inputIsZero || outputIsZero) {
|
||||
contextualInfo = 'No liquidity.';
|
||||
contextualInfo = t("noLiquidity");
|
||||
} else if (this.isUnapproved()) {
|
||||
contextualInfo = 'Please unlock token to continue.';
|
||||
contextualInfo = t("unlockTokenCont");
|
||||
} else if (!recipient) {
|
||||
contextualInfo = 'Enter a wallet address to send to.';
|
||||
contextualInfo = t("noRecipient");
|
||||
} else if (!validRecipientAddress) {
|
||||
contextualInfo = 'Please enter a valid wallet address recipient.';
|
||||
contextualInfo = t("invalidRecipient");
|
||||
}
|
||||
|
||||
return (
|
||||
<ContextualInfo
|
||||
openModalText={t("transactionDetails")}
|
||||
contextualInfo={contextualInfo}
|
||||
isError={isError}
|
||||
renderTransactionDetails={this.renderTransactionDetails}
|
||||
@ -586,7 +588,7 @@ class Send extends Component {
|
||||
inputAmountB,
|
||||
lastEditedField,
|
||||
} = this.state;
|
||||
const { selectors, account } = this.props;
|
||||
const { t, selectors, account } = this.props;
|
||||
|
||||
ReactGA.event({
|
||||
category: 'TransactionDetail',
|
||||
@ -641,10 +643,10 @@ class Send extends Component {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
You are selling {b(`${+inputValue} ${inputLabel}`)}.
|
||||
{t("youAreSending")} {b(`${+inputValue} ${inputLabel}`)}.
|
||||
</div>
|
||||
<div className="send__last-summary-text">
|
||||
{recipientText} will receive at least {b(`${+minOutput} ${outputLabel}`)} or the transaction will fail.
|
||||
{recipientText} {t("willReceive")} {b(`${+minOutput} ${outputLabel}`)} {t("orTransFail")}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -652,12 +654,12 @@ class Send extends Component {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
You are sending {b(`${+outputValue} ${outputLabel}`)} to {recipientText}.
|
||||
{t("youAreSending")} {b(`${+outputValue} ${outputLabel}`)} {t("to")} {recipientText}.
|
||||
{/*You are selling between {b(`${+inputValue} ${inputLabel}`)} to {b(`${+maxInput} ${inputLabel}`)}.*/}
|
||||
</div>
|
||||
<div className="send__last-summary-text">
|
||||
{/*{b(`${recipient.slice(0, 6)}...${recipient.slice(-4)}`)} will receive {b(`${+outputValue} ${outputLabel}`)}.*/}
|
||||
It will cost at most {b(`${+maxInput} ${inputLabel}`)} or the transaction will fail.
|
||||
{t("itWillCost")} {b(`${+maxInput} ${inputLabel}`)} {t("orTransFail")}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -665,7 +667,7 @@ class Send extends Component {
|
||||
}
|
||||
|
||||
renderExchangeRate() {
|
||||
const { account, selectors } = this.props;
|
||||
const { t, account, selectors } = this.props;
|
||||
const { exchangeRate, inputCurrency, outputCurrency } = this.state;
|
||||
const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
|
||||
const { label: outputLabel } = selectors().getBalance(account, outputCurrency);
|
||||
@ -674,7 +676,7 @@ class Send extends Component {
|
||||
return (
|
||||
<OversizedPanel hideBottom>
|
||||
<div className="swap__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Exchange Rate</span>
|
||||
<span className="swap__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
</OversizedPanel>
|
||||
@ -684,7 +686,7 @@ class Send extends Component {
|
||||
return (
|
||||
<OversizedPanel hideBottom>
|
||||
<div className="swap__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Exchange Rate</span>
|
||||
<span className="swap__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span>
|
||||
{`1 ${inputLabel} = ${exchangeRate.toFixed(7)} ${outputLabel}`}
|
||||
</span>
|
||||
@ -697,12 +699,12 @@ class Send extends Component {
|
||||
if (!currency || decimals === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `Balance: ${balance.dividedBy(BN(10 ** decimals)).toFixed(4)}`
|
||||
const balanceInput = balance.dividedBy(BN(10 ** decimals)).toFixed(4)
|
||||
return this.props.t("balance", { balanceInput })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectors, account } = this.props;
|
||||
const { t, selectors, account } = this.props;
|
||||
const {
|
||||
lastEditedField,
|
||||
inputCurrency,
|
||||
@ -711,7 +713,7 @@ class Send extends Component {
|
||||
outputValue,
|
||||
recipient,
|
||||
} = this.state;
|
||||
const estimatedText = '(estimated)';
|
||||
const estimatedText = `(${t("estimated")})`;
|
||||
|
||||
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
|
||||
const { value: outputBalance, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency);
|
||||
@ -733,7 +735,7 @@ class Send extends Component {
|
||||
})}
|
||||
/>
|
||||
<CurrencyInputPanel
|
||||
title="Input"
|
||||
title={t("input")}
|
||||
description={lastEditedField === OUTPUT ? estimatedText : ''}
|
||||
extraText={this.renderBalance(inputCurrency, inputBalance, inputDecimals)}
|
||||
onCurrencySelected={inputCurrency => this.setState({ inputCurrency }, this.recalcForm)}
|
||||
@ -749,7 +751,7 @@ class Send extends Component {
|
||||
</div>
|
||||
</OversizedPanel>
|
||||
<CurrencyInputPanel
|
||||
title="Output"
|
||||
title={t("output")}
|
||||
description={lastEditedField === INPUT ? estimatedText : ''}
|
||||
extraText={this.renderBalance(outputCurrency, outputBalance, outputDecimals)}
|
||||
onCurrencySelected={outputCurrency => this.setState({ outputCurrency }, this.recalcForm)}
|
||||
@ -766,6 +768,7 @@ class Send extends Component {
|
||||
</div>
|
||||
</OversizedPanel>
|
||||
<AddressInputPanel
|
||||
t={this.props.t}
|
||||
value={recipient}
|
||||
onChange={address => this.setState({recipient: address})}
|
||||
/>
|
||||
@ -779,7 +782,7 @@ class Send extends Component {
|
||||
disabled={!isValid}
|
||||
onClick={this.onSend}
|
||||
>
|
||||
Send
|
||||
{t("send")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -800,7 +803,7 @@ export default connect(
|
||||
selectors: () => dispatch(selectors()),
|
||||
addPendingTx: id => dispatch(addPendingTx(id)),
|
||||
}),
|
||||
)(Send);
|
||||
)(withNamespaces()(Send));
|
||||
|
||||
const b = text => <span className="swap__highlight-text">{text}</span>;
|
||||
|
||||
|
@ -5,6 +5,7 @@ import classnames from 'classnames';
|
||||
import {BigNumber as BN} from "bignumber.js";
|
||||
import MediaQuery from 'react-responsive';
|
||||
import ReactGA from 'react-ga';
|
||||
import { withNamespaces } from 'react-i18next';
|
||||
import { selectors, addPendingTx } from '../../ducks/web3connect';
|
||||
import Header from '../../components/Header';
|
||||
import NavigationTabs from '../../components/NavigationTabs';
|
||||
@ -84,11 +85,11 @@ class Swap extends Component {
|
||||
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
|
||||
|
||||
if (inputBalance.isLessThan(BN(inputValue * 10 ** inputDecimals))) {
|
||||
inputError = 'Insufficient Balance';
|
||||
inputError = this.props.t("insufficientBalance");
|
||||
}
|
||||
|
||||
if (inputValue === 'N/A') {
|
||||
inputError = 'Not a valid input value';
|
||||
inputError = this.props.t("inputNotValid");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -525,6 +526,7 @@ class Swap extends Component {
|
||||
outputValue,
|
||||
outputCurrency,
|
||||
} = this.state;
|
||||
const t = this.props.t;
|
||||
|
||||
const inputIsZero = BN(inputValue).isZero();
|
||||
const outputIsZero = BN(outputValue).isZero();
|
||||
@ -532,11 +534,11 @@ class Swap extends Component {
|
||||
let isError = false;
|
||||
|
||||
if (!inputCurrency || !outputCurrency) {
|
||||
contextualInfo = 'Select a token to continue.';
|
||||
contextualInfo = t("selectTokenCont");
|
||||
}
|
||||
|
||||
if (!inputValue || !outputValue) {
|
||||
contextualInfo = 'Enter a value to continue.';
|
||||
contextualInfo = t("enterValueCont");
|
||||
}
|
||||
|
||||
if (inputError || outputError) {
|
||||
@ -545,15 +547,16 @@ class Swap extends Component {
|
||||
}
|
||||
|
||||
if (inputIsZero || outputIsZero) {
|
||||
contextualInfo = 'No liquidity.';
|
||||
contextualInfo = t("noLiquidity");
|
||||
}
|
||||
|
||||
if (this.isUnapproved()) {
|
||||
contextualInfo = 'Please unlock token to continue.';
|
||||
contextualInfo = t("unlockTokenCont");
|
||||
}
|
||||
|
||||
return (
|
||||
<ContextualInfo
|
||||
openModalText={t("transactionDetails")}
|
||||
contextualInfo={contextualInfo}
|
||||
isError={isError}
|
||||
renderTransactionDetails={this.renderTransactionDetails}
|
||||
@ -569,7 +572,7 @@ class Swap extends Component {
|
||||
outputCurrency,
|
||||
lastEditedField,
|
||||
} = this.state;
|
||||
const { selectors, account } = this.props;
|
||||
const { t, selectors, account } = this.props;
|
||||
|
||||
ReactGA.event({
|
||||
category: 'TransactionDetail',
|
||||
@ -623,10 +626,10 @@ class Swap extends Component {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
You are selling {b(`${+inputValue} ${inputLabel}`)}.
|
||||
{t("youAreSelling")} {b(`${+inputValue} ${inputLabel}`)} {t("orTransFail")}
|
||||
</div>
|
||||
<div className="send__last-summary-text">
|
||||
You will receive at least {b(`${+minOutput} ${outputLabel}`)} or the transaction will fail.
|
||||
{t("youWillReceive")} {b(`${+minOutput} ${outputLabel}`)} {t("orTransFail")}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -634,10 +637,10 @@ class Swap extends Component {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
You are buying {b(`${+outputValue} ${outputLabel}`)}.
|
||||
{t("youAreBuying")} {b(`${+outputValue} ${outputLabel}`)}.
|
||||
</div>
|
||||
<div className="send__last-summary-text">
|
||||
It will cost at most {b(`${+maxInput} ${inputLabel}`)} or the transaction will fail.
|
||||
{t("itWillCost")} {b(`${+maxInput} ${inputLabel}`)} {t("orTransFail")}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -645,7 +648,7 @@ class Swap extends Component {
|
||||
}
|
||||
|
||||
renderExchangeRate() {
|
||||
const { account, selectors } = this.props;
|
||||
const { t, account, selectors } = this.props;
|
||||
const { exchangeRate, inputCurrency, outputCurrency } = this.state;
|
||||
const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
|
||||
const { label: outputLabel } = selectors().getBalance(account, outputCurrency);
|
||||
@ -654,7 +657,7 @@ class Swap extends Component {
|
||||
return (
|
||||
<OversizedPanel hideBottom>
|
||||
<div className="swap__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Exchange Rate</span>
|
||||
<span className="swap__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span> - </span>
|
||||
</div>
|
||||
</OversizedPanel>
|
||||
@ -664,7 +667,7 @@ class Swap extends Component {
|
||||
return (
|
||||
<OversizedPanel hideBottom>
|
||||
<div className="swap__exchange-rate-wrapper">
|
||||
<span className="swap__exchange-rate">Exchange Rate</span>
|
||||
<span className="swap__exchange-rate">{t("exchangeRate")}</span>
|
||||
<span>
|
||||
{`1 ${inputLabel} = ${exchangeRate.toFixed(7)} ${outputLabel}`}
|
||||
</span>
|
||||
@ -678,11 +681,12 @@ class Swap extends Component {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `Balance: ${balance.dividedBy(BN(10 ** decimals)).toFixed(4)}`
|
||||
const balanceInput = balance.dividedBy(BN(10 ** decimals)).toFixed(4)
|
||||
return this.props.t("balance", { balanceInput })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectors, account } = this.props;
|
||||
const { t, selectors, account } = this.props;
|
||||
const {
|
||||
lastEditedField,
|
||||
inputCurrency,
|
||||
@ -690,7 +694,7 @@ class Swap extends Component {
|
||||
inputValue,
|
||||
outputValue,
|
||||
} = this.state;
|
||||
const estimatedText = '(estimated)';
|
||||
const estimatedText = `(${t("estimated")})`;
|
||||
|
||||
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
|
||||
const { value: outputBalance, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency);
|
||||
@ -715,7 +719,7 @@ class Swap extends Component {
|
||||
})}
|
||||
/>
|
||||
<CurrencyInputPanel
|
||||
title="Input"
|
||||
title={t("input")}
|
||||
description={lastEditedField === OUTPUT ? estimatedText : ''}
|
||||
extraText={this.renderBalance(inputCurrency, inputBalance, inputDecimals)}
|
||||
onCurrencySelected={inputCurrency => this.setState({ inputCurrency }, this.recalcForm)}
|
||||
@ -731,7 +735,7 @@ class Swap extends Component {
|
||||
</div>
|
||||
</OversizedPanel>
|
||||
<CurrencyInputPanel
|
||||
title="Output"
|
||||
title={t("output")}
|
||||
description={lastEditedField === INPUT ? estimatedText : ''}
|
||||
extraText={this.renderBalance(outputCurrency, outputBalance, outputDecimals)}
|
||||
onCurrencySelected={outputCurrency => this.setState({ outputCurrency }, this.recalcForm)}
|
||||
@ -752,7 +756,7 @@ class Swap extends Component {
|
||||
disabled={!isValid}
|
||||
onClick={this.onSwap}
|
||||
>
|
||||
Swap
|
||||
{t("swap")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -773,7 +777,7 @@ export default connect(
|
||||
selectors: () => dispatch(selectors()),
|
||||
addPendingTx: id => dispatch(addPendingTx(id)),
|
||||
}),
|
||||
)(Swap);
|
||||
)(withNamespaces()(Swap));
|
||||
|
||||
const b = text => <span className="swap__highlight-text">{text}</span>;
|
||||
|
||||
|
82
yarn.lock
82
yarn.lock
@ -751,6 +751,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.12.0"
|
||||
|
||||
"@babel/runtime@^7.1.2":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz#b03e42eeddf5898e00646e4c840fa07ba8dcad7f"
|
||||
integrity sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.12.0"
|
||||
|
||||
"@babel/template@7.0.0-beta.44":
|
||||
version "7.0.0-beta.44"
|
||||
resolved "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f"
|
||||
@ -2994,6 +3001,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
create-react-context@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3"
|
||||
integrity sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==
|
||||
dependencies:
|
||||
fbjs "^0.8.0"
|
||||
gud "^1.0.0"
|
||||
|
||||
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
@ -4835,6 +4850,19 @@ fb-watchman@^2.0.0:
|
||||
dependencies:
|
||||
bser "^2.0.0"
|
||||
|
||||
fbjs@^0.8.0:
|
||||
version "0.8.17"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
|
||||
integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.18"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
@ -5522,6 +5550,11 @@ growly@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
|
||||
|
||||
gud@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
|
||||
integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==
|
||||
|
||||
gzip-size@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80"
|
||||
@ -5767,6 +5800,13 @@ hoek@4.x.x:
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
|
||||
integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==
|
||||
|
||||
hoist-non-react-statics@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.0.1.tgz#fba3e7df0210eb9447757ca1a7cb607162f0a364"
|
||||
integrity sha512-1kXwPsOi0OGQIZNVMPvgWJ9tSnGMiMfJdihqEzrPEXlHOBh9AAHXX/QYmAJTXztnz/K+PQ8ryCb4eGaN6HlGbQ==
|
||||
dependencies:
|
||||
react-is "^16.3.2"
|
||||
|
||||
hoist-non-react-statics@^2.5.0:
|
||||
version "2.5.5"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
|
||||
@ -5853,6 +5893,13 @@ html-minifier@^3.2.3:
|
||||
relateurl "0.2.x"
|
||||
uglify-js "3.3.x"
|
||||
|
||||
html-parse-stringify2@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
|
||||
integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
|
||||
dependencies:
|
||||
void-elements "^2.0.1"
|
||||
|
||||
html-webpack-plugin@4.0.0-alpha.2:
|
||||
version "4.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-alpha.2.tgz#7745967e389a57a098e26963f328ebe4c19b598d"
|
||||
@ -5966,6 +6013,21 @@ hyphenate-style-name@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
|
||||
integrity sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=
|
||||
|
||||
i18next-browser-languagedetector@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-2.2.4.tgz#b02412d7ab15d7d74e1b1317d67d8a244b219ee3"
|
||||
integrity sha512-wPbtH18FdOuB245I8Bhma5/XSDdN/HpYlX+wga1eMy+slhaFQSnrWX6fp+aYSL2eEuj0RlfHeEVz6Fo/lxAj6A==
|
||||
|
||||
i18next-xhr-backend@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz#50282610780c6a696d880dfa7f4ac1d01e8c3ad5"
|
||||
integrity sha512-9OLdC/9YxDvTFcgsH5t2BHCODHEotHCa6h7Ly0EUlUC7Y2GS09UeoHOGj3gWKQ3HCqXz8NlH4gOrK3NNc9vPuw==
|
||||
|
||||
i18next@^13.0.1:
|
||||
version "13.0.1"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-13.0.1.tgz#aac758333e01a712710a81447bf033e6a0dbb71c"
|
||||
integrity sha512-V9hnqoP7N7aHncb1FYvHcAgKiDTmVpNuIr70QGFTyyNUVlQwz2O393fM0x7JIm0/ZYsoKjZdwtlGKYO4aYJ79Q==
|
||||
|
||||
iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
@ -10374,6 +10436,16 @@ react-helmet@^5.2.0:
|
||||
prop-types "^15.5.4"
|
||||
react-side-effect "^1.1.0"
|
||||
|
||||
react-i18next@^8.4.0:
|
||||
version "8.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-8.4.0.tgz#e9f0c5b9938b155eaa6051360614719c08cae72f"
|
||||
integrity sha512-zIO/bc1L0UUGdaws2y40cTiSQHuQud5e9SSodYM6MTzhJTI3iayxCCdgvotblOLM4taOD77Ct2/fUbheQIhyeg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
create-react-context "0.2.3"
|
||||
hoist-non-react-statics "3.0.1"
|
||||
html-parse-stringify2 "2.0.1"
|
||||
|
||||
react-input-autosize@^2.1.2:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
|
||||
@ -10381,6 +10453,11 @@ react-input-autosize@^2.1.2:
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-is@^16.3.2:
|
||||
version "16.7.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa"
|
||||
integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g==
|
||||
|
||||
react-motion@^0.5.0:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
|
||||
@ -12964,6 +13041,11 @@ vm-browserify@0.0.4:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
void-elements@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
|
||||
|
||||
w3c-hr-time@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
|
||||
|
Loading…
Reference in New Issue
Block a user