Commit b38b41a1 authored by Ross Bulat's avatar Ross Bulat Committed by GitHub

Merge branch 'master' into remove-animated-switch

parents 60eab0eb 09d3a7ce
{
"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"
}
{
"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": "输入代币地址继续"
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1736 2036.92">
<defs>
<style>
.cls-2{fill:#fff}
</style>
<linearGradient id="linear-gradient" x1="868.25" y1="-1245.53" x2="868.25" y2="791.39" gradientTransform="translate(-.25 1245.53)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f9ba16"/>
<stop offset=".04" stop-color="#faa612"/>
<stop offset=".11" stop-color="#fc8b0c"/>
<stop offset=".19" stop-color="#fd7508"/>
<stop offset=".28" stop-color="#fe6404"/>
<stop offset=".4" stop-color="#ff5902"/>
<stop offset=".56" stop-color="#ff5200"/>
<stop offset="1" stop-color="#ff5000"/>
</linearGradient>
</defs>
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<path d="M1736 659l-148.2-256.1 17.6-82.9-134.9-137-111.9 15.4L1177.4 0h-310l-310 2.5-180.8 198-111.9-16.1-134.1 138.5 17.2 82.5L0 660.5 40.5 814l184 700.6a358.61 358.61 0 0 0 138.1 199.8s223.9 157.8 444.5 301a98.76 98.76 0 0 0 123.1 0c247.9-162.5 444.1-301.7 444.1-301.7a359 359 0 0 0 137.8-199.8l183.3-701z" fill="url(#linear-gradient)"/>
<path class="cls-2" d="M915.5 1213.3a266.26 266.26 0 0 0-35.9-13.3h-22.2a253.36 253.36 0 0 0-35.9 13.3l-54.9 23c-17.6 7.2-45.2 20.4-62.1 29.1L603.4 1318a19.39 19.39 0 0 0-2.5 35.9l87.5 62.1c15.4 10.8 39.8 29.8 53.8 42.3l24.8 21.2 51.7 45.2 23.3 20.8a40.33 40.33 0 0 0 51.7 0L918 1524l51.7-45.2 24.8-21.5c14.3-12.6 38.4-31.6 53.8-42.3l87.9-62.8a19 19 0 0 0-2.5-35.8l-102.2-51.3c-16.9-8.6-44.8-21.5-62.4-28.7l-53.6-23.1z"/>
<path class="cls-2" d="M1536.9 698.5l2.9-9a239.82 239.82 0 0 0-2.5-35.9 307.9 307.9 0 0 0-32.6-61.3l-56.7-83.6c-10.4-15.8-28.7-40.5-40.5-55.2l-76.1-94.7a259.16 259.16 0 0 0-22.6-26.5l-33.7 6.1-118.7 20.4-50.9 9.7a131.88 131.88 0 0 1-50.2-7.2l-92.2-29.8c-17.9-5.7-47.7-14-66-18.3a141.51 141.51 0 0 0-29.1 0 141.51 141.51 0 0 0-29.1 0c-18.3 4.3-48.1 12.6-66 18.3l-92.2 29.8a133.86 133.86 0 0 1-50.2 7.2l-51.3-9.7-117-22.6-33.7-6.1a259.16 259.16 0 0 0-22.6 26.5l-77.8 96.9c-11.8 14.7-30.1 39.5-40.5 55.2l-56.7 83.9a461.89 461.89 0 0 0-26.9 44.8 203.06 203.06 0 0 0-7.9 53.1l3.2 9a127.14 127.14 0 0 0 5.4 17.2 578.09 578.09 0 0 0 46.6 49.9l196.6 181.9a52.81 52.81 0 0 1 9.7 56L425 1082a101.22 101.22 0 0 0 0 63.9l6.5 17.9a172.65 172.65 0 0 0 53.1 74.6l31.2 25.5a59.06 59.06 0 0 0 57.4 6.8l111.6-53.1a284 284 0 0 0 56.3-37.7l89.3-80.7a35.89 35.89 0 0 0 2.4-50.7l-.6-.6L678 915.5a51.14 51.14 0 0 1-12.2-54.5l51.3-127a89.25 89.25 0 0 0 0-59.9 88.69 88.69 0 0 0-44.5-40.9l-245-92.6c-17.6-6.8-16.9-13.6 2.2-15.4l127-11.8a184.69 184.69 0 0 1 66.4 8.3l126.6 45.2a40 40 0 0 1 24.8 44.8L728.3 814c-4.3 18.3-8.6 38.7-10 45.2a35.78 35.78 0 0 0 31.2 18.3l88.3 17.2a204.2 204.2 0 0 0 67.1 0l80.7-16.9a35.71 35.71 0 0 0 31.2-18.7c0-6.5-5.7-26.5-10-44.8l-47-202.7a39.36 39.36 0 0 1 24.8-44.8l126.6-45.2a184.14 184.14 0 0 1 66.4-8.3l127 11.8c18.7 0 19.7 8.6 2.2 15.4l-244.7 92.9a88.54 88.54 0 0 0-44.5 40.2 89.25 89.25 0 0 0 0 59.9l53.1 127.4a51.39 51.39 0 0 1-12.9 54.2L904 1047.9a35.77 35.77 0 0 0 1.2 50.7l.6.6 89.7 79.6a285.94 285.94 0 0 0 56.3 35.9l111.6 53.1a59.06 59.06 0 0 0 57.4-6.8l31.2-25.5a173.23 173.23 0 0 0 53.1-74.6l6.5-17.9a101.22 101.22 0 0 0 0-63.9l-34.4-74.6a52.92 52.92 0 0 1 11.8-54.9l196.2-182.2a581.78 581.78 0 0 0 46.6-50.2 123.28 123.28 0 0 0 5.1-18.7z"/>
</g>
</g>
</svg>
<svg width="256" height="417" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid">
<path fill="#343434" d="M127.961 0l-2.795 9.5v275.668l2.795 2.79 127.962-75.638z"/>
<path fill="#8C8C8C" d="M127.962 0L0 212.32l127.962 75.639V154.158z"/>
<path fill="#3C3C3B" d="M127.961 312.187l-1.575 1.92v98.199l1.575 4.6L256 236.587z"/>
<path fill="#8C8C8C" d="M127.962 416.905v-104.72L0 236.585z"/>
<path fill="#141414" d="M127.961 287.958l127.96-75.637-127.96-58.162z"/>
<path fill="#393939" d="M0 212.32l127.96 75.638v-133.8z"/>
</svg>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 318.6 318.6" xml:space="preserve">
<style>
.st1{fill:#e4761b;stroke:#e4761b}.st1,.st10{stroke-linecap:round;stroke-linejoin:round}.st2{fill:#763d16;stroke:#763d16}.st2,.st3,.st4,.st5,.st6,.st7,.st8{stroke-linecap:round;stroke-linejoin:round}.st3{fill:#f6851b;stroke:#f6851b}.st4{fill:#e2761b;stroke:#e2761b}.st5{fill:#cd6116;stroke:#cd6116}.st6{fill:#c0ad9e;stroke:#c0ad9e}.st7{fill:#d7c1b3;stroke:#d7c1b3}.st8{fill:#e4751f;stroke:#e4751f}.st10{fill:#161616;stroke:#161616}
</style>
<path fill="#161616" stroke="#161616" d="M277.3 145.6l-5-3.6 8-7.3-6.1-4.8 8-6.1-5.3-4 8.4-40.8-12.6-37.9-81.1 30.3h-67.5L43 41.1 30.4 79l8.5 40.8-5.4 4 8 6.1-6.1 4.8 8 7.3-5 3.6 11.5 13.5-17.4 54.2 16.1 55.3 56.7-15.6 11 9 22.4 15.5H177l22.4-15.5 11-9 56.7 15.6 16.2-55.3-17.5-54.2z"/>
<path class="st1" d="M105.3 253l-56.7 15.6-16.1-55.3zm178-39.7l-16.2 55.3-56.7-15.6z"/>
<path class="st2" d="M265.8 159.1l-52.3-15.3 18.3-4.8zm-215.9 0L84 139l18.2 4.8zM43.4 142l-1.9-12.1L84 139z"/>
<path class="st2" d="M272.3 142l-40.5-3 42.4-9.1z"/>
<path class="st2" d="M272.3 142l-6.5 17.1-34-20.1zm-228.9 0l40.6-3-34.1 20.1zm188.4-3l45.1-19.2-2.7 10.1zM84 139l-42.5-9.1-2.6-10.1z"/>
<path class="st3" d="M124.1 71.4h67.5l-15.1 41.1z"/>
<path class="st3" d="M176.5 112.5h-37.3l-15.1-41.1z"/>
<path class="st2" d="M276.9 119.8L231.8 139l-.8-51.6zm-174.7 24L84 139l.7-51.6z"/>
<path class="st2" d="M84.7 87.4L84 139l-45.1-19.2zm146.3 0l.8 51.6-18.3 4.8z"/>
<path class="st1" d="M139.2 112.5L43 41.1l81.1 30.3z"/>
<path class="st4" d="M272.7 41.1l-96.2 71.4 15.1-41.1z"/>
<path class="st1" d="M210.4 253l26.5-39.7h46.4zM32.5 213.3h46.4l26.4 39.7z"/>
<path class="st3" d="M229.3 167.7l54 45.6h-46.4zm-142.9 0l-53.9 45.6 17.4-54.2zm-7.5 45.6H32.5l53.9-45.6z"/>
<path class="st3" d="M229.3 167.7l36.5-8.6 17.5 54.2z"/>
<path class="st2" d="M84.7 87.4l54.5 25.1-37 31.3zm128.8 56.4l-37-31.3L231 87.4zm52.3 15.3l6.5-17.1 5 3.6zm-215.9 0l-11.5-13.5 5-3.6zM272.3 142l1.9-12.1 6.1 4.8zm-228.9 0l-8-7.3 6.1-4.8z"/>
<path class="st2" d="M33.5 123.8l5.4-4 2.6 10.1zm248.7 0l-8 6.1 2.7-10.1z"/>
<path class="st3" d="M49.9 159.1l52.3-15.3-15.8 23.9zm215.9 0l-36.5 8.6-15.8-23.9z"/>
<path class="st2" d="M38.9 119.8L30.4 79l54.3 8.4zM231 87.4l54.3-8.4-8.4 40.8z"/>
<path class="st1" d="M102.2 143.8l37-31.3 3.4 57.7zm111.3 0l15.8 23.9-56.2 2.5zm-40.4 26.4l3.4-57.7 37 31.3z"/>
<path class="st1" d="M142.6 170.2l-56.2-2.5 15.8-23.9z"/>
<path class="st2" d="M272.7 41.1L285.3 79 231 87.4zM43 41.1l96.2 71.4-54.5-25.1zm188 46.3l-54.5 25.1 96.2-71.4z"/>
<path class="st2" d="M84.7 87.4L30.4 79 43 41.1z"/>
<path class="st5" d="M105.3 253l-26.4-39.7 31.1.4zm105.1 0l-4.7-39.3 31.2-.4z"/>
<path class="st3" d="M173.1 170.2h-30.5l-3.4-57.7z"/>
<path class="st3" d="M139.2 112.5h37.3l-3.4 57.7z"/>
<path class="st6" d="M116.3 262l-11-9 31.5 14.9zm62.6 5.9l31.5-14.9-11 9z"/>
<path class="st7" d="M136.6 258.6l.2 9.3-31.5-14.9zm42.6 0l31.2-5.6-31.5 14.9z"/>
<path class="st3" d="M86.4 167.7l23.6 46-31.1-.4zm150.5 45.6l-31.2.4 23.6-46z"/>
<path class="st8" d="M86.4 167.7l22.8 23.1.8 22.9zm142.9 0l-23.6 46 .9-22.9z"/>
<path class="st7" d="M105.3 253l33.9-16.5-2.6 22.1zm105.1 0l-31.2 5.6-2.7-22.1z"/>
<path class="st1" d="M139.2 236.5L105.3 253l4.7-39.3zm37.3 0l29.2-22.8 4.7 39.3z"/>
<path class="st5" d="M173.1 170.2l56.2-2.5-22.7 23.1zm-63.9 20.6l-22.8-23.1 56.2 2.5z"/>
<path class="st5" d="M142.6 170.2l-13.5 11.5-19.9 9.1zm64 20.6l-20-9.1-13.5-11.5z"/>
<path class="st3" d="M205.7 213.7l-27.4-14.6 28.3-8.3zm-95.7 0l-.8-22.9 28.2 8.3z"/>
<path d="M137.4 199.1l-28.2-8.3 19.9-9.1zm40.9 0l8.3-17.4 20 9.1z" fill="#233447" stroke="#233447" stroke-linecap="round" stroke-linejoin="round"/>
<path class="st5" d="M186.6 181.7l-8.3 17.4-5.2-28.9zm-57.5 0l13.5-11.5-5.2 28.9z"/>
<path class="st6" d="M199.4 262L177 277.5l1.9-9.6zm-62.6 5.9l1.9 9.6-22.4-15.5z"/>
<path class="st4" d="M178.3 199.1l-6.5-10.7 1.3-18.2z"/>
<path class="st8" d="M137.4 199.1l5.2-28.9 1.3 18.2z"/>
<path class="st3" d="M173.1 170.2l-1.3 18.2h-27.9z"/>
<path class="st3" d="M143.9 188.4l-1.3-18.2h30.5zm34.4 10.7l27.4 14.6-29.2 22.8zm-39.1 37.4L110 213.7l27.4-14.6z"/>
<path class="st3" d="M137.4 199.1l6.6 34.1-4.8 3.3zm39.1 37.4l-4.8-3.3 6.6-34.1z"/>
<path class="st8" d="M171.8 188.4l6.5 10.7-6.6 34.1zm-27.9 0l.1 44.8-6.6-34.1z"/>
<path class="st3" d="M143.9 188.4h27.9l-.1 44.8zm27.8 44.8H144l-.1-44.8z"/>
<path class="st6" d="M179.2 258.6l-.3 9.3-1.9 9.6zm-40.5 18.9l-1.9-9.6-.2-9.3z"/>
<path class="st6" d="M136.6 258.6l2.4-2.2-.3 21.1zm40.4 18.9l-.3-21.1 2.5 2.2z"/>
<path class="st6" d="M138.7 277.5l.3-21.1h37.7zm38-21.1l.3 21.1h-38.3z"/>
<path class="st10" d="M176.5 236.5l2.7 22.1-2.5-2.2zM139 256.4l-2.4 2.2 2.6-22.1zm.2-19.9l1.5 4.7-1.7 15.2z"/>
<path class="st10" d="M176.7 256.4l-1.7-15.2 1.5-4.7zm-33-18.7l-3 3.5-1.5-4.7z"/>
<path class="st10" d="M176.5 236.5l-1.5 4.7-3-3.5z"/>
<path class="st10" d="M172 237.7l-.3-4.5 4.8 3.3zm-32.8-1.2l4.8-3.3-.3 4.5z"/>
<path class="st10" d="M171.7 233.2l.3 4.5h-28.3z"/>
<path class="st10" d="M143.7 237.7l.3-4.5h27.7zm-3 3.5H175l1.7 15.2z"/>
<path class="st10" d="M176.7 256.4H139l1.7-15.2zm-36-15.2l3-3.5H172z"/>
<path class="st10" d="M172 237.7l3 3.5h-34.3z"/>
</svg>
...@@ -20,6 +20,7 @@ class AddressInputPanel extends Component { ...@@ -20,6 +20,7 @@ class AddressInputPanel extends Component {
render() { render() {
const { const {
t,
title, title,
onChange, onChange,
value, value,
...@@ -34,7 +35,7 @@ class AddressInputPanel extends Component { ...@@ -34,7 +35,7 @@ class AddressInputPanel extends Component {
<div className="address-input-panel__input-container"> <div className="address-input-panel__input-container">
<div className="currency-input-panel__label-row"> <div className="currency-input-panel__label-row">
<div className="currency-input-panel__label-container"> <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> </div>
<div className="currency-input-panel__input-row"> <div className="currency-input-panel__input-row">
......
...@@ -35,7 +35,7 @@ class ContextualInfo extends Component { ...@@ -35,7 +35,7 @@ class ContextualInfo extends Component {
<div className="contextual-info__details"> <div className="contextual-info__details">
{this.props.renderTransactionDetails()} {this.props.renderTransactionDetails()}
</div> </div>
) );
} }
render() { render() {
......
...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; ...@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { CSSTransitionGroup } from "react-transition-group"; import { CSSTransitionGroup } from "react-transition-group";
import classnames from 'classnames'; import classnames from 'classnames';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withNamespaces } from 'react-i18next';
import Fuse from '../../helpers/fuse'; import Fuse from '../../helpers/fuse';
import Modal from '../Modal'; import Modal from '../Modal';
import TokenLogo from '../TokenLogo'; import TokenLogo from '../TokenLogo';
...@@ -105,6 +106,7 @@ class CurrencyInputPanel extends Component { ...@@ -105,6 +106,7 @@ class CurrencyInputPanel extends Component {
const tokens = this.createTokenList(); const tokens = this.createTokenList();
const { loadingExchange, searchQuery } = this.state; const { loadingExchange, searchQuery } = this.state;
const { const {
t,
selectedTokens, selectedTokens,
disableTokenSelect, disableTokenSelect,
web3, web3,
...@@ -160,7 +162,7 @@ class CurrencyInputPanel extends Component { ...@@ -160,7 +162,7 @@ class CurrencyInputPanel extends Component {
const { label } = selectors().getBalance(account, searchQuery); const { label } = selectors().getBalance(account, searchQuery);
return [ return [
<div key="token-modal-no-exchange" className="token-modal__token-row token-modal__token-row--no-exchange"> <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>,
<div <div
key="token-modal-create-exchange" key="token-modal-create-exchange"
...@@ -178,7 +180,7 @@ class CurrencyInputPanel extends Component { ...@@ -178,7 +180,7 @@ class CurrencyInputPanel extends Component {
if (!results.length) { if (!results.length) {
return ( return (
<div className="token-modal__token-row token-modal__token-row--no-exchange"> <div className="token-modal__token-row token-modal__token-row--no-exchange">
<div>No Exchange Found</div> <div>{t("noExchange")}</div>
</div> </div>
) )
} }
...@@ -222,7 +224,7 @@ class CurrencyInputPanel extends Component { ...@@ -222,7 +224,7 @@ class CurrencyInputPanel extends Component {
<div className="token-modal__search-container"> <div className="token-modal__search-container">
<input <input
type="text" type="text"
placeholder="Search Token or Paste Address" placeholder={this.props.t("searchOrPaste")}
className="token-modal__search-input" className="token-modal__search-input"
onChange={e => { onChange={e => {
this.setState({ searchQuery: e.target.value }); this.setState({ searchQuery: e.target.value });
...@@ -241,6 +243,7 @@ class CurrencyInputPanel extends Component { ...@@ -241,6 +243,7 @@ class CurrencyInputPanel extends Component {
renderUnlockButton() { renderUnlockButton() {
const { const {
t,
selectors, selectors,
selectedTokenAddress, selectedTokenAddress,
account, account,
...@@ -276,7 +279,7 @@ class CurrencyInputPanel extends Component { ...@@ -276,7 +279,7 @@ class CurrencyInputPanel extends Component {
className='currency-input-panel__sub-currency-select currency-input-panel__sub-currency-select--pending' className='currency-input-panel__sub-currency-select currency-input-panel__sub-currency-select--pending'
> >
<div className="loader" /> <div className="loader" />
Pending {t("pending")}
</button> </button>
); );
} }
...@@ -296,13 +299,14 @@ class CurrencyInputPanel extends Component { ...@@ -296,13 +299,14 @@ class CurrencyInputPanel extends Component {
}); });
}} }}
> >
Unlock {t("unlock")}
</button> </button>
); );
} }
renderInput() { renderInput() {
const { const {
t,
errorMessage, errorMessage,
value, value,
onValueChange, onValueChange,
...@@ -358,7 +362,7 @@ class CurrencyInputPanel extends Component { ...@@ -358,7 +362,7 @@ class CurrencyInputPanel extends Component {
) )
: null : null
} }
{ TOKEN_ADDRESS_TO_LABEL[selectedTokenAddress] || 'Select a token' } { TOKEN_ADDRESS_TO_LABEL[selectedTokenAddress] || t("selectToken") }
<span className="currency-input-panel__dropdown-icon" /> <span className="currency-input-panel__dropdown-icon" />
</button> </button>
</div> </div>
...@@ -416,5 +420,5 @@ export default withRouter( ...@@ -416,5 +420,5 @@ export default withRouter(
addPendingTx: opts => dispatch(addPendingTx(opts)), addPendingTx: opts => dispatch(addPendingTx(opts)),
addApprovalTx: opts => dispatch(addApprovalTx(opts)), addApprovalTx: opts => dispatch(addApprovalTx(opts)),
}), }),
)(CurrencyInputPanel) )(withNamespaces()(CurrencyInputPanel))
); );
...@@ -3,11 +3,12 @@ import PropTypes from 'prop-types'; ...@@ -3,11 +3,12 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import classnames from 'classnames'; import classnames from 'classnames';
import UAParser from 'ua-parser-js'; import UAParser from 'ua-parser-js';
import { withNamespaces } from 'react-i18next';
import Logo from '../Logo'; import Logo from '../Logo';
import CoinbaseWalletLogo from '../../assets/images/coinbase-wallet-logo.png'; import CoinbaseWalletLogo from '../../assets/images/coinbase-wallet-logo.png';
import TrustLogo from '../../assets/images/trust-wallet-logo.svg'; import TrustLogo from '../../assets/images/trust-wallet-logo.svg';
import BraveLogo from '../../assets/images/brave-logo.png'; import BraveLogo from '../../assets/images/brave-logo.svg';
import MetamaskLogo from '../../assets/images/metamask-logo.png'; import MetamaskLogo from '../../assets/images/metamask-logo.svg';
import Web3Status from '../Web3Status'; import Web3Status from '../Web3Status';
import "./header.scss"; import "./header.scss";
...@@ -77,6 +78,7 @@ function isMobile() { ...@@ -77,6 +78,7 @@ function isMobile() {
class BlockingWarning extends Component { class BlockingWarning extends Component {
render () { render () {
const { const {
t,
isConnected, isConnected,
initialized, initialized,
networkId, networkId,
...@@ -90,21 +92,21 @@ class BlockingWarning extends Component { ...@@ -90,21 +92,21 @@ class BlockingWarning extends Component {
if (wrongNetwork && initialized) { if (wrongNetwork && initialized) {
content = [ 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"> <div key="warning-desc" className="header__dialog__description">
{`Please switch to ${correctNetwork}`} {t("switchNetwork", {correctNetwork})}
</div>, </div>,
]; ];
} }
if (!isConnected && initialized) { if (!isConnected && initialized) {
content = [ 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"> <div key="warning-desc" className="header__dialog__description">
{ {
isMobile() isMobile()
? 'Please visit us from a web3-enabled mobile browser such as Trust Wallet or Coinbase Wallet.' ? t("installWeb3MobileBrowser")
: 'Please visit us after installing Metamask on Chrome or Brave.' : t("installMetamask")
} }
</div>, </div>,
<div key="warning-logos" className="header__download"> <div key="warning-logos" className="header__download">
...@@ -171,4 +173,4 @@ export default connect( ...@@ -171,4 +173,4 @@ export default connect(
web3: state.web3connect.web3, web3: state.web3connect.web3,
networkId: state.web3connect.networkId, networkId: state.web3connect.networkId,
}), }),
)(Header); )(withNamespaces()(Header));
...@@ -2,6 +2,7 @@ import React, { Component } from 'react'; ...@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withNamespaces } from 'react-i18next';
import { dismissBetaMessage } from '../../ducks/app'; import { dismissBetaMessage } from '../../ducks/app';
import {Tab, Tabs} from "../Tab"; import {Tab, Tabs} from "../Tab";
...@@ -38,18 +39,18 @@ class NavigationTabs extends Component { ...@@ -38,18 +39,18 @@ class NavigationTabs extends Component {
} }
render() { render() {
const { showBetaMessage, className, dismissBetaMessage } = this.props; const { t, showBetaMessage, className, dismissBetaMessage } = this.props;
return ( return (
<div> <div>
<Tabs className={className}> <Tabs className={className}>
{ this.renderTab('Swap', '/swap', /swap/) } { this.renderTab(t("swap"), '/swap', /swap/) }
{ this.renderTab('Send', '/send', /send/) } { this.renderTab(t("send"), '/send', /send/) }
{ this.renderTab('Pool', '/add-liquidity', /add-liquidity|remove-liquidity|create-exchange/) } { this.renderTab(t("pool"), '/add-liquidity', /add-liquidity|remove-liquidity|create-exchange/) }
</Tabs> </Tabs>
{ {
showBetaMessage && ( showBetaMessage && (
<div className="beta-message" onClick={dismissBetaMessage}> <div className="beta-message" onClick={dismissBetaMessage}>
💀 This project is in beta. Use at your own risk. 💀 {t("betaWarning")}
</div> </div>
) )
} }
...@@ -66,5 +67,5 @@ export default withRouter( ...@@ -66,5 +67,5 @@ export default withRouter(
dispatch => ({ dispatch => ({
dismissBetaMessage: () => dispatch(dismissBetaMessage()), dismissBetaMessage: () => dispatch(dismissBetaMessage()),
}), }),
)(NavigationTabs) )(withNamespaces()(NavigationTabs))
); );
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import EthereumLogo from '../../assets/images/ethereum-logo.png'; import EthereumLogo from '../../assets/images/ethereum-logo.svg';
import GenericTokenLogo from '../../assets/images/generic-token-logo.png'; import GenericTokenLogo from '../../assets/images/generic-token-logo.png';
const RINKEBY_TOKEN_MAP = { const RINKEBY_TOKEN_MAP = {
......
...@@ -5,6 +5,7 @@ import classnames from 'classnames'; ...@@ -5,6 +5,7 @@ import classnames from 'classnames';
import Web3 from 'web3'; import Web3 from 'web3';
import Jazzicon from 'jazzicon'; import Jazzicon from 'jazzicon';
import { CSSTransitionGroup } from "react-transition-group"; import { CSSTransitionGroup } from "react-transition-group";
import { withNamespaces } from 'react-i18next';
import './web3-status.scss'; import './web3-status.scss';
import Modal from '../Modal'; import Modal from '../Modal';
...@@ -35,7 +36,7 @@ class Web3Status extends Component { ...@@ -35,7 +36,7 @@ class Web3Status extends Component {
{transaction} {transaction}
</div> </div>
<div className="pending-modal__pending-indicator"> <div className="pending-modal__pending-indicator">
<div className="loader" /> Pending <div className="loader" /> {this.props.t("pending")}
</div> </div>
</div> </div>
); );
...@@ -69,7 +70,7 @@ class Web3Status extends Component { ...@@ -69,7 +70,7 @@ class Web3Status extends Component {
} }
render() { render() {
const { address, pending, confirmed } = this.props; const { t, address, pending, confirmed } = this.props;
const hasPendingTransactions = !!pending.length; const hasPendingTransactions = !!pending.length;
const hasConfirmedTransactions = !!confirmed.length; const hasConfirmedTransactions = !!confirmed.length;
...@@ -83,7 +84,7 @@ class Web3Status extends Component { ...@@ -83,7 +84,7 @@ class Web3Status extends Component {
onClick={this.handleClick} onClick={this.handleClick}
> >
<div className="web3-status__text"> <div className="web3-status__text">
{ hasPendingTransactions ? getPendingText(pending) : getText(address) } {hasPendingTransactions ? getPendingText(pending, t("pending")) : getText(address, t("disconnected")) }
</div> </div>
<div <div
className="web3-status__identicon" className="web3-status__identicon"
...@@ -108,18 +109,18 @@ class Web3Status extends Component { ...@@ -108,18 +109,18 @@ class Web3Status extends Component {
function getPendingText(pendingTransactions) { function getPendingText(pendingTransactions, pendingLabel) {
return ( return (
<div className="web3-status__pending-container"> <div className="web3-status__pending-container">
<div className="loader" /> <div className="loader" />
<span key="text">{pendingTransactions.length} Pending</span> <span key="text">{pendingTransactions.length} {pendingLabel}</span>
</div> </div>
); );
} }
function getText(text) { function getText(text, disconnectedText) {
if (!text || text.length < 42 || !Web3.utils.isHexStrict(text)) { if (!text || text.length < 42 || !Web3.utils.isHexStrict(text)) {
return 'Disconnected'; return disconnectedText;
} }
const address = Web3.utils.toChecksumAddress(text); const address = Web3.utils.toChecksumAddress(text);
...@@ -145,4 +146,4 @@ export default connect( ...@@ -145,4 +146,4 @@ export default connect(
confirmed: state.web3connect.transactions.confirmed, confirmed: state.web3connect.transactions.confirmed,
}; };
} }
)(Web3Status); )(withNamespaces()(Web3Status));
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'; ...@@ -2,6 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import ReactGA from 'react-ga'; import ReactGA from 'react-ga';
import './i18n';
import App from './pages/App'; import App from './pages/App';
import store from './store'; import store from './store';
......
...@@ -4,12 +4,9 @@ ...@@ -4,12 +4,9 @@
&__wrapper { &__wrapper {
height: 100%; height: 100%;
position: relative; position: relative;
margin: auto;
@media only screen and (min-width : 768px) { max-width: 560px;
margin: auto; width: 100%;
max-width: 560px;
width: 100%;
}
& > div { & > div {
position: absolute; position: absolute;
...@@ -24,6 +21,6 @@ ...@@ -24,6 +21,6 @@
#app-container { #app-container {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
@extend %col-nowrap; @extend %col-nowrap;
} }
\ No newline at end of file
This diff is collapsed.
...@@ -2,6 +2,7 @@ import React, { Component } from 'react'; ...@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withNamespaces } from 'react-i18next';
import {selectors, addPendingTx} from "../../ducks/web3connect"; import {selectors, addPendingTx} from "../../ducks/web3connect";
import classnames from "classnames"; import classnames from "classnames";
import NavigationTabs from "../../components/NavigationTabs"; import NavigationTabs from "../../components/NavigationTabs";
...@@ -39,6 +40,7 @@ class CreateExchange extends Component { ...@@ -39,6 +40,7 @@ class CreateExchange extends Component {
validate() { validate() {
const { tokenAddress } = this.state; const { tokenAddress } = this.state;
const { const {
t,
web3, web3,
account, account,
selectors, selectors,
...@@ -59,7 +61,7 @@ class CreateExchange extends Component { ...@@ -59,7 +61,7 @@ class CreateExchange extends Component {
if (web3 && web3.utils && !web3.utils.isAddress(tokenAddress)) { if (web3 && web3.utils && !web3.utils.isAddress(tokenAddress)) {
return { return {
isValid: false, isValid: false,
errorMessage: 'Not a valid token address', errorMessage: t("invalidTokenAddress"),
}; };
} }
...@@ -74,15 +76,15 @@ class CreateExchange extends Component { ...@@ -74,15 +76,15 @@ class CreateExchange extends Component {
} }
}); });
} else { } else {
errorMessage = `${label} Exchange already exists!`; errorMessage = t("exchangeExists", { label });
} }
if (!label) { if (!label) {
errorMessage = 'Invalid symbol'; errorMessage = t("invalidSymbol");
} }
if (!decimals) { if (!decimals) {
errorMessage = 'Invalid decimals'; errorMessage = t("invalidDecimals");
} }
return { return {
...@@ -141,7 +143,7 @@ class CreateExchange extends Component { ...@@ -141,7 +143,7 @@ class CreateExchange extends Component {
if (!tokenAddress) { if (!tokenAddress) {
return ( return (
<div className="create-exchange__summary-panel"> <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> </div>
) )
} }
...@@ -159,7 +161,7 @@ class CreateExchange extends Component { ...@@ -159,7 +161,7 @@ class CreateExchange extends Component {
render() { render() {
const { tokenAddress } = this.state; const { tokenAddress } = this.state;
const { isConnected, account, selectors, web3 } = this.props; const { t, isConnected, account, selectors, web3 } = this.props;
const { isValid, errorMessage } = this.validate(); const { isValid, errorMessage } = this.validate();
let label, decimals; let label, decimals;
...@@ -183,7 +185,7 @@ class CreateExchange extends Component { ...@@ -183,7 +185,7 @@ class CreateExchange extends Component {
/> />
<ModeSelector title={t("createExchange")} /> <ModeSelector title={t("createExchange")} />
<AddressInputPanel <AddressInputPanel
title="Token Address" title={t("tokenAddress")}
value={tokenAddress} value={tokenAddress}
onChange={this.onChange} onChange={this.onChange}
errorMessage={errorMessage} errorMessage={errorMessage}
...@@ -191,11 +193,11 @@ class CreateExchange extends Component { ...@@ -191,11 +193,11 @@ class CreateExchange extends Component {
<OversizedPanel hideBottom> <OversizedPanel hideBottom>
<div className="pool__summary-panel"> <div className="pool__summary-panel">
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="pool__exchange-rate">Label</span> <span className="pool__exchange-rate">{t("label")}</span>
<span>{label || ' - '}</span> <span>{label || ' - '}</span>
</div> </div>
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate">Decimals</span> <span className="swap__exchange-rate">{t("decimals")}</span>
<span>{decimals || ' - '}</span> <span>{decimals || ' - '}</span>
</div> </div>
</div> </div>
...@@ -209,7 +211,7 @@ class CreateExchange extends Component { ...@@ -209,7 +211,7 @@ class CreateExchange extends Component {
disabled={!isValid} disabled={!isValid}
onClick={this.onCreateExchange} onClick={this.onCreateExchange}
> >
Create Exchange {t("createExchange")}
</button> </button>
</div> </div>
</div> </div>
...@@ -232,5 +234,5 @@ export default withRouter( ...@@ -232,5 +234,5 @@ export default withRouter(
addExchange: opts => dispatch(addExchange(opts)), addExchange: opts => dispatch(addExchange(opts)),
addPendingTx: id => dispatch(addPendingTx(id)), addPendingTx: id => dispatch(addPendingTx(id)),
}) })
)(CreateExchange) )(withNamespaces()(CreateExchange))
); );
import React, { Component } from 'react'; import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withNamespaces } from 'react-i18next';
import OversizedPanel from "../../components/OversizedPanel"; import OversizedPanel from "../../components/OversizedPanel";
import Dropdown from "../../assets/images/dropdown-blue.svg"; import Dropdown from "../../assets/images/dropdown-blue.svg";
import Modal from "../../components/Modal"; import Modal from "../../components/Modal";
...@@ -55,19 +56,19 @@ class ModeSelector extends Component { ...@@ -55,19 +56,19 @@ class ModeSelector extends Component {
className="pool-modal__item" className="pool-modal__item"
onClick={() => this.changeView(ADD)} onClick={() => this.changeView(ADD)}
> >
{ADD} {this.props.t("addLiquidity")}
</div> </div>
<div <div
className="pool-modal__item" className="pool-modal__item"
onClick={() => this.changeView(REMOVE)} onClick={() => this.changeView(REMOVE)}
> >
{REMOVE} {this.props.t("removeLiquidity")}
</div> </div>
<div <div
className="pool-modal__item" className="pool-modal__item"
onClick={() => this.changeView(CREATE)} onClick={() => this.changeView(CREATE)}
> >
{CREATE} {this.props.t("createExchange")}
</div> </div>
</div> </div>
</CSSTransitionGroup> </CSSTransitionGroup>
...@@ -93,4 +94,4 @@ class ModeSelector extends Component { ...@@ -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'; ...@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import classnames from "classnames"; import classnames from "classnames";
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { BigNumber as BN } from 'bignumber.js'; import { BigNumber as BN } from 'bignumber.js';
import { withNamespaces } from 'react-i18next';
import NavigationTabs from "../../components/NavigationTabs"; import NavigationTabs from "../../components/NavigationTabs";
import ModeSelector from "./ModeSelector"; import ModeSelector from "./ModeSelector";
import CurrencyInputPanel from "../../components/CurrencyInputPanel"; import CurrencyInputPanel from "../../components/CurrencyInputPanel";
...@@ -40,7 +41,7 @@ class RemoveLiquidity extends Component { ...@@ -40,7 +41,7 @@ class RemoveLiquidity extends Component {
validate() { validate() {
const { tokenAddress, value } = this.state; 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]; const exchangeAddress = fromToken[tokenAddress];
if (!web3 || !exchangeAddress || !account || !value) { if (!web3 || !exchangeAddress || !account || !value) {
...@@ -54,7 +55,7 @@ class RemoveLiquidity extends Component { ...@@ -54,7 +55,7 @@ class RemoveLiquidity extends Component {
const { value: liquidityBalance, decimals: liquidityDecimals } = getBalance(account, exchangeAddress); const { value: liquidityBalance, decimals: liquidityDecimals } = getBalance(account, exchangeAddress);
if (liquidityBalance.isLessThan(BN(value).multipliedBy(10 ** liquidityDecimals))) { if (liquidityBalance.isLessThan(BN(value).multipliedBy(10 ** liquidityDecimals))) {
return { isValid: false, errorMessage: 'Insufficient balance' }; return { isValid: false, errorMessage: t("insufficientBalance") };
} }
return { return {
...@@ -159,7 +160,7 @@ class RemoveLiquidity extends Component { ...@@ -159,7 +160,7 @@ class RemoveLiquidity extends Component {
}; };
renderSummary(errorMessage) { renderSummary(errorMessage) {
const { selectors, exchangeAddresses: { fromToken } } = this.props; const { t, selectors, exchangeAddresses: { fromToken } } = this.props;
const { const {
value: input, value: input,
tokenAddress, tokenAddress,
...@@ -172,17 +173,18 @@ class RemoveLiquidity extends Component { ...@@ -172,17 +173,18 @@ class RemoveLiquidity extends Component {
contextualInfo = errorMessage; contextualInfo = errorMessage;
isError = true; isError = true;
} else if (!tokenAddress) { } else if (!tokenAddress) {
contextualInfo = 'Select a token to continue.'; contextualInfo = t("selectTokenCont");
} else if (inputIsZero) { } else if (inputIsZero) {
contextualInfo = 'Amount cannot be zero.'; contextualInfo = t("noZero");
} else if (!input) { } else if (!input) {
const { label } = selectors().getTokenBalance(tokenAddress, fromToken[tokenAddress]); const { label } = selectors().getTokenBalance(tokenAddress, fromToken[tokenAddress]);
contextualInfo = `Enter a ${label} value to continue.`; contextualInfo = t("enterLabelCont", { label });
} }
return ( return (
<ContextualInfo <ContextualInfo
key="context-info" key="context-info"
openModalText={t("transactionDetails")}
contextualInfo={contextualInfo} contextualInfo={contextualInfo}
isError={isError} isError={isError}
renderTransactionDetails={this.renderTransactionDetails} renderTransactionDetails={this.renderTransactionDetails}
...@@ -193,6 +195,7 @@ class RemoveLiquidity extends Component { ...@@ -193,6 +195,7 @@ class RemoveLiquidity extends Component {
renderTransactionDetails = () => { renderTransactionDetails = () => {
const { tokenAddress, value: input, totalSupply } = this.state; const { tokenAddress, value: input, totalSupply } = this.state;
const { const {
t,
exchangeAddresses: { fromToken }, exchangeAddresses: { fromToken },
web3, web3,
selectors, selectors,
...@@ -228,16 +231,17 @@ class RemoveLiquidity extends Component { ...@@ -228,16 +231,17 @@ class RemoveLiquidity extends Component {
return ( return (
<div> <div>
<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-modal__item">{t("youAreRemoving")} {b(`${+BN(ethWithdrawn).toFixed(7)} ETH`)} {t("and")} {b(`${+minTokenWithdrawn} - ${+maxTokenWithdrawn} ${label}`)} {t("outPool")}</div>
<div className="pool__summary-item">You will remove {b(+input)} liquidity tokens.</div> <div className="pool__summary-modal__item">{t("youWillRemove")} {b(+input)} {t("liquidityTokens")}</div>
<div className="pool__summary-item">Current total supply of liquidity tokens is {b(+adjTotalSupply.toFixed(7))}</div> <div className="pool__summary-modal__item">{t("totalSupplyIs")} {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("tokenWorth")} {b(+ethReserve.dividedBy(totalSupply).toFixed(7))} ETH {t("and")} {b(+tokenReserve.dividedBy(totalSupply).toFixed(7))} {label}</div>
</div> </div>
); );
} }
renderOutput() { renderOutput() {
const { const {
t,
exchangeAddresses: { fromToken }, exchangeAddresses: { fromToken },
account, account,
web3, web3,
...@@ -250,8 +254,8 @@ class RemoveLiquidity extends Component { ...@@ -250,8 +254,8 @@ class RemoveLiquidity extends Component {
const blank = [ const blank = [
<CurrencyInputPanel <CurrencyInputPanel
key="remove-liquidity-input" key="remove-liquidity-input"
title="Output" title={t("output")}
description="(estimated)" description={`(${t("estimated")})`}
renderInput={() => ( renderInput={() => (
<div className="remove-liquidity__output"></div> <div className="remove-liquidity__output"></div>
)} )}
...@@ -261,15 +265,15 @@ class RemoveLiquidity extends Component { ...@@ -261,15 +265,15 @@ class RemoveLiquidity extends Component {
<OversizedPanel key="remove-liquidity-input-under" hideBottom> <OversizedPanel key="remove-liquidity-input-under" hideBottom>
<div className="pool__summary-panel"> <div className="pool__summary-panel">
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="pool__exchange-rate">Exchange Rate</span> <span className="pool__exchange-rate">{t("exchangeRate")}</span>
<span> - </span> <span> - </span>
</div> </div>
<div className="pool__exchange-rate-wrapper"> <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> <span> - </span>
</div> </div>
<div className="pool__exchange-rate-wrapper"> <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> <span> - </span>
</div> </div>
</div> </div>
...@@ -299,8 +303,8 @@ class RemoveLiquidity extends Component { ...@@ -299,8 +303,8 @@ class RemoveLiquidity extends Component {
return [ return [
<CurrencyInputPanel <CurrencyInputPanel
title="Output" title={t("output")}
description="(estimated)" description={`(${t("estimated")})`}
key="remove-liquidity-input" key="remove-liquidity-input"
renderInput={() => input renderInput={() => input
? ( ? (
...@@ -322,18 +326,18 @@ class RemoveLiquidity extends Component { ...@@ -322,18 +326,18 @@ class RemoveLiquidity extends Component {
<OversizedPanel key="remove-liquidity-input-under" hideBottom> <OversizedPanel key="remove-liquidity-input-under" hideBottom>
<div className="pool__summary-panel"> <div className="pool__summary-panel">
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="pool__exchange-rate">Exchange Rate</span> <span className="pool__exchange-rate">{t("exchangeRate")}</span>
<span> <span>
{`1 ETH = ${exchangeRate.toFixed(4)} ${label}`} {`1 ETH = ${exchangeRate.toFixed(4)} ${label}`}
</span> </span>
</div> </div>
<div className="pool__exchange-rate-wrapper"> <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> <span>{`${ethReserve.dividedBy(10 ** 18).toFixed(2)} ETH + ${tokenReserve.dividedBy(10 ** tokenDecimals).toFixed(2)} ${label}`}</span>
</div> </div>
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate"> <span className="swap__exchange-rate">
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%) {t("yourPoolShare")} ({ownership.multipliedBy(100).toFixed(2)}%)
</span> </span>
<span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span> <span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
</div> </div>
...@@ -343,7 +347,7 @@ class RemoveLiquidity extends Component { ...@@ -343,7 +347,7 @@ class RemoveLiquidity extends Component {
} }
render() { render() {
const { isConnected } = this.props; const { t, isConnected } = this.props;
const { tokenAddress, value } = this.state; const { tokenAddress, value } = this.state;
const { isValid, errorMessage } = this.validate(); const { isValid, errorMessage } = this.validate();
...@@ -359,9 +363,9 @@ class RemoveLiquidity extends Component { ...@@ -359,9 +363,9 @@ class RemoveLiquidity extends Component {
'header--inactive': !isConnected, 'header--inactive': !isConnected,
})} })}
/> />
<ModeSelector title="Remove Liquidity" /> <ModeSelector title={t("removeLiquidity")} />
<CurrencyInputPanel <CurrencyInputPanel
title="Pool Tokens" title={t("poolTokens")}
extraText={this.getBalance(tokenAddress)} extraText={this.getBalance(tokenAddress)}
onValueChange={this.onInputChange} onValueChange={this.onInputChange}
value={value} value={value}
...@@ -386,7 +390,7 @@ class RemoveLiquidity extends Component { ...@@ -386,7 +390,7 @@ class RemoveLiquidity extends Component {
disabled={!isValid} disabled={!isValid}
onClick={this.onRemoveLiquidity} onClick={this.onRemoveLiquidity}
> >
Remove Liquidity {t("removeLiquidity")}
</button> </button>
</div> </div>
</div> </div>
...@@ -406,7 +410,7 @@ export default connect( ...@@ -406,7 +410,7 @@ export default connect(
selectors: () => dispatch(selectors()), selectors: () => dispatch(selectors()),
addPendingTx: id => dispatch(addPendingTx(id)), addPendingTx: id => dispatch(addPendingTx(id)),
}) })
)(RemoveLiquidity); )(withNamespaces()(RemoveLiquidity));
function b(text) { function b(text) {
return <span className="swap__highlight-text">{text}</span> return <span className="swap__highlight-text">{text}</span>
......
...@@ -3,6 +3,7 @@ import { connect } from 'react-redux'; ...@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import {BigNumber as BN} from "bignumber.js"; import {BigNumber as BN} from "bignumber.js";
import { withNamespaces } from 'react-i18next';
import { selectors, addPendingTx } from '../../ducks/web3connect'; import { selectors, addPendingTx } from '../../ducks/web3connect';
import Header from '../../components/Header'; import Header from '../../components/Header';
import NavigationTabs from '../../components/NavigationTabs'; import NavigationTabs from '../../components/NavigationTabs';
...@@ -87,11 +88,11 @@ class Send extends Component { ...@@ -87,11 +88,11 @@ class Send extends Component {
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency); const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
if (inputBalance.isLessThan(BN(inputValue * 10 ** inputDecimals))) { if (inputBalance.isLessThan(BN(inputValue * 10 ** inputDecimals))) {
inputError = 'Insufficient Balance'; inputError = this.props.t("insufficientBalance");
} }
if (inputValue === 'N/A') { if (inputValue === 'N/A') {
inputError = 'Not a valid input value'; inputError = this.props.t("inputNotValid");
} }
return { return {
...@@ -535,7 +536,7 @@ class Send extends Component { ...@@ -535,7 +536,7 @@ class Send extends Component {
outputCurrency, outputCurrency,
recipient, recipient,
} = this.state; } = this.state;
const { web3 } = this.props; const { t, web3 } = this.props;
const { selectors, account } = this.props; const { selectors, account } = this.props;
const { label: inputLabel } = selectors().getBalance(account, inputCurrency); const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
...@@ -551,24 +552,25 @@ class Send extends Component { ...@@ -551,24 +552,25 @@ class Send extends Component {
contextualInfo = inputError || outputError; contextualInfo = inputError || outputError;
isError = true; isError = true;
} else if (!inputCurrency || !outputCurrency) { } else if (!inputCurrency || !outputCurrency) {
contextualInfo = 'Select a token to continue.'; contextualInfo = t("selectTokenCont");
} else if (inputCurrency === outputCurrency) { } else if (inputCurrency === outputCurrency) {
contextualInfo = 'Must be different token.'; contextualInfo = t("differentToken");
} else if (!inputValue || !outputValue) { } else if (!inputValue || !outputValue) {
const missingCurrencyValue = !inputValue ? inputLabel : outputLabel; const missingCurrencyValue = !inputValue ? inputLabel : outputLabel;
contextualInfo = `Enter a ${missingCurrencyValue} value to continue.`; contextualInfo = t("enterValueCont", {missingCurrencyValue});
} else if (inputIsZero || outputIsZero) { } else if (inputIsZero || outputIsZero) {
contextualInfo = 'No liquidity.'; contextualInfo = t("noLiquidity");
} else if (this.isUnapproved()) { } else if (this.isUnapproved()) {
contextualInfo = 'Please unlock token to continue.'; contextualInfo = t("unlockTokenCont");
} else if (!recipient) { } else if (!recipient) {
contextualInfo = 'Enter a wallet address to send to.'; contextualInfo = t("noRecipient");
} else if (!validRecipientAddress) { } else if (!validRecipientAddress) {
contextualInfo = 'Please enter a valid wallet address recipient.'; contextualInfo = t("invalidRecipient");
} }
return ( return (
<ContextualInfo <ContextualInfo
openModalText={t("transactionDetails")}
contextualInfo={contextualInfo} contextualInfo={contextualInfo}
isError={isError} isError={isError}
renderTransactionDetails={this.renderTransactionDetails} renderTransactionDetails={this.renderTransactionDetails}
...@@ -586,7 +588,7 @@ class Send extends Component { ...@@ -586,7 +588,7 @@ class Send extends Component {
inputAmountB, inputAmountB,
lastEditedField, lastEditedField,
} = this.state; } = this.state;
const { selectors, account } = this.props; const { t, selectors, account } = this.props;
ReactGA.event({ ReactGA.event({
category: 'TransactionDetail', category: 'TransactionDetail',
...@@ -641,10 +643,10 @@ class Send extends Component { ...@@ -641,10 +643,10 @@ class Send extends Component {
return ( return (
<div> <div>
<div> <div>
You are selling {b(`${+inputValue} ${inputLabel}`)}. {t("youAreSending")} {b(`${+inputValue} ${inputLabel}`)}.
</div> </div>
<div className="send__last-summary-text"> <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>
</div> </div>
); );
...@@ -652,12 +654,12 @@ class Send extends Component { ...@@ -652,12 +654,12 @@ class Send extends Component {
return ( return (
<div> <div>
<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}`)}.*/} {/*You are selling between {b(`${+inputValue} ${inputLabel}`)} to {b(`${+maxInput} ${inputLabel}`)}.*/}
</div> </div>
<div className="send__last-summary-text"> <div className="send__last-summary-text">
{/*{b(`${recipient.slice(0, 6)}...${recipient.slice(-4)}`)} will receive {b(`${+outputValue} ${outputLabel}`)}.*/} {/*{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>
</div> </div>
); );
...@@ -665,7 +667,7 @@ class Send extends Component { ...@@ -665,7 +667,7 @@ class Send extends Component {
} }
renderExchangeRate() { renderExchangeRate() {
const { account, selectors } = this.props; const { t, account, selectors } = this.props;
const { exchangeRate, inputCurrency, outputCurrency } = this.state; const { exchangeRate, inputCurrency, outputCurrency } = this.state;
const { label: inputLabel } = selectors().getBalance(account, inputCurrency); const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
const { label: outputLabel } = selectors().getBalance(account, outputCurrency); const { label: outputLabel } = selectors().getBalance(account, outputCurrency);
...@@ -674,7 +676,7 @@ class Send extends Component { ...@@ -674,7 +676,7 @@ class Send extends Component {
return ( return (
<OversizedPanel hideBottom> <OversizedPanel hideBottom>
<div className="swap__exchange-rate-wrapper"> <div className="swap__exchange-rate-wrapper">
<span className="swap__exchange-rate">Exchange Rate</span> <span className="swap__exchange-rate">{t("exchangeRate")}</span>
<span> - </span> <span> - </span>
</div> </div>
</OversizedPanel> </OversizedPanel>
...@@ -684,7 +686,7 @@ class Send extends Component { ...@@ -684,7 +686,7 @@ class Send extends Component {
return ( return (
<OversizedPanel hideBottom> <OversizedPanel hideBottom>
<div className="swap__exchange-rate-wrapper"> <div className="swap__exchange-rate-wrapper">
<span className="swap__exchange-rate">Exchange Rate</span> <span className="swap__exchange-rate">{t("exchangeRate")}</span>
<span> <span>
{`1 ${inputLabel} = ${exchangeRate.toFixed(7)} ${outputLabel}`} {`1 ${inputLabel} = ${exchangeRate.toFixed(7)} ${outputLabel}`}
</span> </span>
...@@ -697,12 +699,12 @@ class Send extends Component { ...@@ -697,12 +699,12 @@ class Send extends Component {
if (!currency || decimals === 0) { if (!currency || decimals === 0) {
return ''; return '';
} }
const balanceInput = balance.dividedBy(BN(10 ** decimals)).toFixed(4)
return `Balance: ${balance.dividedBy(BN(10 ** decimals)).toFixed(4)}` return this.props.t("balance", { balanceInput })
} }
render() { render() {
const { selectors, account } = this.props; const { t, selectors, account } = this.props;
const { const {
lastEditedField, lastEditedField,
inputCurrency, inputCurrency,
...@@ -711,7 +713,7 @@ class Send extends Component { ...@@ -711,7 +713,7 @@ class Send extends Component {
outputValue, outputValue,
recipient, recipient,
} = this.state; } = this.state;
const estimatedText = '(estimated)'; const estimatedText = `(${t("estimated")})`;
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency); const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
const { value: outputBalance, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency); const { value: outputBalance, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency);
...@@ -734,7 +736,7 @@ class Send extends Component { ...@@ -734,7 +736,7 @@ class Send extends Component {
/> />
<CurrencyInputPanel <CurrencyInputPanel
title="Input" title={t("input")}
description={lastEditedField === OUTPUT ? estimatedText : ''} description={lastEditedField === OUTPUT ? estimatedText : ''}
extraText={this.renderBalance(inputCurrency, inputBalance, inputDecimals)} extraText={this.renderBalance(inputCurrency, inputBalance, inputDecimals)}
onCurrencySelected={inputCurrency => this.setState({ inputCurrency }, this.recalcForm)} onCurrencySelected={inputCurrency => this.setState({ inputCurrency }, this.recalcForm)}
...@@ -750,7 +752,7 @@ class Send extends Component { ...@@ -750,7 +752,7 @@ class Send extends Component {
</div> </div>
</OversizedPanel> </OversizedPanel>
<CurrencyInputPanel <CurrencyInputPanel
title="Output" title={t("output")}
description={lastEditedField === INPUT ? estimatedText : ''} description={lastEditedField === INPUT ? estimatedText : ''}
extraText={this.renderBalance(outputCurrency, outputBalance, outputDecimals)} extraText={this.renderBalance(outputCurrency, outputBalance, outputDecimals)}
onCurrencySelected={outputCurrency => this.setState({ outputCurrency }, this.recalcForm)} onCurrencySelected={outputCurrency => this.setState({ outputCurrency }, this.recalcForm)}
...@@ -767,6 +769,7 @@ class Send extends Component { ...@@ -767,6 +769,7 @@ class Send extends Component {
</div> </div>
</OversizedPanel> </OversizedPanel>
<AddressInputPanel <AddressInputPanel
t={this.props.t}
value={recipient} value={recipient}
onChange={address => this.setState({recipient: address})} onChange={address => this.setState({recipient: address})}
/> />
...@@ -780,7 +783,7 @@ class Send extends Component { ...@@ -780,7 +783,7 @@ class Send extends Component {
disabled={!isValid} disabled={!isValid}
onClick={this.onSend} onClick={this.onSend}
> >
Send {t("send")}
</button> </button>
</div> </div>
</div> </div>
...@@ -801,7 +804,7 @@ export default connect( ...@@ -801,7 +804,7 @@ export default connect(
selectors: () => dispatch(selectors()), selectors: () => dispatch(selectors()),
addPendingTx: id => dispatch(addPendingTx(id)), addPendingTx: id => dispatch(addPendingTx(id)),
}), }),
)(Send); )(withNamespaces()(Send));
const b = text => <span className="swap__highlight-text">{text}</span>; const b = text => <span className="swap__highlight-text">{text}</span>;
......
...@@ -5,6 +5,7 @@ import classnames from 'classnames'; ...@@ -5,6 +5,7 @@ import classnames from 'classnames';
import {BigNumber as BN} from "bignumber.js"; import {BigNumber as BN} from "bignumber.js";
import MediaQuery from 'react-responsive'; import MediaQuery from 'react-responsive';
import ReactGA from 'react-ga'; import ReactGA from 'react-ga';
import { withNamespaces } from 'react-i18next';
import { selectors, addPendingTx } from '../../ducks/web3connect'; import { selectors, addPendingTx } from '../../ducks/web3connect';
import Header from '../../components/Header'; import Header from '../../components/Header';
import NavigationTabs from '../../components/NavigationTabs'; import NavigationTabs from '../../components/NavigationTabs';
...@@ -84,11 +85,11 @@ class Swap extends Component { ...@@ -84,11 +85,11 @@ class Swap extends Component {
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency); const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
if (inputBalance.isLessThan(BN(inputValue * 10 ** inputDecimals))) { if (inputBalance.isLessThan(BN(inputValue * 10 ** inputDecimals))) {
inputError = 'Insufficient Balance'; inputError = this.props.t("insufficientBalance");
} }
if (inputValue === 'N/A') { if (inputValue === 'N/A') {
inputError = 'Not a valid input value'; inputError = this.props.t("inputNotValid");
} }
return { return {
...@@ -525,6 +526,7 @@ class Swap extends Component { ...@@ -525,6 +526,7 @@ class Swap extends Component {
outputValue, outputValue,
outputCurrency, outputCurrency,
} = this.state; } = this.state;
const t = this.props.t;
const inputIsZero = BN(inputValue).isZero(); const inputIsZero = BN(inputValue).isZero();
const outputIsZero = BN(outputValue).isZero(); const outputIsZero = BN(outputValue).isZero();
...@@ -532,11 +534,11 @@ class Swap extends Component { ...@@ -532,11 +534,11 @@ class Swap extends Component {
let isError = false; let isError = false;
if (!inputCurrency || !outputCurrency) { if (!inputCurrency || !outputCurrency) {
contextualInfo = 'Select a token to continue.'; contextualInfo = t("selectTokenCont");
} }
if (!inputValue || !outputValue) { if (!inputValue || !outputValue) {
contextualInfo = 'Enter a value to continue.'; contextualInfo = t("enterValueCont");
} }
if (inputError || outputError) { if (inputError || outputError) {
...@@ -545,15 +547,16 @@ class Swap extends Component { ...@@ -545,15 +547,16 @@ class Swap extends Component {
} }
if (inputIsZero || outputIsZero) { if (inputIsZero || outputIsZero) {
contextualInfo = 'No liquidity.'; contextualInfo = t("noLiquidity");
} }
if (this.isUnapproved()) { if (this.isUnapproved()) {
contextualInfo = 'Please unlock token to continue.'; contextualInfo = t("unlockTokenCont");
} }
return ( return (
<ContextualInfo <ContextualInfo
openModalText={t("transactionDetails")}
contextualInfo={contextualInfo} contextualInfo={contextualInfo}
isError={isError} isError={isError}
renderTransactionDetails={this.renderTransactionDetails} renderTransactionDetails={this.renderTransactionDetails}
...@@ -569,7 +572,7 @@ class Swap extends Component { ...@@ -569,7 +572,7 @@ class Swap extends Component {
outputCurrency, outputCurrency,
lastEditedField, lastEditedField,
} = this.state; } = this.state;
const { selectors, account } = this.props; const { t, selectors, account } = this.props;
ReactGA.event({ ReactGA.event({
category: 'TransactionDetail', category: 'TransactionDetail',
...@@ -623,10 +626,10 @@ class Swap extends Component { ...@@ -623,10 +626,10 @@ class Swap extends Component {
return ( return (
<div> <div>
<div> <div>
You are selling {b(`${+inputValue} ${inputLabel}`)}. {t("youAreSelling")} {b(`${+inputValue} ${inputLabel}`)} {t("orTransFail")}
</div> </div>
<div className="send__last-summary-text"> <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>
</div> </div>
); );
...@@ -634,10 +637,10 @@ class Swap extends Component { ...@@ -634,10 +637,10 @@ class Swap extends Component {
return ( return (
<div> <div>
<div> <div>
You are buying {b(`${+outputValue} ${outputLabel}`)}. {t("youAreBuying")} {b(`${+outputValue} ${outputLabel}`)}.
</div> </div>
<div className="send__last-summary-text"> <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>
</div> </div>
); );
...@@ -645,7 +648,7 @@ class Swap extends Component { ...@@ -645,7 +648,7 @@ class Swap extends Component {
} }
renderExchangeRate() { renderExchangeRate() {
const { account, selectors } = this.props; const { t, account, selectors } = this.props;
const { exchangeRate, inputCurrency, outputCurrency } = this.state; const { exchangeRate, inputCurrency, outputCurrency } = this.state;
const { label: inputLabel } = selectors().getBalance(account, inputCurrency); const { label: inputLabel } = selectors().getBalance(account, inputCurrency);
const { label: outputLabel } = selectors().getBalance(account, outputCurrency); const { label: outputLabel } = selectors().getBalance(account, outputCurrency);
...@@ -654,7 +657,7 @@ class Swap extends Component { ...@@ -654,7 +657,7 @@ class Swap extends Component {
return ( return (
<OversizedPanel hideBottom> <OversizedPanel hideBottom>
<div className="swap__exchange-rate-wrapper"> <div className="swap__exchange-rate-wrapper">
<span className="swap__exchange-rate">Exchange Rate</span> <span className="swap__exchange-rate">{t("exchangeRate")}</span>
<span> - </span> <span> - </span>
</div> </div>
</OversizedPanel> </OversizedPanel>
...@@ -664,7 +667,7 @@ class Swap extends Component { ...@@ -664,7 +667,7 @@ class Swap extends Component {
return ( return (
<OversizedPanel hideBottom> <OversizedPanel hideBottom>
<div className="swap__exchange-rate-wrapper"> <div className="swap__exchange-rate-wrapper">
<span className="swap__exchange-rate">Exchange Rate</span> <span className="swap__exchange-rate">{t("exchangeRate")}</span>
<span> <span>
{`1 ${inputLabel} = ${exchangeRate.toFixed(7)} ${outputLabel}`} {`1 ${inputLabel} = ${exchangeRate.toFixed(7)} ${outputLabel}`}
</span> </span>
...@@ -678,11 +681,12 @@ class Swap extends Component { ...@@ -678,11 +681,12 @@ class Swap extends Component {
return ''; 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() { render() {
const { selectors, account } = this.props; const { t, selectors, account } = this.props;
const { const {
lastEditedField, lastEditedField,
inputCurrency, inputCurrency,
...@@ -690,7 +694,7 @@ class Swap extends Component { ...@@ -690,7 +694,7 @@ class Swap extends Component {
inputValue, inputValue,
outputValue, outputValue,
} = this.state; } = this.state;
const estimatedText = '(estimated)'; const estimatedText = `(${t("estimated")})`;
const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency); const { value: inputBalance, decimals: inputDecimals } = selectors().getBalance(account, inputCurrency);
const { value: outputBalance, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency); const { value: outputBalance, decimals: outputDecimals } = selectors().getBalance(account, outputCurrency);
...@@ -715,7 +719,7 @@ class Swap extends Component { ...@@ -715,7 +719,7 @@ class Swap extends Component {
/> />
<CurrencyInputPanel <CurrencyInputPanel
title="Input" title={t("input")}
description={lastEditedField === OUTPUT ? estimatedText : ''} description={lastEditedField === OUTPUT ? estimatedText : ''}
extraText={this.renderBalance(inputCurrency, inputBalance, inputDecimals)} extraText={this.renderBalance(inputCurrency, inputBalance, inputDecimals)}
onCurrencySelected={inputCurrency => this.setState({ inputCurrency }, this.recalcForm)} onCurrencySelected={inputCurrency => this.setState({ inputCurrency }, this.recalcForm)}
...@@ -731,7 +735,7 @@ class Swap extends Component { ...@@ -731,7 +735,7 @@ class Swap extends Component {
</div> </div>
</OversizedPanel> </OversizedPanel>
<CurrencyInputPanel <CurrencyInputPanel
title="Output" title={t("output")}
description={lastEditedField === INPUT ? estimatedText : ''} description={lastEditedField === INPUT ? estimatedText : ''}
extraText={this.renderBalance(outputCurrency, outputBalance, outputDecimals)} extraText={this.renderBalance(outputCurrency, outputBalance, outputDecimals)}
onCurrencySelected={outputCurrency => this.setState({ outputCurrency }, this.recalcForm)} onCurrencySelected={outputCurrency => this.setState({ outputCurrency }, this.recalcForm)}
...@@ -752,7 +756,7 @@ class Swap extends Component { ...@@ -752,7 +756,7 @@ class Swap extends Component {
disabled={!isValid} disabled={!isValid}
onClick={this.onSwap} onClick={this.onSwap}
> >
Swap {t("swap")}
</button> </button>
</div> </div>
</div> </div>
...@@ -773,7 +777,7 @@ export default connect( ...@@ -773,7 +777,7 @@ export default connect(
selectors: () => dispatch(selectors()), selectors: () => dispatch(selectors()),
addPendingTx: id => dispatch(addPendingTx(id)), addPendingTx: id => dispatch(addPendingTx(id)),
}), }),
)(Swap); )(withNamespaces()(Swap));
const b = text => <span className="swap__highlight-text">{text}</span>; const b = text => <span className="swap__highlight-text">{text}</span>;
......
...@@ -751,6 +751,13 @@ ...@@ -751,6 +751,13 @@
dependencies: dependencies:
regenerator-runtime "^0.12.0" 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": "@babel/template@7.0.0-beta.44":
version "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" 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: ...@@ -2994,6 +3001,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
sha.js "^2.4.8" 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: cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5" version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
...@@ -4835,6 +4850,19 @@ fb-watchman@^2.0.0: ...@@ -4835,6 +4850,19 @@ fb-watchman@^2.0.0:
dependencies: dependencies:
bser "^2.0.0" 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: fbjs@^0.8.16:
version "0.8.16" version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
...@@ -5522,6 +5550,11 @@ growly@^1.3.0: ...@@ -5522,6 +5550,11 @@ growly@^1.3.0:
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= 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: gzip-size@5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80"
...@@ -5767,6 +5800,13 @@ hoek@4.x.x: ...@@ -5767,6 +5800,13 @@ hoek@4.x.x:
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ== 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: hoist-non-react-statics@^2.5.0:
version "2.5.5" version "2.5.5"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" 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: ...@@ -5853,6 +5893,13 @@ html-minifier@^3.2.3:
relateurl "0.2.x" relateurl "0.2.x"
uglify-js "3.3.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: html-webpack-plugin@4.0.0-alpha.2:
version "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" 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: ...@@ -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" resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
integrity sha1-MRYKNpMK2vH8BMYHT360FGXU7Es= 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: iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
version "0.4.24" version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
...@@ -10374,6 +10436,16 @@ react-helmet@^5.2.0: ...@@ -10374,6 +10436,16 @@ react-helmet@^5.2.0:
prop-types "^15.5.4" prop-types "^15.5.4"
react-side-effect "^1.1.0" 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: react-input-autosize@^2.1.2:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" 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: ...@@ -10381,6 +10453,11 @@ react-input-autosize@^2.1.2:
dependencies: dependencies:
prop-types "^15.5.8" 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: react-motion@^0.5.0:
version "0.5.2" version "0.5.2"
resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316" resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
...@@ -12964,6 +13041,11 @@ vm-browserify@0.0.4: ...@@ -12964,6 +13041,11 @@ vm-browserify@0.0.4:
dependencies: dependencies:
indexof "0.0.1" 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: w3c-hr-time@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment