Browse Source

feat(i18n): initial multi-language support

renovate/lint-staged-8.x
Tom Kirkpatrick 6 years ago
parent
commit
aedd1ee233
No known key found for this signature in database GPG Key ID: 72203A8EC5967EA8
  1. 5
      .babelrc
  2. 21
      app/components/Activity/Activity.js
  3. 21
      app/components/Activity/Activity.scss
  4. 7
      app/components/Activity/Countdown/Countdown.js
  5. 6
      app/components/Activity/Countdown/messages.js
  6. 31
      app/components/Activity/Invoice/Invoice.js
  7. 10
      app/components/Activity/Invoice/messages.js
  8. 47
      app/components/Activity/InvoiceModal/InvoiceModal.js
  9. 12
      app/components/Activity/InvoiceModal/messages.js
  10. 31
      app/components/Activity/Payment/Payment.js
  11. 8
      app/components/Activity/Payment/messages.js
  12. 24
      app/components/Activity/PaymentModal/PaymentModal.js
  13. 8
      app/components/Activity/PaymentModal/messages.js
  14. 32
      app/components/Activity/Transaction/Transaction.js
  15. 10
      app/components/Activity/Transaction/messages.js
  16. 30
      app/components/Activity/TransactionModal/TransactionModal.js
  17. 9
      app/components/Activity/TransactionModal/messages.js
  18. 13
      app/components/Activity/messages.js
  19. 25
      app/components/Contacts/AddChannel/AddChannel.js
  20. 11
      app/components/Contacts/AddChannel/messages.js
  21. 21
      app/components/Contacts/ConnectManually/ConnectManually.js
  22. 9
      app/components/Contacts/ConnectManually/messages.js
  23. 39
      app/components/Contacts/Network/Network.js
  24. 16
      app/components/Contacts/Network/messages.js
  25. 30
      app/components/Contacts/SubmitChannelForm/SubmitChannelForm.js
  26. 11
      app/components/Contacts/SubmitChannelForm/messages.js
  27. 11
      app/components/Contacts/SuggestedNodes/SuggestedNodes.js
  28. 8
      app/components/Contacts/SuggestedNodes/messages.js
  29. 28
      app/components/Form/Pay/Pay.js
  30. 11
      app/components/Form/Pay/messages.js
  31. 25
      app/components/Form/Request/Request.js
  32. 9
      app/components/Form/Request/messages.js
  33. 7
      app/components/LoadingBolt/LoadingBolt.js
  34. 6
      app/components/LoadingBolt/messages.js
  35. 10
      app/components/Onboarding/Autopilot/Autopilot.js
  36. 7
      app/components/Onboarding/Autopilot/messages.js
  37. 21
      app/components/Onboarding/BtcPayServer/BtcPayServer.js
  38. 10
      app/components/Onboarding/BtcPayServer/messages.js
  39. 8
      app/components/Onboarding/ConnectionConfirm/ConnectionConfirm.js
  40. 7
      app/components/Onboarding/ConnectionConfirm/messages.js
  41. 18
      app/components/Onboarding/ConnectionDetails/ConnectionDetails.js
  42. 10
      app/components/Onboarding/ConnectionDetails/messages.js
  43. 18
      app/components/Onboarding/ConnectionType/ConnectionType.js
  44. 14
      app/components/Onboarding/ConnectionType/messages.js
  45. 14
      app/components/Onboarding/FormContainer/FormContainer.js
  46. 8
      app/components/Onboarding/FormContainer/messages.js
  47. 21
      app/components/Onboarding/Login/Login.js
  48. 7
      app/components/Onboarding/Login/messages.js
  49. 20
      app/components/Onboarding/NewWalletPassword/NewWalletPassword.js
  50. 10
      app/components/Onboarding/NewWalletPassword/messages.js
  51. 87
      app/components/Onboarding/Onboarding.js
  52. 11
      app/components/Onboarding/RecoverForm/RecoverForm.js
  53. 6
      app/components/Onboarding/RecoverForm/messages.js
  54. 10
      app/components/Onboarding/Signup/Signup.js
  55. 7
      app/components/Onboarding/Signup/messages.js
  56. 52
      app/components/Onboarding/Syncing/Syncing.js
  57. 17
      app/components/Onboarding/Syncing/messages.js
  58. 35
      app/components/Onboarding/messages.js
  59. 6
      app/components/Settings/Fiat/Fiat.js
  60. 6
      app/components/Settings/Fiat/messages.js
  61. 49
      app/components/Settings/Locale/Locale.js
  62. 42
      app/components/Settings/Locale/Locale.scss
  63. 3
      app/components/Settings/Locale/index.js
  64. 6
      app/components/Settings/Locale/messages.js
  65. 10
      app/components/Settings/Menu/Menu.js
  66. 7
      app/components/Settings/Menu/messages.js
  67. 8
      app/components/Settings/Settings.js
  68. 23
      app/components/Wallet/ReceiveModal/ReceiveModal.js
  69. 9
      app/components/Wallet/ReceiveModal/messages.js
  70. 21
      app/components/Wallet/Wallet.js
  71. 10
      app/components/Wallet/messages.js
  72. 11
      app/containers/Activity.js
  73. 28
      app/containers/Root.js
  74. 37
      app/index.js
  75. 125
      app/lib/utils/i18n.js
  76. 40
      app/lib/zap/menuBuilder.js
  77. 8
      app/reducers/activity.js
  78. 4
      app/reducers/index.js
  79. 2
      app/reducers/ipc.js
  80. 40
      app/reducers/locale.js
  81. 157
      app/translations/bg-BG.json
  82. 157
      app/translations/cs-CZ.json
  83. 157
      app/translations/de-DE.json
  84. 157
      app/translations/el-GR.json
  85. 157
      app/translations/en.json
  86. 157
      app/translations/es-ES.json
  87. 157
      app/translations/fr-FR.json
  88. 157
      app/translations/hr-HR.json
  89. 157
      app/translations/ja-JP.json
  90. 157
      app/translations/nl-NL.json
  91. 157
      app/translations/pt-BR.json
  92. 157
      app/translations/ro-RO.json
  93. 157
      app/translations/ru-RU.json
  94. 157
      app/translations/sv-SE.json
  95. 157
      app/translations/tr-TR.json
  96. 157
      app/translations/uk-UA.json
  97. 157
      app/translations/zh-CN.json
  98. 10
      package.json
  99. 41
      test/unit/__helpers__/intl-enzyme-test-helper.js.js
  100. 10
      test/unit/components/Form/Pay.spec.js

5
.babelrc

@ -10,7 +10,10 @@
"stage-0", "stage-0",
"react" "react"
], ],
"plugins": ["add-module-exports", "dynamic-import-webpack"], "plugins": ["add-module-exports", "dynamic-import-webpack", ["react-intl-auto", {
"removePrefix": "app/",
"filebase": false
}]],
"env": { "env": {
"production": { "production": {
"presets": ["react-optimize"], "presets": ["react-optimize"],

21
app/components/Activity/Activity.js

@ -5,6 +5,8 @@ import searchIcon from 'icons/search.svg'
import xIcon from 'icons/x.svg' import xIcon from 'icons/x.svg'
import FaRepeat from 'react-icons/lib/fa/repeat' import FaRepeat from 'react-icons/lib/fa/repeat'
import { FormattedMessage, injectIntl } from 'react-intl'
import Wallet from 'components/Wallet' import Wallet from 'components/Wallet'
import LoadingBolt from 'components/LoadingBolt' import LoadingBolt from 'components/LoadingBolt'
import Invoice from './Invoice' import Invoice from './Invoice'
@ -13,6 +15,8 @@ import Transaction from './Transaction'
import styles from './Activity.scss' import styles from './Activity.scss'
import messages from './messages'
class Activity extends Component { class Activity extends Component {
constructor(props, context) { constructor(props, context) {
super(props, context) super(props, context)
@ -87,7 +91,8 @@ class Activity extends Component {
updateSearchActive, updateSearchActive,
updateSearchText, updateSearchText,
walletProps walletProps,
intl
} = this.props } = this.props
if (balance.channelBalance === null || balance.walletBalance === null) { if (balance.channelBalance === null || balance.walletBalance === null) {
@ -134,7 +139,7 @@ class Activity extends Component {
<header className={`${styles.header} ${styles.search}`}> <header className={`${styles.header} ${styles.search}`}>
<section> <section>
<input <input
placeholder="Search" placeholder={intl.formatMessage({ ...messages.search })}
value={searchText} value={searchText}
onChange={event => updateSearchText(event.target.value)} onChange={event => updateSearchText(event.target.value)}
/> />
@ -160,7 +165,7 @@ class Activity extends Component {
className={f.key === filter.key ? styles.activeFilter : undefined} className={f.key === filter.key ? styles.activeFilter : undefined}
onClick={() => changeFilter(f)} onClick={() => changeFilter(f)}
> >
<span>{f.name}</span> <FormattedMessage {...messages[f.name]} />
<div className={f.key === filter.key ? styles.activeBorder : undefined} /> <div className={f.key === filter.key ? styles.activeBorder : undefined} />
</li> </li>
@ -176,7 +181,7 @@ class Activity extends Component {
this.repeat = ref this.repeat = ref
}} }}
> >
{refreshing ? <FaRepeat /> : 'Refresh'} {refreshing ? <FaRepeat /> : <FormattedMessage {...messages.refresh} />}
</span> </span>
</li> </li>
<li className={styles.activeFilter} onClick={() => updateSearchActive(true)}> <li className={styles.activeFilter} onClick={() => updateSearchActive(true)}>
@ -204,7 +209,11 @@ class Activity extends Component {
{showExpiredToggle && ( {showExpiredToggle && (
<li> <li>
<div className={styles.toggleExpired} onClick={toggleExpiredRequests}> <div className={styles.toggleExpired} onClick={toggleExpiredRequests}>
{showExpiredRequests ? 'Hide Expired Requests' : 'Show Expired Requests'} {showExpiredRequests ? (
<FormattedMessage {...messages.hide_expired} />
) : (
<FormattedMessage {...messages.show_expired} />
)}
</div> </div>
</li> </li>
)} )}
@ -240,4 +249,4 @@ Activity.propTypes = {
currencyName: PropTypes.string.isRequired currencyName: PropTypes.string.isRequired
} }
export default Activity export default injectIntl(Activity)

21
app/components/Activity/Activity.scss

@ -284,23 +284,15 @@
font-size: 10px; font-size: 10px;
} }
.icon, .date {
h3, font-size: 12px;
span {
vertical-align: middle;
}
h3,
span {
font-size: 14px;
font-weight: bold;
letter-spacing: 1.2px;
} }
.icon { .icon {
display: inline-block; display: inline-block;
flex: none; flex: none;
position: relative; position: relative;
vertical-align: middle;
width: 20px; width: 20px;
height: 20px; height: 20px;
background: #31343f; background: #31343f;
@ -321,6 +313,9 @@
h3 { h3 {
display: inline-block; display: inline-block;
font-size: 14px;
font-weight: bold;
letter-spacing: 1.2px;
&::after { &::after {
content: ' '; content: ' ';
@ -328,10 +323,6 @@
width: 3px; width: 3px;
} }
} }
span {
text-transform: uppercase;
}
} }
.amount { .amount {

7
app/components/Activity/Countdown/Countdown.js

@ -1,6 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Countdown.scss' import styles from './Countdown.scss'
class Countdown extends React.Component { class Countdown extends React.Component {
@ -73,7 +76,9 @@ class Countdown extends React.Component {
return ( return (
<span className={styles.container}> <span className={styles.container}>
<i className={styles.caption}>Expires in</i> <i className={styles.caption}>
<FormattedMessage {...messages.expires} />
</i>
<i>{days > 0 && `${days}:`}</i> <i>{days > 0 && `${days}:`}</i>
<i>{hours > 0 && `${hours}:`}</i> <i>{hours > 0 && `${hours}:`}</i>
<i>{minutes > 0 && `${minutes}:`}</i> <i>{minutes > 0 && `${minutes}:`}</i>

6
app/components/Activity/Countdown/messages.js

@ -0,0 +1,6 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
expires: 'Expires in'
})

31
app/components/Activity/Invoice/Invoice.js

@ -1,14 +1,17 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import { btc } from 'lib/utils' import { btc } from 'lib/utils'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import Value from 'components/Value' import Value from 'components/Value'
import checkmarkIcon from 'icons/check_circle.svg' import checkmarkIcon from 'icons/check_circle.svg'
import { FormattedTime, FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from '../Activity.scss' import styles from '../Activity.scss'
const Invoice = ({ invoice, ticker, currentTicker, showActivityModal, currencyName }) => ( const Invoice = ({ invoice, ticker, currentTicker, showActivityModal, currencyName, intl }) => (
<div <div
className={`${styles.container} ${!invoice.settled ? styles.unpaid : undefined}`} className={`${styles.container} ${!invoice.settled ? styles.unpaid : undefined}`}
onClick={() => showActivityModal('INVOICE', invoice.payment_request)} onClick={() => showActivityModal('INVOICE', invoice.payment_request)}
@ -16,7 +19,11 @@ const Invoice = ({ invoice, ticker, currentTicker, showActivityModal, currencyNa
<div className={styles.activityTypeIcon}> <div className={styles.activityTypeIcon}>
<section <section
className="hint--bottom" className="hint--bottom"
data-hint={`Lightning invoice (${invoice.settled ? 'paid)' : 'unpaid'})`} data-hint={
invoice.settled
? intl.formatMessage({ ...messages.type_paid })
: intl.formatMessage({ ...messages.type_unpaid })
}
> >
<Isvg src={checkmarkIcon} /> <Isvg src={checkmarkIcon} />
</section> </section>
@ -24,19 +31,25 @@ const Invoice = ({ invoice, ticker, currentTicker, showActivityModal, currencyNa
<div className={styles.data}> <div className={styles.data}>
<div className={styles.title}> <div className={styles.title}>
<h3>{invoice.settled ? 'Received payment' : 'Requested payment'}</h3> <h3>
{invoice.settled ? (
<FormattedMessage {...messages.received} />
) : (
<FormattedMessage {...messages.requested} />
)}
</h3>
</div> </div>
<div className={styles.subtitle}> <div className={styles.subtitle}>
<Moment format="h:mm a"> <FormattedTime
{invoice.settled ? invoice.settle_date * 1000 : invoice.creation_date * 1000} value={invoice.settled ? invoice.settle_date * 1000 : invoice.creation_date * 1000}
</Moment> />
</div> </div>
</div> </div>
<div <div
className={`hint--top-left ${styles.amount} ${ className={`hint--top-left ${styles.amount} ${
invoice.settled ? styles.positive : styles.negative invoice.settled ? styles.positive : styles.negative
}`} }`}
data-hint="Invoice amount" data-hint={intl.formatMessage({ ...messages.amount })}
> >
<span> <span>
<i className={styles.plus}>+</i> <i className={styles.plus}>+</i>
@ -66,4 +79,4 @@ Invoice.propTypes = {
currencyName: PropTypes.string.isRequired currencyName: PropTypes.string.isRequired
} }
export default Invoice export default injectIntl(Invoice)

10
app/components/Activity/Invoice/messages.js

@ -0,0 +1,10 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
received: 'Received payment',
requested: 'Requested payment',
type_paid: 'Lightning invoice (paid)',
type_unpaid: 'Lightning invoice (unpaid)',
amount: 'Invoice amount'
})

47
app/components/Activity/InvoiceModal/InvoiceModal.js

@ -1,8 +1,6 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import QRCode from 'qrcode.react' import QRCode from 'qrcode.react'
import copy from 'copy-to-clipboard' import copy from 'copy-to-clipboard'
import { showNotification } from 'lib/utils/notifications' import { showNotification } from 'lib/utils/notifications'
@ -10,8 +8,11 @@ import { showNotification } from 'lib/utils/notifications'
import FaAngleDown from 'react-icons/lib/fa/angle-down' import FaAngleDown from 'react-icons/lib/fa/angle-down'
import Value from 'components/Value' import Value from 'components/Value'
import { FormattedDate, FormattedTime, FormattedMessage } from 'react-intl'
import Countdown from '../Countdown' import Countdown from '../Countdown'
import messages from './messages'
import styles from './InvoiceModal.scss' import styles from './InvoiceModal.scss'
const InvoiceModal = ({ const InvoiceModal = ({
@ -29,7 +30,7 @@ const InvoiceModal = ({
}) => { }) => {
const copyPaymentRequest = () => { const copyPaymentRequest = () => {
copy(invoice.payment_request) copy(invoice.payment_request)
showNotification('Noice', 'Successfully copied to clipboard') showNotification('Noice', <FormattedMessage {...messages.copied} />)
} }
const countDownDate = parseInt(invoice.creation_date, 10) + parseInt(invoice.expiry, 10) const countDownDate = parseInt(invoice.creation_date, 10) + parseInt(invoice.expiry, 10)
@ -38,7 +39,9 @@ const InvoiceModal = ({
<div className={styles.container}> <div className={styles.container}>
<div className={styles.content}> <div className={styles.content}>
<section className={styles.left}> <section className={styles.left}>
<h2>Payment Request</h2> <h2>
<FormattedMessage {...messages.pay_req} />
</h2>
<QRCode <QRCode
value={invoice.payment_request} value={invoice.payment_request}
renderAs="svg" renderAs="svg"
@ -80,28 +83,50 @@ const InvoiceModal = ({
</section> </section>
<section className={styles.date}> <section className={styles.date}>
<p> <p>
<Moment format="MM/DD/YYYY">{invoice.creation_date * 1000}</Moment> <FormattedDate
value={invoice.creation_date * 1000}
year="numeric"
month="long"
day="2-digit"
/>{' '}
<FormattedTime value={new Date(invoice.creation_date * 1000)} />
</p> </p>
{!invoice.settled && <p className={styles.notPaid}>Not Paid</p>} {!invoice.settled && (
{invoice.settled && <p className={styles.paid}>Paid</p>} <p className={styles.notPaid}>
<FormattedMessage {...messages.not_paid} />
</p>
)}
{invoice.settled && (
<p className={styles.paid}>
<FormattedMessage {...messages.paid} />
</p>
)}
</section> </section>
</div> </div>
<div className={styles.memo}> <div className={styles.memo}>
<h4>Memo</h4> <h4>
<FormattedMessage {...messages.memo} />
</h4>
<p>{invoice.memo}</p> <p>{invoice.memo}</p>
</div> </div>
<div className={styles.request}> <div className={styles.request}>
<h4>Request</h4> <h4>
<FormattedMessage {...messages.request} />
</h4>
<p>{invoice.payment_request}</p> <p>{invoice.payment_request}</p>
</div> </div>
</section> </section>
</div> </div>
<div className={styles.actions}> <div className={styles.actions}>
<div>Save as image</div> <div>
<div onClick={copyPaymentRequest}>Copy Request</div> <FormattedMessage {...messages.save} />
</div>
<div onClick={copyPaymentRequest}>
<FormattedMessage {...messages.copy} />
</div>
</div> </div>
</div> </div>
) )

12
app/components/Activity/InvoiceModal/messages.js

@ -0,0 +1,12 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
copy: 'Copy Request',
pay_req: 'Payment Request',
memo: 'Memo',
request: 'Request',
save: 'Save as image',
not_paid: 'Not Paid',
paid: 'Paid'
})

31
app/components/Activity/Payment/Payment.js

@ -1,14 +1,25 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import zap from 'icons/zap.svg' import zap from 'icons/zap.svg'
import { btc } from 'lib/utils' import { btc } from 'lib/utils'
import Value from 'components/Value' import Value from 'components/Value'
import { FormattedTime, injectIntl } from 'react-intl'
import messages from './messages'
import styles from '../Activity.scss' import styles from '../Activity.scss'
const Payment = ({ payment, ticker, currentTicker, showActivityModal, nodes, currencyName }) => { const Payment = ({
payment,
ticker,
currentTicker,
showActivityModal,
nodes,
currencyName,
intl
}) => {
const displayNodeName = pubkey => { const displayNodeName = pubkey => {
const node = nodes.find(n => pubkey === n.pub_key) const node = nodes.find(n => pubkey === n.pub_key)
@ -25,7 +36,7 @@ const Payment = ({ payment, ticker, currentTicker, showActivityModal, nodes, cur
onClick={() => showActivityModal('PAYMENT', payment.payment_hash)} onClick={() => showActivityModal('PAYMENT', payment.payment_hash)}
> >
<div className={styles.activityTypeIcon}> <div className={styles.activityTypeIcon}>
<section className="hint--bottom" data-hint="Lightning payment"> <section className="hint--bottom" data-hint={intl.formatMessage({ ...messages.type })}>
<Isvg src={zap} /> <Isvg src={zap} />
</section> </section>
</div> </div>
@ -35,10 +46,13 @@ const Payment = ({ payment, ticker, currentTicker, showActivityModal, nodes, cur
<h3>{displayNodeName(payment.path[payment.path.length - 1])}</h3> <h3>{displayNodeName(payment.path[payment.path.length - 1])}</h3>
</div> </div>
<div className={styles.subtitle}> <div className={styles.subtitle}>
<Moment format="h:mm a">{payment.creation_date * 1000}</Moment> <FormattedTime value={payment.creation_date * 1000} />
</div> </div>
</div> </div>
<div className={`hint--top-left ${styles.amount}`} data-hint="Payment amount"> <div
className={`hint--top-left ${styles.amount}`}
data-hint={intl.formatMessage({ ...messages.amount })}
>
<span> <span>
<i className={styles.minus}>-</i> <i className={styles.minus}>-</i>
<Value <Value
@ -49,7 +63,7 @@ const Payment = ({ payment, ticker, currentTicker, showActivityModal, nodes, cur
/> />
<i> {currencyName}</i> <i> {currencyName}</i>
</span> </span>
<span className="hint--bottom" data-hint="Payment fee"> <span className="hint--bottom" data-hint={intl.formatMessage({ ...messages.fee })}>
{currentTicker[ticker.fiatTicker].symbol} {currentTicker[ticker.fiatTicker].symbol}
{btc.convert('sats', 'fiat', payment.value, currentTicker[ticker.fiatTicker].last)} {btc.convert('sats', 'fiat', payment.value, currentTicker[ticker.fiatTicker].last)}
</span> </span>
@ -64,7 +78,8 @@ Payment.propTypes = {
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired, currentTicker: PropTypes.object.isRequired,
nodes: PropTypes.array.isRequired, nodes: PropTypes.array.isRequired,
showActivityModal: PropTypes.func.isRequired showActivityModal: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired
} }
export default Payment export default injectIntl(Payment)

8
app/components/Activity/Payment/messages.js

@ -0,0 +1,8 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
amount: 'Payment amount',
fee: 'Payment fee',
type: 'Lightning payment'
})

24
app/components/Activity/PaymentModal/PaymentModal.js

@ -1,8 +1,6 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import FaAngleDown from 'react-icons/lib/fa/angle-down' import FaAngleDown from 'react-icons/lib/fa/angle-down'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
@ -11,6 +9,9 @@ import zap from 'icons/zap.svg'
import Value from 'components/Value' import Value from 'components/Value'
import { FormattedDate, FormattedTime, FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './PaymentModal.scss' import styles from './PaymentModal.scss'
const PaymentModal = ({ const PaymentModal = ({
@ -30,12 +31,14 @@ const PaymentModal = ({
<header className={styles.header}> <header className={styles.header}>
<section> <section>
<Isvg src={paperPlane} /> <Isvg src={paperPlane} />
<span>Sent</span> <FormattedMessage {...messages.sent} />
</section> </section>
<section className={styles.details}> <section className={styles.details}>
<div> <div>
<Isvg src={zap} /> <Isvg src={zap} />
<span className={styles.zap}>Lightning Network</span> <span className={styles.zap}>
<FormattedMessage {...messages.lightning} />
</span>
</div> </div>
<div> <div>
<Value <Value
@ -44,7 +47,10 @@ const PaymentModal = ({
currentTicker={currentTicker} currentTicker={currentTicker}
fiatTicker={ticker.fiatTicker} fiatTicker={ticker.fiatTicker}
/> />
<span> {currencyName} fee</span> <span>
{' '}
{currencyName} <FormattedMessage {...messages.fee} />
</span>
</div> </div>
</section> </section>
</header> </header>
@ -78,7 +84,13 @@ const PaymentModal = ({
</div> </div>
<div className={styles.date}> <div className={styles.date}>
<Moment format="LLL">{payment.creation_date * 1000}</Moment> <FormattedDate
value={new Date(payment.creation_date * 1000)}
year="numeric"
month="long"
day="2-digit"
/>{' '}
<FormattedTime value={new Date(payment.creation_date * 1000)} />
</div> </div>
<footer className={styles.footer}> <footer className={styles.footer}>

8
app/components/Activity/PaymentModal/messages.js

@ -0,0 +1,8 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
sent: 'Sent',
fee: 'Fee',
lightning: 'Lightning Network'
})

32
app/components/Activity/Transaction/Transaction.js

@ -1,37 +1,53 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import link from 'icons/link.svg' import link from 'icons/link.svg'
import { btc } from 'lib/utils' import { btc } from 'lib/utils'
import Value from 'components/Value' import Value from 'components/Value'
import { FormattedTime, FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from '../Activity.scss' import styles from '../Activity.scss'
const Transaction = ({ transaction, ticker, currentTicker, showActivityModal, currencyName }) => ( const Transaction = ({
transaction,
ticker,
currentTicker,
showActivityModal,
currencyName,
intl
}) => (
<div <div
className={styles.container} className={styles.container}
onClick={() => showActivityModal('TRANSACTION', transaction.tx_hash)} onClick={() => showActivityModal('TRANSACTION', transaction.tx_hash)}
> >
<div className={styles.activityTypeIcon}> <div className={styles.activityTypeIcon}>
<section className="hint--bottom" data-hint="On-chain transaction"> <section className="hint--bottom" data-hint={intl.formatMessage({ ...messages.type })}>
<Isvg src={link} /> <Isvg src={link} />
</section> </section>
</div> </div>
<div className={styles.data}> <div className={styles.data}>
<div className={styles.title}> <div className={styles.title}>
<h3>{transaction.received ? 'Received' : 'Sent'}</h3> <h3>
{transaction.received ? (
<FormattedMessage {...messages.received} />
) : (
<FormattedMessage {...messages.sent} />
)}
</h3>
</div> </div>
<div className={styles.subtitle}> <div className={styles.subtitle}>
<Moment format="h:mm a">{transaction.time_stamp * 1000}</Moment> <FormattedTime value={transaction.time_stamp * 1000} />
</div> </div>
</div> </div>
<div <div
className={`hint--top-left ${styles.amount} ${ className={`hint--top-left ${styles.amount} ${
transaction.received ? styles.positive : styles.negative transaction.received ? styles.positive : styles.negative
}`} }`}
data-hint="Transaction amount" data-hint={intl.formatMessage({ ...messages.amount })}
> >
<span> <span>
<i className={transaction.received ? styles.plus : styles.minus}> <i className={transaction.received ? styles.plus : styles.minus}>
@ -45,7 +61,7 @@ const Transaction = ({ transaction, ticker, currentTicker, showActivityModal, cu
/> />
<i> {currencyName}</i> <i> {currencyName}</i>
</span> </span>
<span className="hint--bottom" data-hint="Transaction fee"> <span className="hint--bottom" data-hint={intl.formatMessage({ ...messages.fee })}>
{currentTicker[ticker.fiatTicker].symbol} {currentTicker[ticker.fiatTicker].symbol}
{btc.convert('sats', 'fiat', transaction.amount, currentTicker[ticker.fiatTicker].last)} {btc.convert('sats', 'fiat', transaction.amount, currentTicker[ticker.fiatTicker].last)}
</span> </span>
@ -61,4 +77,4 @@ Transaction.propTypes = {
currencyName: PropTypes.string.isRequired currencyName: PropTypes.string.isRequired
} }
export default Transaction export default injectIntl(Transaction)

10
app/components/Activity/Transaction/messages.js

@ -0,0 +1,10 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
received: 'Received',
sent: 'Sent',
amount: 'Transaction amount',
fee: 'Transaction fee',
type: 'On-chain transaction'
})

30
app/components/Activity/TransactionModal/TransactionModal.js

@ -1,10 +1,6 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import FaAngleDown from 'react-icons/lib/fa/angle-down' import FaAngleDown from 'react-icons/lib/fa/angle-down'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import paperPlane from 'icons/paper_plane.svg' import paperPlane from 'icons/paper_plane.svg'
import hand from 'icons/hand.svg' import hand from 'icons/hand.svg'
@ -13,6 +9,9 @@ import { blockExplorer } from 'lib/utils'
import Value from 'components/Value' import Value from 'components/Value'
import { FormattedDate, FormattedTime, FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './TransactionModal.scss' import styles from './TransactionModal.scss'
const TransactionModal = ({ const TransactionModal = ({
@ -34,12 +33,16 @@ const TransactionModal = ({
{transaction.received ? ( {transaction.received ? (
<section> <section>
<Isvg src={hand} /> <Isvg src={hand} />
<span>Received</span> <span>
<FormattedMessage {...messages.received} />
</span>
</section> </section>
) : ( ) : (
<section> <section>
<Isvg src={paperPlane} /> <Isvg src={paperPlane} />
<span>Sent</span> <span>
<FormattedMessage {...messages.sent} />
</span>
</section> </section>
)} )}
<section className={styles.details}> <section className={styles.details}>
@ -49,7 +52,7 @@ const TransactionModal = ({
className={styles.link} className={styles.link}
onClick={() => blockExplorer.showTransaction(network, transaction.tx_hash)} onClick={() => blockExplorer.showTransaction(network, transaction.tx_hash)}
> >
On-Chain <FormattedMessage {...messages.on_chain} />
</span> </span>
</div> </div>
<div> <div>
@ -59,7 +62,10 @@ const TransactionModal = ({
currentTicker={currentTicker} currentTicker={currentTicker}
fiatTicker={ticker.fiatTicker} fiatTicker={ticker.fiatTicker}
/> />
<span> {currencyName} fee</span> <span>
{' '}
{currencyName} <FormattedMessage {...messages.fee} />
</span>
</div> </div>
</section> </section>
</header> </header>
@ -95,7 +101,13 @@ const TransactionModal = ({
</div> </div>
<div className={styles.date}> <div className={styles.date}>
<Moment format="LLL">{transaction.time_stamp * 1000}</Moment> <FormattedDate
value={new Date(transaction.time_stamp * 1000)}
year="numeric"
month="long"
day="2-digit"
/>{' '}
<FormattedTime value={new Date(transaction.time_stamp * 1000)} />
</div> </div>
<footer className={styles.footer}> <footer className={styles.footer}>

9
app/components/Activity/TransactionModal/messages.js

@ -0,0 +1,9 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
fee: 'Fee',
on_chain: 'On-Chain',
received: 'Received',
sent: 'Sent'
})

13
app/components/Activity/messages.js

@ -0,0 +1,13 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
all: 'All',
sent: 'Sent',
requested: 'Requested',
pending: 'Pending',
refresh: 'Refresh',
search: 'Search',
hide_expired: 'Hide Expired Requests',
show_expired: 'Show Expired Requests'
})

25
app/components/Contacts/AddChannel/AddChannel.js

@ -4,6 +4,9 @@ import Isvg from 'react-inlinesvg'
import x from 'icons/x.svg' import x from 'icons/x.svg'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './AddChannel.scss' import styles from './AddChannel.scss'
const AddChannel = ({ const AddChannel = ({
@ -35,7 +38,9 @@ const AddChannel = ({
if (activeChannelPubkeys.includes(node.pub_key)) { if (activeChannelPubkeys.includes(node.pub_key)) {
return ( return (
<span className={`${styles.online} ${styles.inactive}`}> <span className={`${styles.online} ${styles.inactive}`}>
<span>Online</span> <span>
<FormattedMessage {...messages.online} />
</span>
</span> </span>
) )
} }
@ -43,7 +48,9 @@ const AddChannel = ({
if (nonActiveChannelPubkeys.includes(node.pub_key)) { if (nonActiveChannelPubkeys.includes(node.pub_key)) {
return ( return (
<span className={`${styles.offline} ${styles.inactive}`}> <span className={`${styles.offline} ${styles.inactive}`}>
<span>Offline</span> <span>
<FormattedMessage {...messages.offline} />
</span>
</span> </span>
) )
} }
@ -51,13 +58,19 @@ const AddChannel = ({
if (pendingOpenChannelPubkeys.includes(node.pub_key)) { if (pendingOpenChannelPubkeys.includes(node.pub_key)) {
return ( return (
<span className={`${styles.pending} ${styles.inactive}`}> <span className={`${styles.pending} ${styles.inactive}`}>
<span>Pending</span> <span>
<FormattedMessage {...messages.pending} />
</span>
</span> </span>
) )
} }
if (!node.addresses.length) { if (!node.addresses.length) {
return <span className={`${styles.private} ${styles.inactive}`}>Private</span> return (
<span className={`${styles.private} ${styles.inactive}`}>
<FormattedMessage {...messages.private} />
</span>
)
} }
return ( return (
@ -128,10 +141,10 @@ const AddChannel = ({
{showManualForm && ( {showManualForm && (
<section className={styles.manualForm}> <section className={styles.manualForm}>
<p> <p>
Hm, looks like we can&apos;t see that node from here, wanna try to manually connect? <FormattedMessage {...messages.manual_description} />
</p> </p>
<div className={styles.manualConnectButton} onClick={openManualForm}> <div className={styles.manualConnectButton} onClick={openManualForm}>
Connect Manually <FormattedMessage {...messages.manual_button} />
</div> </div>
</section> </section>
)} )}

11
app/components/Contacts/AddChannel/messages.js

@ -0,0 +1,11 @@
import { defineMessages } from 'react-intl'
export default defineMessages({
online: 'Online',
offline: 'Offline',
pending: 'Pending',
private: 'Private',
manual_button: 'Connect Manually',
manual_description:
"Hm, looks like we can't see that node from here, wanna try to manually connect?"
})

21
app/components/Contacts/ConnectManually/ConnectManually.js

@ -1,5 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './ConnectManually.scss' import styles from './ConnectManually.scss'
class ConnectManually extends React.Component { class ConnectManually extends React.Component {
@ -15,7 +19,8 @@ class ConnectManually extends React.Component {
setNode, setNode,
showErrors showErrors,
intl
} = this.props } = this.props
const formSubmitted = () => { const formSubmitted = () => {
@ -48,15 +53,19 @@ class ConnectManually extends React.Component {
return ( return (
<div className={styles.content}> <div className={styles.content}>
<header className={styles.header}> <header className={styles.header}>
<h1>Connect Manually</h1> <h1>
<p>Please enter the peer&apos;s pubkey@host</p> <FormattedMessage {...messages.title} />
</h1>
<p>
<FormattedMessage {...messages.description} />
</p>
</header> </header>
<section className={styles.peer}> <section className={styles.peer}>
<div className={styles.input}> <div className={styles.input}>
<input <input
type="text" type="text"
placeholder="pubkey@host" placeholder={intl.formatMessage({ ...messages.placeholder })}
value={manualSearchQuery} value={manualSearchQuery}
onChange={event => updateManualFormSearchQuery(event.target.value)} onChange={event => updateManualFormSearchQuery(event.target.value)}
/> />
@ -76,7 +85,7 @@ class ConnectManually extends React.Component {
className={`${styles.button} ${manualFormIsValid.isValid ? styles.active : undefined}`} className={`${styles.button} ${manualFormIsValid.isValid ? styles.active : undefined}`}
onClick={formSubmitted} onClick={formSubmitted}
> >
Submit <FormattedMessage {...messages.submit} />
</div> </div>
</section> </section>
</div> </div>
@ -98,4 +107,4 @@ ConnectManually.propTypes = {
showErrors: PropTypes.object.isRequired showErrors: PropTypes.object.isRequired
} }
export default ConnectManually export default injectIntl(ConnectManually)

9
app/components/Contacts/ConnectManually/messages.js

@ -0,0 +1,9 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
title: 'Connect Manually',
description: 'Please enter the peer’s pubkey@host',
placeholder: 'pubkey@host',
submit: 'Submit'
})

39
app/components/Contacts/Network/Network.js

@ -10,6 +10,10 @@ import plus from 'icons/plus.svg'
import search from 'icons/search.svg' import search from 'icons/search.svg'
import Value from 'components/Value' import Value from 'components/Value'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import SuggestedNodes from '../SuggestedNodes' import SuggestedNodes from '../SuggestedNodes'
import styles from './Network.scss' import styles from './Network.scss'
@ -59,7 +63,8 @@ class Network extends Component {
network, network,
currencyName currencyName,
intl
} = this.props } = this.props
const refreshClicked = () => { const refreshClicked = () => {
@ -164,7 +169,9 @@ class Network extends Component {
<div className={styles.network}> <div className={styles.network}>
<header className={styles.header}> <header className={styles.header}>
<section> <section>
<h2>My Network</h2> <h2>
<FormattedMessage {...messages.title} />
</h2>
<span className={styles.channelAmount}> <span className={styles.channelAmount}>
<Value <Value
value={balance.channelBalance} value={balance.channelBalance}
@ -180,7 +187,7 @@ class Network extends Component {
<section <section
className={`${styles.addChannel} hint--bottom-left`} className={`${styles.addChannel} hint--bottom-left`}
onClick={openContactsForm} onClick={openContactsForm}
data-hint="Open a channel" data-hint={intl.formatMessage({ ...messages.open_channel })}
> >
<span className={styles.plusContainer}> <span className={styles.plusContainer}>
<Isvg src={plus} /> <Isvg src={plus} />
@ -214,7 +221,7 @@ class Network extends Component {
this.repeat = ref this.repeat = ref
}} }}
> >
{refreshing ? <FaRepeat /> : 'Refresh'} {refreshing ? <FaRepeat /> : <FormattedMessage {...messages.refresh} />}
</span> </span>
</section> </section>
</header> </header>
@ -238,7 +245,10 @@ class Network extends Component {
return ( return (
<li key={loadingPubkey} className={styles.channel}> <li key={loadingPubkey} className={styles.channel}>
<section className={styles.channelTitle}> <section className={styles.channelTitle}>
<span className={`${styles.loading} hint--right`} data-hint="loading"> <span
className={`${styles.loading} hint--right`}
data-hint={intl.formatMessage({ ...messages.loading })}
>
<i className={styles.spinner} /> <i className={styles.spinner} />
</span> </span>
<span>{nodeDisplay()}</span> <span>{nodeDisplay()}</span>
@ -264,7 +274,7 @@ class Network extends Component {
<section className={styles.channelTitle}> <section className={styles.channelTitle}>
<span <span
className={`${styles[channelStatus(channelObj)]} hint--right`} className={`${styles[channelStatus(channelObj)]} hint--right`}
data-hint={channelStatus(channelObj)} data-hint={intl.formatMessage({ ...messages[channelStatus(channelObj)] })}
> >
{closingChannelIds.includes(channel.chan_id) ? ( {closingChannelIds.includes(channel.chan_id) ? (
<span className={styles.loading}> <span className={styles.loading}>
@ -296,7 +306,9 @@ class Network extends Component {
<div className={styles.limits}> <div className={styles.limits}>
<section> <section>
<h5>Pay Limit</h5> <h5>
<FormattedMessage {...messages.pay_limit} />
</h5>
<p> <p>
<Value <Value
value={channel.local_balance} value={channel.local_balance}
@ -308,7 +320,9 @@ class Network extends Component {
</p> </p>
</section> </section>
<section> <section>
<h5>Request Limit</h5> <h5>
<FormattedMessage {...messages.req_limit} />
</h5>
<p> <p>
<Value <Value
value={channel.remote_balance} value={channel.remote_balance}
@ -323,7 +337,10 @@ class Network extends Component {
<div className={styles.actions}> <div className={styles.actions}>
{closingChannelIds.includes(channel.chan_id) && ( {closingChannelIds.includes(channel.chan_id) && (
<section> <section>
<span className={`${styles.loading} hint--right`} data-hint="closing"> <span
className={`${styles.loading} hint--right`}
data-hint={intl.formatMessage({ ...messages.closing })}
>
<i>Closing</i> <i className={`${styles.spinner} ${styles.closing}`} /> <i>Closing</i> <i className={`${styles.spinner} ${styles.closing}`} />
</span> </span>
</section> </section>
@ -350,7 +367,7 @@ class Network extends Component {
id="search" id="search"
type="text" type="text"
className={`${styles.text} ${styles.input}`} className={`${styles.text} ${styles.input}`}
placeholder="search by alias or pubkey" placeholder={intl.formatMessage({ ...messages.search_placeholder })}
value={searchQuery} value={searchQuery}
onChange={event => updateChannelSearchQuery(event.target.value)} onChange={event => updateChannelSearchQuery(event.target.value)}
/> />
@ -385,4 +402,4 @@ Network.propTypes = {
currencyName: PropTypes.string.isRequired currencyName: PropTypes.string.isRequired
} }
export default Network export default injectIntl(Network)

16
app/components/Contacts/Network/messages.js

@ -0,0 +1,16 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
title: 'My Network',
loading: 'loading',
pending: 'pending',
closing: 'closing',
offline: 'offline',
online: 'online',
refresh: 'Refresh',
open_channel: 'Open a channel',
pay_limit: 'Pay Limit',
req_limit: 'Request Limit',
search_placeholder: 'search by alias or pubkey'
})

30
app/components/Contacts/SubmitChannelForm/SubmitChannelForm.js

@ -5,6 +5,10 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import FaExclamationCircle from 'react-icons/lib/fa/exclamation-circle' import FaExclamationCircle from 'react-icons/lib/fa/exclamation-circle'
import AmountInput from 'components/AmountInput' import AmountInput from 'components/AmountInput'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './SubmitChannelForm.scss' import styles from './SubmitChannelForm.scss'
class SubmitChannelForm extends React.Component { class SubmitChannelForm extends React.Component {
@ -55,16 +59,18 @@ class SubmitChannelForm extends React.Component {
const renderWarning = dupeChanInfo => { const renderWarning = dupeChanInfo => {
const { alias, activeChannels, capacity, currencyName } = dupeChanInfo const { alias, activeChannels, capacity, currencyName } = dupeChanInfo
const aliasMsg = alias ? <span className={styles.alias}>{alias}</span> : 'this_node'
const chansMsg =
activeChannels === 1 ? ' an active channel ' : ` ${activeChannels} active channels `
const aliasMsg = alias ? <span className={styles.alias}>{alias}</span> : ' this node '
return ( return (
<p> <p>
{`You currently have ${chansMsg} open to `} <FormattedMessage
{aliasMsg} {...messages.duplicate_warnig}
{` with a capacity of ${capacity} ${currencyName}.`} values={{
activeChannels,
aliasMsg
}}
/>{' '}
{capacity} {currencyName}.
</p> </p>
) )
} }
@ -92,11 +98,11 @@ class SubmitChannelForm extends React.Component {
return ( return (
<div className={styles.content}> <div className={styles.content}>
<header className={styles.header}> <header className={styles.header}>
<h1>Add Funds to Network</h1> <h1>
<FormattedMessage {...messages.title} />
</h1>
<p> <p>
Opening a channel will help you send and receive money on the Lightning Network. You <FormattedMessage {...messages.description} />
aren&apos;t spending any money, rather moving the money you plan to use onto the
network.
</p> </p>
</header> </header>
@ -148,7 +154,7 @@ class SubmitChannelForm extends React.Component {
className={`${styles.button} ${contactCapacity > 0 ? styles.active : undefined}`} className={`${styles.button} ${contactCapacity > 0 ? styles.active : undefined}`}
onClick={formSubmitted} onClick={formSubmitted}
> >
Submit <FormattedMessage {...messages.submit} />
</div> </div>
</section> </section>
</div> </div>

11
app/components/Contacts/SubmitChannelForm/messages.js

@ -0,0 +1,11 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
title: 'Add Funds to Network',
description:
"Opening a channel will help you send and receive money on the Lightning Network. You aren't spending any money, rather moving the money you plan to use onto the network.",
submit: 'Submit',
duplicate_warnig:
'You currently have {activeChannels, plural, zero {no active channels} one {1 active channel} other {{activeChannels} active channels}} open to {aliasMsg, select, this_node {this node} other {{aliasMsg}}} with a capacity of'
})

11
app/components/Contacts/SuggestedNodes/SuggestedNodes.js

@ -1,5 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './SuggestedNodes.scss' import styles from './SuggestedNodes.scss'
const SuggestedNodes = ({ const SuggestedNodes = ({
@ -27,8 +31,7 @@ const SuggestedNodes = ({
return ( return (
<div className={styles.container}> <div className={styles.container}>
<header> <header>
Hmmm, looks like you don&apos;t have any channels yet. Here are some suggested nodes to open <FormattedMessage {...messages.empty_description} />
a channel with to get started
</header> </header>
<ul className={styles.suggestedNodes}> <ul className={styles.suggestedNodes}>
@ -39,7 +42,9 @@ const SuggestedNodes = ({
<span>{`${node.pubkey.substring(0, 30)}...`}</span> <span>{`${node.pubkey.substring(0, 30)}...`}</span>
</section> </section>
<section> <section>
<span onClick={() => nodeClicked(node)}>Connect</span> <span onClick={() => nodeClicked(node)}>
<FormattedMessage {...messages.connect} />
</span>
</section> </section>
</li> </li>
))} ))}

8
app/components/Contacts/SuggestedNodes/messages.js

@ -0,0 +1,8 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
connect: 'Connect',
empty_description:
"Hmmm, looks like you don't have any channels yet. Here are some suggested nodes to open a channel with to get started"
})

28
app/components/Form/Pay/Pay.js

@ -9,6 +9,9 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import { btc } from 'lib/utils' import { btc } from 'lib/utils'
import AmountInput from 'components/AmountInput' import AmountInput from 'components/AmountInput'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './Pay.scss' import styles from './Pay.scss'
class Pay extends Component { class Pay extends Component {
@ -65,7 +68,8 @@ class Pay extends Component {
onPaySubmit, onPaySubmit,
setCurrency setCurrency,
intl
} = this.props } = this.props
const displayNodeName = pubkey => { const displayNodeName = pubkey => {
@ -92,20 +96,26 @@ class Pay extends Component {
<div className={styles.container}> <div className={styles.container}>
<header className={styles.header}> <header className={styles.header}>
<Isvg src={paperPlane} /> <Isvg src={paperPlane} />
<h1>Make Payment</h1> <h1>
<FormattedMessage {...messages.title} />
</h1>
</header> </header>
<div className={styles.content}> <div className={styles.content}>
<section className={styles.destination}> <section className={styles.destination}>
<div className={styles.top}> <div className={styles.top}>
<label htmlFor="paymentRequest">Destination</label> <label htmlFor="paymentRequest">
<FormattedMessage {...messages.destination} />
</label>
<span <span
className={`${styles.description} ${isOnchain || isLn ? styles.active : undefined}`} className={`${styles.description} ${isOnchain || isLn ? styles.active : undefined}`}
> >
{isOnchain && ( {isOnchain && (
<i> <i>
<Isvg src={link} /> <Isvg src={link} />
<span>On-Chain (~10 minutes)</span> <span>
<FormattedMessage {...messages.onchain_description} />
</span>
</i> </i>
)} )}
{isLn && ( {isLn && (
@ -120,7 +130,7 @@ class Pay extends Component {
<div className={styles.bottom}> <div className={styles.bottom}>
<textarea <textarea
type="text" type="text"
placeholder="Paste payment request or bitcoin address here" placeholder={intl.formatMessage({ ...messages.request_placeholder })}
value={payInput} value={payInput}
onChange={event => setPayInput(event.target.value)} onChange={event => setPayInput(event.target.value)}
onBlur={onPayInputBlur} onBlur={onPayInputBlur}
@ -140,7 +150,9 @@ class Pay extends Component {
<section className={styles.amount}> <section className={styles.amount}>
<div className={styles.top}> <div className={styles.top}>
<label htmlFor="amount">Amount</label> <label htmlFor="amount">
<FormattedMessage {...messages.amount} />
</label>
<span /> <span />
</div> </div>
<div className={styles.bottom}> <div className={styles.bottom}>
@ -188,7 +200,7 @@ class Pay extends Component {
className={`${styles.button} ${isValid ? styles.active : undefined}`} className={`${styles.button} ${isValid ? styles.active : undefined}`}
onClick={onPaySubmit} onClick={onPaySubmit}
> >
Pay <FormattedMessage {...messages.pay} />
</div> </div>
</section> </section>
</div> </div>
@ -231,4 +243,4 @@ Pay.propTypes = {
currentCurrencyFilters: PropTypes.array.isRequired currentCurrencyFilters: PropTypes.array.isRequired
} }
export default Pay export default injectIntl(Pay)

11
app/components/Form/Pay/messages.js

@ -0,0 +1,11 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
title: 'Make Payment',
destination: 'Destination',
amount: 'Amount',
request_placeholder: 'Paste payment request or bitcoin address here',
pay: 'Pay',
onchain_description: 'On-Chain (~10 minutes)'
})

25
app/components/Form/Request/Request.js

@ -7,6 +7,10 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import { btc } from 'lib/utils' import { btc } from 'lib/utils'
import AmountInput from 'components/AmountInput' import AmountInput from 'components/AmountInput'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './Request.scss' import styles from './Request.scss'
const Request = ({ const Request = ({
@ -22,7 +26,8 @@ const Request = ({
currentCurrencyFilters, currentCurrencyFilters,
onRequestSubmit onRequestSubmit,
intl
}) => { }) => {
const onCurrencyFilterClick = currency => { const onCurrencyFilterClick = currency => {
// change the input amount // change the input amount
@ -36,13 +41,17 @@ const Request = ({
<div className={styles.container}> <div className={styles.container}>
<header className={styles.header}> <header className={styles.header}>
<Isvg src={hand} /> <Isvg src={hand} />
<h1>Request Payment</h1> <h1>
<FormattedMessage {...messages.title} />
</h1>
</header> </header>
<div className={styles.content}> <div className={styles.content}>
<section className={styles.amount}> <section className={styles.amount}>
<div className={styles.top}> <div className={styles.top}>
<label htmlFor="amount">Amount</label> <label htmlFor="amount">
<FormattedMessage {...messages.amount} />
</label>
<span /> <span />
</div> </div>
<div className={styles.bottom}> <div className={styles.bottom}>
@ -79,12 +88,14 @@ const Request = ({
<section className={styles.memo}> <section className={styles.memo}>
<div className={styles.top}> <div className={styles.top}>
<label htmlFor="memo">Memo</label> <label htmlFor="memo">
<FormattedMessage {...messages.memo} />
</label>
</div> </div>
<div className={styles.bottom}> <div className={styles.bottom}>
<input <input
type="text" type="text"
placeholder="Details about the request" placeholder={intl.formatMessage({ ...messages.details })}
value={memo} value={memo}
onChange={event => setRequestMemo(event.target.value)} onChange={event => setRequestMemo(event.target.value)}
id="memo" id="memo"
@ -97,7 +108,7 @@ const Request = ({
className={`${styles.button} ${amount > 0 ? styles.active : undefined}`} className={`${styles.button} ${amount > 0 ? styles.active : undefined}`}
onClick={onRequestSubmit} onClick={onRequestSubmit}
> >
Request <FormattedMessage {...messages.request} />
</div> </div>
</section> </section>
</div> </div>
@ -125,4 +136,4 @@ Request.propTypes = {
ticker: PropTypes.object.isRequired ticker: PropTypes.object.isRequired
} }
export default Request export default injectIntl(Request)

9
app/components/Form/Request/messages.js

@ -0,0 +1,9 @@
import { defineMessages } from 'react-intl'
export default defineMessages({
title: 'Request Payment',
amount: 'Amount',
memo: 'Memo',
details: 'Details about the request',
request: 'Request'
})

7
app/components/LoadingBolt/LoadingBolt.js

@ -3,13 +3,18 @@ import Isvg from 'react-inlinesvg'
import cloudboltIcon from 'icons/cloudbolt.svg' import cloudboltIcon from 'icons/cloudbolt.svg'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './LoadingBolt.scss' import styles from './LoadingBolt.scss'
const LoadingBolt = () => ( const LoadingBolt = () => (
<div className={styles.container}> <div className={styles.container}>
<div className={styles.content}> <div className={styles.content}>
<Isvg className={styles.bolt} src={cloudboltIcon} /> <Isvg className={styles.bolt} src={cloudboltIcon} />
<h1>loading</h1> <h1>
<FormattedMessage {...messages.loading} />
</h1>
</div> </div>
</div> </div>
) )

6
app/components/LoadingBolt/messages.js

@ -0,0 +1,6 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
loading: 'loading'
})

10
app/components/Onboarding/Autopilot/Autopilot.js

@ -2,6 +2,8 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import FaCircle from 'react-icons/lib/fa/circle' import FaCircle from 'react-icons/lib/fa/circle'
import FaCircleThin from 'react-icons/lib/fa/circle-thin' import FaCircleThin from 'react-icons/lib/fa/circle-thin'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Autopilot.scss' import styles from './Autopilot.scss'
const Autopilot = ({ autopilot, setAutopilot }) => ( const Autopilot = ({ autopilot, setAutopilot }) => (
@ -9,7 +11,9 @@ const Autopilot = ({ autopilot, setAutopilot }) => (
<section className={`${styles.enable} ${autopilot ? styles.active : undefined}`}> <section className={`${styles.enable} ${autopilot ? styles.active : undefined}`}>
<div onClick={() => setAutopilot(true)}> <div onClick={() => setAutopilot(true)}>
{autopilot ? <FaCircle /> : <FaCircleThin />} {autopilot ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Enable Autopilot</span> <span className={styles.label}>
<FormattedMessage {...messages.enable} /> Autopilot
</span>
</div> </div>
</section> </section>
<section <section
@ -19,7 +23,9 @@ const Autopilot = ({ autopilot, setAutopilot }) => (
> >
<div onClick={() => setAutopilot(false)}> <div onClick={() => setAutopilot(false)}>
{!autopilot && autopilot !== null ? <FaCircle /> : <FaCircleThin />} {!autopilot && autopilot !== null ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Disable Autopilot</span> <span className={styles.label}>
<FormattedMessage {...messages.disable} /> Autopilot
</span>
</div> </div>
</section> </section>
</div> </div>

7
app/components/Onboarding/Autopilot/messages.js

@ -0,0 +1,7 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
enable: 'Enable',
disable: 'Disable'
})

21
app/components/Onboarding/BtcPayServer/BtcPayServer.js

@ -1,21 +1,28 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './BtcPayServer.scss' import styles from './BtcPayServer.scss'
const BtcPayServer = ({ const BtcPayServer = ({
connectionString, connectionString,
connectionStringIsValid, connectionStringIsValid,
setConnectionString, setConnectionString,
startLndHostError startLndHostError,
intl
}) => ( }) => (
<div className={styles.container}> <div className={styles.container}>
<section className={styles.input}> <section className={styles.input}>
<label htmlFor="connectionString">Connection String:</label> <label htmlFor="connectionString">
<FormattedMessage {...messages.connection_string_label} />:
</label>
<textarea <textarea
type="text" type="text"
id="connectionString" id="connectionString"
rows="10" rows="10"
placeholder="BTCPay Server Connection String" placeholder={intl.formatMessage({ ...messages.connection_string_placeholder })}
className={ className={
connectionString && (startLndHostError || !connectionStringIsValid) connectionString && (startLndHostError || !connectionStringIsValid)
? styles.error ? styles.error
@ -26,16 +33,14 @@ const BtcPayServer = ({
onChange={event => setConnectionString(event.target.value)} onChange={event => setConnectionString(event.target.value)}
/> />
<p className={styles.description}> <p className={styles.description}>
Paste the full content of your BTCPay Server connection config file. This can be found by <FormattedMessage {...messages.btcpay_description} />
clicking the link entitled &quot;Click here to open the configuration file.&quot; in your
BTCPay Server gRPC settings.
</p> </p>
<p <p
className={`${styles.errorMessage} ${ className={`${styles.errorMessage} ${
connectionString && !connectionStringIsValid ? styles.visible : undefined connectionString && !connectionStringIsValid ? styles.visible : undefined
}`} }`}
> >
Invalid connection string. <FormattedMessage {...messages.btcpay_error} />
</p> </p>
<p <p
className={`${styles.errorMessage} ${ className={`${styles.errorMessage} ${
@ -55,4 +60,4 @@ BtcPayServer.propTypes = {
startLndHostError: PropTypes.string startLndHostError: PropTypes.string
} }
export default BtcPayServer export default injectIntl(BtcPayServer)

10
app/components/Onboarding/BtcPayServer/messages.js

@ -0,0 +1,10 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
btcpay_description:
"Paste the full content of your BTCPay Server connection config file. This can be found by clicking the link entitled 'Click here to open the configuration file' in your BTCPay Server gRPC settings.",
btcpay_error: 'Invalid connection string.',
connection_string_label: 'Connection String',
connection_string_placeholder: 'BTCPay Server Connection String'
})

8
app/components/Onboarding/ConnectionConfirm/ConnectionConfirm.js

@ -1,15 +1,19 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './ConnectionConfirm.scss' import styles from './ConnectionConfirm.scss'
const ConnectionConfirm = ({ connectionHost }) => ( const ConnectionConfirm = ({ connectionHost }) => (
<div className={styles.container}> <div className={styles.container}>
<p> <p>
Are you sure you want to connect to{' '} <FormattedMessage {...messages.verify_host_title} />{' '}
<span className={styles.host}>{connectionHost.split(':')[0]}</span>?{' '} <span className={styles.host}>{connectionHost.split(':')[0]}</span>?{' '}
</p> </p>
<p> <p>
<strong>Please check the hostname carefully.</strong> <strong>
<FormattedMessage {...messages.verify_host_description} />
</strong>
</p> </p>
</div> </div>
) )

7
app/components/Onboarding/ConnectionConfirm/messages.js

@ -0,0 +1,7 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
verify_host_title: 'Are you sure you want to connect to',
verify_host_description: 'Please check the hostname carefully.'
})

18
app/components/Onboarding/ConnectionDetails/ConnectionDetails.js

@ -1,5 +1,7 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './ConnectionDetails.scss' import styles from './ConnectionDetails.scss'
const ConnectionDetails = ({ const ConnectionDetails = ({
@ -15,7 +17,9 @@ const ConnectionDetails = ({
}) => ( }) => (
<div className={styles.container}> <div className={styles.container}>
<section className={styles.input}> <section className={styles.input}>
<label htmlFor="connectionHost">Host:</label> <label htmlFor="connectionHost">
<FormattedMessage {...messages.hostname_title} />:
</label>
<input <input
type="text" type="text"
id="connectionHost" id="connectionHost"
@ -25,14 +29,16 @@ const ConnectionDetails = ({
onChange={event => setConnectionHost(event.target.value)} onChange={event => setConnectionHost(event.target.value)}
/> />
<p className={styles.description}> <p className={styles.description}>
Hostname and port of the Lnd gRPC interface. Example: localhost:10009 <FormattedMessage {...messages.hostname_description} />
</p> </p>
<p className={`${startLndHostError ? styles.visible : undefined} ${styles.errorMessage}`}> <p className={`${startLndHostError ? styles.visible : undefined} ${styles.errorMessage}`}>
{startLndHostError} {startLndHostError}
</p> </p>
</section> </section>
<section className={styles.input}> <section className={styles.input}>
<label htmlFor="connectionCert">TLS Certificate:</label> <label htmlFor="connectionCert">
<FormattedMessage {...messages.cert_title} />:
</label>
<input <input
type="text" type="text"
id="connectionCert" id="connectionCert"
@ -41,7 +47,9 @@ const ConnectionDetails = ({
value={connectionCert} value={connectionCert}
onChange={event => setConnectionCert(event.target.value)} onChange={event => setConnectionCert(event.target.value)}
/> />
<p className={styles.description}>Path to the lnd tls cert. Example: /path/to/tls.cert</p> <p className={styles.description}>
<FormattedMessage {...messages.cert_description} />
</p>
<p className={`${startLndCertError ? styles.visible : undefined} ${styles.errorMessage}`}> <p className={`${startLndCertError ? styles.visible : undefined} ${styles.errorMessage}`}>
{startLndCertError} {startLndCertError}
</p> </p>
@ -57,7 +65,7 @@ const ConnectionDetails = ({
onChange={event => setConnectionMacaroon(event.target.value)} onChange={event => setConnectionMacaroon(event.target.value)}
/> />
<p className={styles.description}> <p className={styles.description}>
Path to the lnd macaroon file. Example: /path/to/admin.macaroon <FormattedMessage {...messages.macaroon_description} />
</p> </p>
<p className={`${startLndMacaroonError ? styles.visible : undefined} ${styles.errorMessage}`}> <p className={`${startLndMacaroonError ? styles.visible : undefined} ${styles.errorMessage}`}>
{startLndMacaroonError} {startLndMacaroonError}

10
app/components/Onboarding/ConnectionDetails/messages.js

@ -0,0 +1,10 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
hostname_title: 'Host',
hostname_description: 'Hostname and port of the Lnd gRPC interface. Example: localhost:10009',
cert_title: 'TLS Certificate',
cert_description: 'Path to the lnd tls cert. Example: /path/to/tls.cert',
macaroon_description: 'Path to the lnd macaroon file. Example: /path/to/admin.macaroon'
})

18
app/components/Onboarding/ConnectionType/ConnectionType.js

@ -2,6 +2,8 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import FaCircle from 'react-icons/lib/fa/circle' import FaCircle from 'react-icons/lib/fa/circle'
import FaCircleThin from 'react-icons/lib/fa/circle-thin' import FaCircleThin from 'react-icons/lib/fa/circle-thin'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './ConnectionType.scss' import styles from './ConnectionType.scss'
const ConnectionType = ({ connectionType, setConnectionType }) => ( const ConnectionType = ({ connectionType, setConnectionType }) => (
@ -12,13 +14,14 @@ const ConnectionType = ({ connectionType, setConnectionType }) => (
<div className={`${styles.button}`} onClick={() => setConnectionType('local')}> <div className={`${styles.button}`} onClick={() => setConnectionType('local')}>
{connectionType === 'local' ? <FaCircle /> : <FaCircleThin />} {connectionType === 'local' ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}> <span className={styles.label}>
Default <span className={styles.superscript}>testnet</span> <FormattedMessage {...messages.default} />{' '}
<span className={styles.superscript}>testnet</span>
</span> </span>
</div> </div>
<div className={`${styles.description}`}> <div className={`${styles.description}`}>
By selecting the defualt mode we will do everything for you. Just click and go! <FormattedMessage {...messages.default_description} />
<br /> <br />
(testnet only) (testnet <FormattedMessage {...messages.only} />)
</div> </div>
</section> </section>
<section <section
@ -26,11 +29,12 @@ const ConnectionType = ({ connectionType, setConnectionType }) => (
> >
<div className={`${styles.button}`} onClick={() => setConnectionType('custom')}> <div className={`${styles.button}`} onClick={() => setConnectionType('custom')}>
{connectionType === 'custom' ? <FaCircle /> : <FaCircleThin />} {connectionType === 'custom' ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Custom</span> <span className={styles.label}>
<FormattedMessage {...messages.custom} />
</span>
</div> </div>
<div className={`${styles.description}`}> <div className={`${styles.description}`}>
Connect to your own node. You will need to provide your own connection settings so this is <FormattedMessage {...messages.custom_description} />
for advanced users only.
</div> </div>
</section> </section>
<section className={`${styles.option} ${connectionType === 'btcpayserver' && styles.active}`}> <section className={`${styles.option} ${connectionType === 'btcpayserver' && styles.active}`}>
@ -39,7 +43,7 @@ const ConnectionType = ({ connectionType, setConnectionType }) => (
<span className={styles.label}>BTCPay Server</span> <span className={styles.label}>BTCPay Server</span>
</div> </div>
<div className={`${styles.description}`}> <div className={`${styles.description}`}>
Connect to your own BTCPay Server instance to access your BTCPay Server wallet. <FormattedMessage {...messages.btcpay_description} />
</div> </div>
</section> </section>
</div> </div>

14
app/components/Onboarding/ConnectionType/messages.js

@ -0,0 +1,14 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
default: 'Default',
default_description:
'By selecting the defualt mode we will do everything for you. Just click and go!',
only: 'only',
custom: 'Custom',
custom_description:
'Connect to your own node. You will need to provide your own connection settings so this is for advanced users only.',
btcpay_description:
'Connect to your own BTCPay Server instance to access your BTCPay Server wallet.'
})

14
app/components/Onboarding/FormContainer/FormContainer.js

@ -7,6 +7,8 @@ import FaAngleLeft from 'react-icons/lib/fa/angle-left'
import FaAngleRight from 'react-icons/lib/fa/angle-right' import FaAngleRight from 'react-icons/lib/fa/angle-right'
import zapLogo from 'icons/zap_logo.svg' import zapLogo from 'icons/zap_logo.svg'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './FormContainer.scss' import styles from './FormContainer.scss'
const FormContainer = ({ title, description, back, next, children }) => ( const FormContainer = ({ title, description, back, next, children }) => (
@ -24,7 +26,7 @@ const FormContainer = ({ title, description, back, next, children }) => (
shell.openExternal('https://ln-zap.github.io/zap-tutorials/zap-desktop-getting-started') shell.openExternal('https://ln-zap.github.io/zap-tutorials/zap-desktop-getting-started')
} }
> >
Need help? <FormattedMessage {...messages.help} />
</div> </div>
</section> </section>
</header> </header>
@ -41,14 +43,16 @@ const FormContainer = ({ title, description, back, next, children }) => (
<section> <section>
{back && ( {back && (
<div onClick={back} className={styles.backButton}> <div onClick={back} className={styles.backButton}>
<FaAngleLeft style={{ verticalAlign: 'top' }} /> Back <FaAngleLeft style={{ verticalAlign: 'top' }} />{' '}
<FormattedMessage {...messages.back} />
</div> </div>
)} )}
</section> </section>
<section> <section>
{next && ( {next && (
<div onClick={next} className={styles.nextButton}> <div onClick={next} className={styles.nextButton}>
Next <FaAngleRight style={{ verticalAlign: 'top' }} /> <FormattedMessage {...messages.next} />{' '}
<FaAngleRight style={{ verticalAlign: 'top' }} />
</div> </div>
)} )}
</section> </section>
@ -58,8 +62,8 @@ const FormContainer = ({ title, description, back, next, children }) => (
) )
FormContainer.propTypes = { FormContainer.propTypes = {
title: PropTypes.string.isRequired, title: PropTypes.node.isRequired,
description: PropTypes.string.isRequired, description: PropTypes.node.isRequired,
back: PropTypes.func, back: PropTypes.func,
next: PropTypes.func, next: PropTypes.func,

8
app/components/Onboarding/FormContainer/messages.js

@ -0,0 +1,8 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
help: 'Need Help?',
next: 'Next',
back: 'back'
})

21
app/components/Onboarding/Login/Login.js

@ -1,12 +1,21 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './Login.scss' import styles from './Login.scss'
const Login = ({ password, updatePassword, unlockingWallet, unlockWallet, unlockWalletError }) => ( const Login = ({
password,
updatePassword,
unlockingWallet,
unlockWallet,
unlockWalletError,
intl
}) => (
<div className={styles.container}> <div className={styles.container}>
<input <input
type="password" type="password"
placeholder="Password" placeholder={intl.formatMessage({ ...messages.password_placeholder })}
className={`${styles.password} ${unlockWalletError.isError ? styles.inputError : undefined}`} className={`${styles.password} ${unlockWalletError.isError ? styles.inputError : undefined}`}
ref={input => input && input.focus()} ref={input => input && input.focus()}
value={password} value={password}
@ -27,7 +36,11 @@ const Login = ({ password, updatePassword, unlockingWallet, unlockWallet, unlock
className={`${!unlockingWallet ? styles.active : undefined} ${styles.button}`} className={`${!unlockingWallet ? styles.active : undefined} ${styles.button}`}
onClick={() => unlockWallet(password)} onClick={() => unlockWallet(password)}
> >
{unlockingWallet ? <i className={styles.spinner} /> : 'Unlock'} {unlockingWallet ? (
<i className={styles.spinner} />
) : (
<FormattedMessage {...messages.unlock} />
)}
</span> </span>
</div> </div>
</section> </section>
@ -42,4 +55,4 @@ Login.propTypes = {
unlockWalletError: PropTypes.object.isRequired unlockWalletError: PropTypes.object.isRequired
} }
export default Login export default injectIntl(Login)

7
app/components/Onboarding/Login/messages.js

@ -0,0 +1,7 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
password_placeholder: 'Password',
unlock: 'Unlock'
})

20
app/components/Onboarding/NewWalletPassword/NewWalletPassword.js

@ -1,5 +1,7 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './NewWalletPassword.scss' import styles from './NewWalletPassword.scss'
const NewWalletPassword = ({ const NewWalletPassword = ({
@ -8,13 +10,14 @@ const NewWalletPassword = ({
showCreateWalletPasswordConfirmationError, showCreateWalletPasswordConfirmationError,
passwordMinCharsError, passwordMinCharsError,
updateCreateWalletPassword, updateCreateWalletPassword,
updateCreateWalletPasswordConfirmation updateCreateWalletPasswordConfirmation,
intl
}) => ( }) => (
<div className={styles.container}> <div className={styles.container}>
<section className={styles.input}> <section className={styles.input}>
<input <input
type="password" type="password"
placeholder="Password" placeholder={intl.formatMessage({ ...messages.password_placeholder })}
className={`${styles.password} ${ className={`${styles.password} ${
showCreateWalletPasswordConfirmationError ? styles.error : undefined showCreateWalletPasswordConfirmationError ? styles.error : undefined
} }
@ -27,7 +30,7 @@ const NewWalletPassword = ({
<section className={styles.input}> <section className={styles.input}>
<input <input
type="password" type="password"
placeholder="Confirm Password" placeholder={intl.formatMessage({ ...messages.password_confirm_placeholder })}
className={`${styles.password} ${ className={`${styles.password} ${
showCreateWalletPasswordConfirmationError ? styles.error : undefined showCreateWalletPasswordConfirmationError ? styles.error : undefined
} }
@ -40,10 +43,15 @@ const NewWalletPassword = ({
showCreateWalletPasswordConfirmationError ? styles.visible : undefined showCreateWalletPasswordConfirmationError ? styles.visible : undefined
}`} }`}
> >
Passwords do not match <FormattedMessage {...messages.password_error_match} />
</p> </p>
<p className={`${styles.helpMessage} ${passwordMinCharsError ? styles.red : undefined}`}> <p className={`${styles.helpMessage} ${passwordMinCharsError ? styles.red : undefined}`}>
Password must be at least 8 characters long <FormattedMessage
{...messages.password_error_length}
values={{
passwordMinLength: '8'
}}
/>
</p> </p>
</section> </section>
</div> </div>
@ -58,4 +66,4 @@ NewWalletPassword.propTypes = {
updateCreateWalletPasswordConfirmation: PropTypes.func.isRequired updateCreateWalletPasswordConfirmation: PropTypes.func.isRequired
} }
export default NewWalletPassword export default injectIntl(NewWalletPassword)

10
app/components/Onboarding/NewWalletPassword/messages.js

@ -0,0 +1,10 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
password_placeholder: 'Password',
password_confirm_placeholder: 'Confirm Password',
password_error_match: 'Passwords do not match',
password_error_length: 'Password must be at least {passwordMinLength} characters long',
unlock: 'Unlock'
})

87
app/components/Onboarding/Onboarding.js

@ -1,7 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import LoadingBolt from 'components/LoadingBolt' import LoadingBolt from 'components/LoadingBolt'
import messages from './messages'
import FormContainer from './FormContainer' import FormContainer from './FormContainer'
import ConnectionType from './ConnectionType' import ConnectionType from './ConnectionType'
@ -54,12 +56,8 @@ const Onboarding = ({
case 0.1: case 0.1:
return ( return (
<FormContainer <FormContainer
title="How do you want to connect to the Lightning Network?" title={<FormattedMessage {...messages.connection_title} />}
description=" description={<FormattedMessage {...messages.connection_description} />}
By default Zap will spin up a node for you and handle all the nerdy stuff
in the background. However you can also setup a custom node connection and
use Zap to control a remote node if you desire (for advanced users).
"
back={null} back={null}
next={() => { next={() => {
switch (connectionType) { switch (connectionType) {
@ -81,8 +79,8 @@ const Onboarding = ({
case 0.2: case 0.2:
return ( return (
<FormContainer <FormContainer
title="Connection details" title={<FormattedMessage {...messages.connection_details_custom_title} />}
description="Enter the connection details for your Lightning node." description={<FormattedMessage {...messages.connection_details_custom_description} />}
back={() => changeStep(0.1)} back={() => changeStep(0.1)}
next={() => { next={() => {
// dont allow the user to move on if we don't at least have a hostname. // dont allow the user to move on if we don't at least have a hostname.
@ -100,8 +98,8 @@ const Onboarding = ({
case 0.3: case 0.3:
return ( return (
<FormContainer <FormContainer
title="BTCPay Server" title={<FormattedMessage {...messages.btcpay_title} />}
description="Enter the connection details for your BTCPay Server node." description={<FormattedMessage {...messages.btcpay_description} />}
back={() => changeStep(0.1)} back={() => changeStep(0.1)}
next={() => { next={() => {
// dont allow the user to move on if the connection string is invalid. // dont allow the user to move on if the connection string is invalid.
@ -119,8 +117,8 @@ const Onboarding = ({
case 0.4: case 0.4:
return ( return (
<FormContainer <FormContainer
title="Confirm connection" title={<FormattedMessage {...messages.confirm_connection_title} />}
description="Confirm the connection details for your Lightning node." description={<FormattedMessage {...messages.confirm_connection_description} />}
back={() => changeStep(previousStep)} back={() => changeStep(previousStep)}
next={() => { next={() => {
startLnd({ startLnd({
@ -139,8 +137,8 @@ const Onboarding = ({
case 1: case 1:
return ( return (
<FormContainer <FormContainer
title="What should we call you?" title={<FormattedMessage {...messages.alias_title} />}
description="Set your nickname to help others connect with you on the Lightning Network" description={<FormattedMessage {...messages.alias_description} />}
back={() => changeStep(0.1)} back={() => changeStep(0.1)}
next={() => changeStep(2)} next={() => changeStep(2)}
> >
@ -150,8 +148,8 @@ const Onboarding = ({
case 2: case 2:
return ( return (
<FormContainer <FormContainer
title="Autopilot" title={<FormattedMessage {...messages.autopilot_title} />}
description="Autopilot is an automatic network manager. Instead of manually adding people to build your network to make payments, enable autopilot to automatically connect you to the Lightning Network using 60% of your balance." // eslint-disable-line max-len description={<FormattedMessage {...messages.autopilot_description} />}
back={() => changeStep(1)} back={() => changeStep(1)}
next={() => startLnd({ type: connectionType, alias, autopilot })} next={() => startLnd({ type: connectionType, alias, autopilot })}
> >
@ -159,24 +157,31 @@ const Onboarding = ({
</FormContainer> </FormContainer>
) )
case 3: case 3:
// eslint-disable-next-line no-case-declarations
let message = 'It looks like you already have a wallet'
if (initWalletProps.loginProps.existingWalletDir && connectionType === 'local') {
message += ` (we found one at ${initWalletProps.loginProps.existingWalletDir})`
} else {
message += ` at ${connectionHost.split(':')[0]}`
}
message += '. Please enter your wallet password to unlock it.'
return ( return (
<FormContainer title="Welcome back!" description={`${message}`} back={null} next={null}> <FormContainer
title={<FormattedMessage {...messages.login_title} />}
description={
<FormattedMessage
{...messages.login_description}
values={{
walletDir:
initWalletProps.loginProps.existingWalletDir && connectionType === 'local'
? initWalletProps.loginProps.existingWalletDir
: connectionHost.split(':')[0]
}}
/>
}
back={null}
next={null}
>
<Login {...initWalletProps.loginProps} /> <Login {...initWalletProps.loginProps} />
</FormContainer> </FormContainer>
) )
case 4: case 4:
return ( return (
<FormContainer <FormContainer
title="Welcome!" title={<FormattedMessage {...messages.create_wallet_password_title} />}
description="Looks like you are new here. Set a password to encrypt your wallet. This password will be needed to unlock Zap in the future" // eslint-disable-line max-len description={<FormattedMessage {...messages.create_wallet_password_description} />}
back={null} back={null}
next={() => { next={() => {
// dont allow the user to move on if the confirmation password doesnt match the original password // dont allow the user to move on if the confirmation password doesnt match the original password
@ -199,8 +204,8 @@ const Onboarding = ({
case 5: case 5:
return ( return (
<FormContainer <FormContainer
title={"Alright, let's get set up"} title={<FormattedMessage {...messages.signup_title} />}
description="Would you like to create a new wallet or import an existing one?" description={<FormattedMessage {...messages.signup_description} />}
back={() => changeStep(4)} back={() => changeStep(4)}
next={() => { next={() => {
// require the user to select create wallet or import wallet // require the user to select create wallet or import wallet
@ -220,8 +225,8 @@ const Onboarding = ({
case 5.1: case 5.1:
return ( return (
<FormContainer <FormContainer
title="Import your seed" title={<FormattedMessage {...messages.import_title} />}
description="Recovering a wallet, nice. You don't need anyone else, you got yourself :)" description={<FormattedMessage {...messages.import_description} />}
back={() => changeStep(5)} back={() => changeStep(5)}
next={() => { next={() => {
const recoverySeed = recoverFormProps.recoverSeedInput.map(input => input.word) const recoverySeed = recoverFormProps.recoverSeedInput.map(input => input.word)
@ -235,8 +240,8 @@ const Onboarding = ({
case 6: case 6:
return ( return (
<FormContainer <FormContainer
title="Save your wallet seed" title={<FormattedMessage {...messages.save_seed_title} />}
description="Please save these 24 words securely! This will allow you to recover your wallet in the future" description={<FormattedMessage {...messages.save_seed_description} />}
back={() => changeStep(5)} back={() => changeStep(5)}
next={() => changeStep(7)} next={() => changeStep(7)}
> >
@ -246,11 +251,17 @@ const Onboarding = ({
case 7: case 7:
return ( return (
<FormContainer <FormContainer
title="Retype your seed" title={<FormattedMessage {...messages.retype_seed_title} />}
description={`Your seed is important! If you lose your seed you'll have no way to recover your wallet. description={
To make sure that you have properly saved your seed, please retype words ${ <FormattedMessage
reEnterSeedProps.seedIndexesArr[0] {...messages.retype_seed_description}
}, ${reEnterSeedProps.seedIndexesArr[1]} and ${reEnterSeedProps.seedIndexesArr[2]}`} values={{
word1: reEnterSeedProps.seedIndexesArr[0],
word2: reEnterSeedProps.seedIndexesArr[1],
word3: reEnterSeedProps.seedIndexesArr[2]
}}
/>
}
back={() => changeStep(6)} back={() => changeStep(6)}
next={() => { next={() => {
// don't allow them to move on if they havent re-entered the seed correctly // don't allow them to move on if they havent re-entered the seed correctly

11
app/components/Onboarding/RecoverForm/RecoverForm.js

@ -1,8 +1,10 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { injectIntl } from 'react-intl'
import messages from './messages'
import styles from './RecoverForm.scss' import styles from './RecoverForm.scss'
const RecoverForm = ({ recoverSeedInput, updateRecoverSeedInput }) => ( const RecoverForm = ({ recoverSeedInput, updateRecoverSeedInput, intl }) => (
<div className={styles.container}> <div className={styles.container}>
<ul className={styles.seedContainer}> <ul className={styles.seedContainer}>
{Array(24) {Array(24)
@ -16,7 +18,7 @@ const RecoverForm = ({ recoverSeedInput, updateRecoverSeedInput }) => (
<input <input
type="text" type="text"
id={index} id={index}
placeholder="word" placeholder={intl.formatMessage({ ...messages.word_placeholder })}
value={recoverSeedInput[index] ? recoverSeedInput[index].word : ''} value={recoverSeedInput[index] ? recoverSeedInput[index].word : ''}
onChange={event => updateRecoverSeedInput({ word: event.target.value, index })} onChange={event => updateRecoverSeedInput({ word: event.target.value, index })}
className={styles.word} className={styles.word}
@ -30,7 +32,8 @@ const RecoverForm = ({ recoverSeedInput, updateRecoverSeedInput }) => (
RecoverForm.propTypes = { RecoverForm.propTypes = {
recoverSeedInput: PropTypes.array.isRequired, recoverSeedInput: PropTypes.array.isRequired,
updateRecoverSeedInput: PropTypes.func.isRequired updateRecoverSeedInput: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired
} }
export default RecoverForm export default injectIntl(RecoverForm)

6
app/components/Onboarding/RecoverForm/messages.js

@ -0,0 +1,6 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
word_placeholder: 'word'
})

10
app/components/Onboarding/Signup/Signup.js

@ -2,6 +2,8 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import FaCircle from 'react-icons/lib/fa/circle' import FaCircle from 'react-icons/lib/fa/circle'
import FaCircleThin from 'react-icons/lib/fa/circle-thin' import FaCircleThin from 'react-icons/lib/fa/circle-thin'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Signup.scss' import styles from './Signup.scss'
const Signup = ({ signupForm, setSignupCreate, setSignupImport }) => ( const Signup = ({ signupForm, setSignupCreate, setSignupImport }) => (
@ -9,13 +11,17 @@ const Signup = ({ signupForm, setSignupCreate, setSignupImport }) => (
<section className={`${styles.enable} ${signupForm.create ? styles.active : undefined}`}> <section className={`${styles.enable} ${signupForm.create ? styles.active : undefined}`}>
<div onClick={setSignupCreate}> <div onClick={setSignupCreate}>
{signupForm.create ? <FaCircle /> : <FaCircleThin />} {signupForm.create ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Create new wallet</span> <span className={styles.label}>
<FormattedMessage {...messages.signup_create} />
</span>
</div> </div>
</section> </section>
<section className={`${styles.disable} ${signupForm.import ? styles.active : undefined}`}> <section className={`${styles.disable} ${signupForm.import ? styles.active : undefined}`}>
<div onClick={setSignupImport}> <div onClick={setSignupImport}>
{signupForm.import ? <FaCircle /> : <FaCircleThin />} {signupForm.import ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Import existing wallet</span> <span className={styles.label}>
<FormattedMessage {...messages.signup_import} />
</span>
</div> </div>
</section> </section>
</div> </div>

7
app/components/Onboarding/Signup/messages.js

@ -0,0 +1,7 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
signup_create: 'Create new wallet',
signup_import: 'Import existing wallet'
})

52
app/components/Onboarding/Syncing/Syncing.js

@ -6,6 +6,8 @@ import Isvg from 'react-inlinesvg'
import zapLogo from 'icons/zap_logo.svg' import zapLogo from 'icons/zap_logo.svg'
import copyIcon from 'icons/copy.svg' import copyIcon from 'icons/copy.svg'
import { showNotification } from 'lib/utils/notifications' import { showNotification } from 'lib/utils/notifications'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './Syncing.scss' import styles from './Syncing.scss'
class Syncing extends Component { class Syncing extends Component {
@ -16,14 +18,13 @@ class Syncing extends Component {
} }
componentWillMount() { componentWillMount() {
const { syncStatus } = this.props const { syncStatus, intl } = this.props
// If we are still waiting for peers after some time, advise te user it could take a wile. // If we are still waiting for peers after some time, advise te user it could take a wile.
let timer = setTimeout(() => { let timer = setTimeout(() => {
if (syncStatus === 'waiting') { if (syncStatus === 'waiting') {
this.setState({ this.setState({
syncMessageDetail: syncMessageDetail: intl.formatMessage({ ...messages.grab_coffee })
'It looks like this could take some time - you might want to grab a coffee or try again later!'
}) })
} }
}, 10000) }, 10000)
@ -44,7 +45,8 @@ class Syncing extends Component {
address, address,
blockHeight, blockHeight,
lndBlockHeight, lndBlockHeight,
lndCfilterHeight lndCfilterHeight,
intl
} = this.props } = this.props
let { syncMessageDetail, syncMessageExtraDetail } = this.state let { syncMessageDetail, syncMessageExtraDetail } = this.state
@ -54,17 +56,27 @@ class Syncing extends Component {
} }
let syncMessage let syncMessage
if (syncStatus === 'waiting') { if (syncStatus === 'waiting') {
syncMessage = 'Waiting for peers...' syncMessage = intl.formatMessage({ ...messages.waiting_for_peers })
} else if (syncStatus === 'in-progress') { } else if (syncStatus === 'in-progress') {
if (typeof syncPercentage === 'undefined' || syncPercentage <= 0) { if (typeof syncPercentage === 'undefined' || syncPercentage <= 0) {
syncMessage = 'Preparing...' syncMessage = intl.formatMessage({ ...messages.preparing })
syncMessageDetail = null syncMessageDetail = null
} else if (syncPercentage) { } else if (syncPercentage) {
syncMessage = `${syncPercentage}%` syncMessage = `${syncPercentage}%`
syncMessageDetail = `Block: syncMessageDetail = intl.formatMessage(
${lndBlockHeight.toLocaleString()} of ${blockHeight.toLocaleString()}` { ...messages.block_progress },
syncMessageExtraDetail = `Commitment Filter: {
${lndCfilterHeight.toLocaleString()} of ${blockHeight.toLocaleString()}` currentBlock: lndBlockHeight.toLocaleString(),
totalBlocks: blockHeight.toLocaleString()
}
)
syncMessageExtraDetail = intl.formatMessage(
{ ...messages.filter_progress },
{
currentFilter: lndCfilterHeight.toLocaleString(),
totalFilters: blockHeight.toLocaleString()
}
)
} }
} }
@ -84,9 +96,11 @@ class Syncing extends Component {
{hasSynced === true && ( {hasSynced === true && (
<div> <div>
<div className={styles.title}> <div className={styles.title}>
<h1>Welcome back to your Zap wallet!</h1> <h1>
<FormattedMessage {...messages.sync_title} />
</h1>
<p> <p>
Please wait a while whilst we fetch all of your latest data from the blockchain. <FormattedMessage {...messages.sync_description} />
</p> </p>
</div> </div>
<div className={styles.loading}> <div className={styles.loading}>
@ -98,8 +112,12 @@ class Syncing extends Component {
{hasSynced === false && ( {hasSynced === false && (
<div> <div>
<div className={styles.title}> <div className={styles.title}>
<h1>Fund your Zap wallet</h1> <h1>
<p>Might as well fund your wallet while you&apos;re waiting to sync.</p> <FormattedMessage {...messages.fund_title} />
</h1>
<p>
<FormattedMessage {...messages.fund_description} />
</p>
</div> </div>
{address && address.length ? ( {address && address.length ? (
<div className={styles.address}> <div className={styles.address}>
@ -130,7 +148,9 @@ class Syncing extends Component {
)} )}
<section className={styles.progressContainer}> <section className={styles.progressContainer}>
<h3>Syncing to the blockchain</h3> <h3>
<FormattedMessage {...messages.sync_caption} />
</h3>
<div className={styles.progressBar}> <div className={styles.progressBar}>
<div <div
className={styles.progress} className={styles.progress}
@ -164,4 +184,4 @@ Syncing.propTypes = {
lndCfilterHeight: PropTypes.number lndCfilterHeight: PropTypes.number
} }
export default Syncing export default injectIntl(Syncing)

17
app/components/Onboarding/Syncing/messages.js

@ -0,0 +1,17 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
grab_coffee:
'It looks like this could take some time - you might want to grab a coffee or try again later!',
waiting_for_peers: 'Waiting for peers…',
preparing: 'Preparing…',
sync_title: 'Welcome back to your Zap wallet!',
sync_description:
'Please wait a while whilst we fetch all of your latest data from the blockchain.',
fund_title: 'Fund your Zap wallet',
fund_description: 'Might as well fund your wallet while you’re waiting to sync.',
sync_caption: 'Syncing to the blockchain',
block_progress: 'Block {currentBlock} of {totalBlocks}',
filter_progress: 'Commitment Filter {currentFilter} of {totalFilters}'
})

35
app/components/Onboarding/messages.js

@ -0,0 +1,35 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
connection_title: 'How do you want to connect to the Lightning Network?',
connection_description:
'By default Zap will spin up a node for you and handle all the nerdy stuff in the background. However you can also setup a custom node connection and use Zap to control a remote node if you desire (for advanced users).',
connection_details_custom_title: 'Connection details',
connection_details_custom_description: 'Enter the connection details for your Lightning node.',
btcpay_title: 'BTCPay Server',
btcpay_description: 'Enter the connection details for your BTCPay Server node.',
confirm_connection_title: 'Confirm connection',
confirm_connection_description: 'Confirm the connection details for your Lightning node.',
alias_title: 'What should we call you?',
alias_description: 'Set your nickname to help others connect with you on the Lightning Network',
autopilot_title: 'Autopilot',
autopilot_description:
'Autopilot is an automatic network manager. Instead of manually adding people to build your network to make payments, enable autopilot to automatically connect you to the Lightning Network using 60% of your balance.',
create_wallet_password_title: 'Welcome!',
create_wallet_password_description:
'Looks like you are new here. Set a password to encrypt your wallet. This password will be needed to unlock Zap in the future',
signup_title: "Alright, let's get set up",
signup_description: 'Would you like to create a new wallet or import an existing one?',
login_title: 'Welcome back!',
login_description:
'It looks like you already have a wallet (wallet found at: `{walletDir}`). Please enter your wallet password to unlock it.',
import_title: 'Import your seed',
import_description: "Recovering a wallet, nice. You don't need anyone else, you got yourself :)",
save_seed_title: 'Save your wallet seed',
save_seed_description:
'Please save these 24 words securely! This will allow you to recover your wallet in the future',
retype_seed_title: 'Retype your seed',
retype_seed_description:
"Your seed is important! If you lose your seed you'll have no way to recover your wallet. To make sure that you have properly saved your seed, please retype words {word1}, {word2} & {word3}"
})

6
app/components/Settings/Fiat/Fiat.js

@ -3,13 +3,17 @@ import PropTypes from 'prop-types'
import FaAngleLeft from 'react-icons/lib/fa/angle-left' import FaAngleLeft from 'react-icons/lib/fa/angle-left'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import checkIcon from 'icons/check.svg' import checkIcon from 'icons/check.svg'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Fiat.scss' import styles from './Fiat.scss'
const Fiat = ({ fiatTicker, fiatTickers, disableSubMenu, setFiatTicker }) => ( const Fiat = ({ fiatTicker, fiatTickers, disableSubMenu, setFiatTicker }) => (
<div> <div>
<header className={styles.submenuHeader} onClick={disableSubMenu}> <header className={styles.submenuHeader} onClick={disableSubMenu}>
<FaAngleLeft /> <FaAngleLeft />
<span>Fiat currency</span> <FormattedMessage {...messages.title} />
</header> </header>
<ul className={styles.fiatTickers}> <ul className={styles.fiatTickers}>
{fiatTickers.map(ft => ( {fiatTickers.map(ft => (

6
app/components/Settings/Fiat/messages.js

@ -0,0 +1,6 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
title: 'Fiat Currency'
})

49
app/components/Settings/Locale/Locale.js

@ -0,0 +1,49 @@
import React from 'react'
import PropTypes from 'prop-types'
import FaAngleLeft from 'react-icons/lib/fa/angle-left'
import ISO6391 from 'iso-639-1'
import Isvg from 'react-inlinesvg'
import checkIcon from 'icons/check.svg'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Locale.scss'
const Translate = ({ locales, disableSubMenu, currentLocale, setLocale }) => {
const changeLocale = lng => {
setLocale(lng)
}
return (
<div>
<header className={styles.submenuHeader} onClick={disableSubMenu}>
<FaAngleLeft />
<FormattedMessage {...messages.title} />
</header>
<ul className={styles.locales}>
{Object.keys(locales).map(lang => {
return (
<li
key={lang}
className={currentLocale === lang ? styles.active : ''}
onClick={() => changeLocale(lang)}
>
<span>{ISO6391.getName(lang.split('-')[0])}</span>
{currentLocale === lang && <Isvg src={checkIcon} />}
</li>
)
})}
</ul>
</div>
)
}
Translate.propTypes = {
locales: PropTypes.object.isRequired,
currentLocale: PropTypes.string.isRequired,
setLocale: PropTypes.func.isRequired,
disableSubMenu: PropTypes.func.isRequired
}
export default Translate

42
app/components/Settings/Locale/Locale.scss

@ -0,0 +1,42 @@
@import '../../../styles/variables.scss';
.submenuHeader {
padding: 20px;
background: lighten(#1d1f27, 20%);
font-size: 10px;
display: flex;
flex-direction: row;
justify-content: end;
align-items: center;
transition: all 0.25s;
&:hover {
background: lighten(#1d1f27, 10%);
}
}
.locales {
height: 300px;
overflow-y: scroll;
li {
background: #191919;
cursor: pointer;
border-bottom: 1px solid #0f0f0f;
transition: 0.25s hover;
&.active {
background: #0f0f0f;
svg {
height: 10px;
width: 10px;
color: $green;
}
}
span:nth-child(1) {
line-height: 12px;
}
}
}

3
app/components/Settings/Locale/index.js

@ -0,0 +1,3 @@
import Locale from './Locale'
export default Locale

6
app/components/Settings/Locale/messages.js

@ -0,0 +1,6 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
title: 'Language'
})

10
app/components/Settings/Menu/Menu.js

@ -1,12 +1,20 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import FaAngleRight from 'react-icons/lib/fa/angle-right' import FaAngleRight from 'react-icons/lib/fa/angle-right'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Menu.scss' import styles from './Menu.scss'
const Menu = ({ setActiveSubMenu }) => ( const Menu = ({ setActiveSubMenu }) => (
<ul> <ul>
<li className={styles.fiat} onClick={() => setActiveSubMenu('fiat')}> <li className={styles.fiat} onClick={() => setActiveSubMenu('fiat')}>
<span>Fiat Currency</span> <FormattedMessage {...messages.fiat} />
<FaAngleRight />
</li>
<li className={styles.locale} onClick={() => setActiveSubMenu('locale')}>
<FormattedMessage {...messages.locale} />
<FaAngleRight /> <FaAngleRight />
</li> </li>
</ul> </ul>

7
app/components/Settings/Menu/messages.js

@ -0,0 +1,7 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
fiat: 'Fiat Currency',
locale: 'Language'
})

8
app/components/Settings/Settings.js

@ -2,6 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Menu from './Menu' import Menu from './Menu'
import Fiat from './Fiat' import Fiat from './Fiat'
import Locale from './Locale'
import styles from './Settings.scss' import styles from './Settings.scss'
class Settings extends React.Component { class Settings extends React.Component {
@ -47,11 +48,13 @@ class Settings extends React.Component {
} }
renderSettings() { renderSettings() {
const { settings, fiatProps, setActiveSubMenu } = this.props const { settings, fiatProps, localeProps, setActiveSubMenu } = this.props
switch (settings.activeSubMenu) { switch (settings.activeSubMenu) {
case 'fiat': case 'fiat':
return <Fiat {...fiatProps} /> return <Fiat {...fiatProps} />
case 'locale':
return <Locale {...localeProps} />
default: default:
return <Menu setActiveSubMenu={setActiveSubMenu} /> return <Menu setActiveSubMenu={setActiveSubMenu} />
} }
@ -70,7 +73,8 @@ Settings.propTypes = {
settings: PropTypes.object.isRequired, settings: PropTypes.object.isRequired,
setActiveSubMenu: PropTypes.func.isRequired, setActiveSubMenu: PropTypes.func.isRequired,
toggleSettings: PropTypes.func.isRequired, toggleSettings: PropTypes.func.isRequired,
fiatProps: PropTypes.object.isRequired fiatProps: PropTypes.object.isRequired,
localeProps: PropTypes.object.isRequired
} }
export default Settings export default Settings

23
app/components/Wallet/ReceiveModal/ReceiveModal.js

@ -8,6 +8,9 @@ import Isvg from 'react-inlinesvg'
import x from 'icons/x.svg' import x from 'icons/x.svg'
import { showNotification } from 'lib/utils/notifications' import { showNotification } from 'lib/utils/notifications'
import { FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
import styles from './ReceiveModal.scss' import styles from './ReceiveModal.scss'
class ReceiveModal extends React.Component { class ReceiveModal extends React.Component {
@ -34,7 +37,7 @@ class ReceiveModal extends React.Component {
} }
} }
const { isOpen, pubkey, address, alias, closeReceiveModal, network } = this.props const { isOpen, pubkey, address, alias, closeReceiveModal, network, intl } = this.props
const { qrCodeType } = this.state const { qrCodeType } = this.state
@ -60,13 +63,13 @@ class ReceiveModal extends React.Component {
className={qrCodeType === 1 ? styles.active : undefined} className={qrCodeType === 1 ? styles.active : undefined}
onClick={changeQrCode} onClick={changeQrCode}
> >
Node Pubkey <FormattedMessage {...messages.node_pubkey} />
</div> </div>
<div <div
className={qrCodeType === 2 ? styles.active : undefined} className={qrCodeType === 2 ? styles.active : undefined}
onClick={changeQrCode} onClick={changeQrCode}
> >
Bitcoin Address <FormattedMessage {...messages.bitcoin_address} />
</div> </div>
</div> </div>
</header> </header>
@ -85,13 +88,15 @@ class ReceiveModal extends React.Component {
</section> </section>
<section className={styles.right}> <section className={styles.right}>
<div className={styles.pubkey}> <div className={styles.pubkey}>
<h4>Node Public Key</h4> <h4>
<FormattedMessage {...messages.node_public_key} />
</h4>
<p> <p>
<span className={styles.data}>{pubkey}</span> <span className={styles.data}>{pubkey}</span>
<span <span
onClick={() => copyOnClick(pubkey)} onClick={() => copyOnClick(pubkey)}
className={`${styles.copy} hint--left`} className={`${styles.copy} hint--left`}
data-hint="Copy pubkey" data-hint={intl.formatMessage({ ...messages.copy_pubkey })}
> >
<Isvg src={copyIcon} /> <Isvg src={copyIcon} />
</span> </span>
@ -99,13 +104,15 @@ class ReceiveModal extends React.Component {
</div> </div>
<div className={styles.address}> <div className={styles.address}>
<h4>Bitcoin {network.name} Address</h4> <h4>
<FormattedMessage {...messages.bitcoin_address} /> ({network.name})
</h4>
<p> <p>
<span className={styles.data}>{address}</span> <span className={styles.data}>{address}</span>
<span <span
onClick={() => copyOnClick(address)} onClick={() => copyOnClick(address)}
className={`${styles.copy} hint--left`} className={`${styles.copy} hint--left`}
data-hint="Copy address" data-hint={intl.formatMessage({ ...messages.copy_address })}
> >
<Isvg src={copyIcon} /> <Isvg src={copyIcon} />
</span> </span>
@ -129,4 +136,4 @@ ReceiveModal.propTypes = {
closeReceiveModal: PropTypes.func.isRequired closeReceiveModal: PropTypes.func.isRequired
} }
export default ReceiveModal export default injectIntl(ReceiveModal)

9
app/components/Wallet/ReceiveModal/messages.js

@ -0,0 +1,9 @@
import { defineMessages } from 'react-intl'
export default defineMessages({
node_public_key: 'Node Public Key',
node_pubkey: 'Node Pubkey',
bitcoin_address: 'Bitcoin Address',
copy_address: 'Copy address',
copy_pubkey: 'Copy Pubkey'
})

21
app/components/Wallet/Wallet.js

@ -12,6 +12,9 @@ import Settings from 'components/Settings'
import zapLogo from 'icons/zap_logo.svg' import zapLogo from 'icons/zap_logo.svg'
import qrCode from 'icons/qrcode.svg' import qrCode from 'icons/qrcode.svg'
import { FormattedMessage } from 'react-intl'
import messages from './messages'
import styles from './Wallet.scss' import styles from './Wallet.scss'
const Wallet = ({ const Wallet = ({
@ -105,10 +108,10 @@ const Wallet = ({
<div className={styles.right}> <div className={styles.right}>
<div className={styles.rightContent}> <div className={styles.rightContent}>
<div className={styles.pay} onClick={openPayForm}> <div className={styles.pay} onClick={openPayForm}>
Pay <FormattedMessage {...messages.pay} />
</div> </div>
<div className={styles.request} onClick={openRequestForm}> <div className={styles.request} onClick={openRequestForm}>
Request <FormattedMessage {...messages.request} />
</div> </div>
</div> </div>
<div className={styles.notificationBox}> <div className={styles.notificationBox}>
@ -118,7 +121,9 @@ const Wallet = ({
<section className={`${styles.spinner} ${styles.icon}`} /> <section className={`${styles.spinner} ${styles.icon}`} />
<span className={styles.timeout}>{paymentTimeout / 1000}</span> <span className={styles.timeout}>{paymentTimeout / 1000}</span>
</div> </div>
<section>Sending your transaction</section> <section>
<FormattedMessage {...messages.sending_tx} />
</section>
</span> </span>
)} )}
{showSuccessPayScreen && ( {showSuccessPayScreen && (
@ -126,7 +131,9 @@ const Wallet = ({
<section className={styles.icon}> <section className={styles.icon}>
<AnimatedCheckmark /> <AnimatedCheckmark />
</section> </section>
<section>Successfully sent payment</section> <section>
<FormattedMessage {...messages.payment_success} />
</section>
</span> </span>
)} )}
{successTransactionScreen.show && ( {successTransactionScreen.show && (
@ -135,16 +142,14 @@ const Wallet = ({
<AnimatedCheckmark /> <AnimatedCheckmark />
</section> </section>
<section> <section>
Successfully{' '}
<span <span
className={styles.txLink} className={styles.txLink}
onClick={() => { onClick={() => {
return blockExplorer.showTransaction(network, successTransactionScreen.txid) return blockExplorer.showTransaction(network, successTransactionScreen.txid)
}} }}
> >
sent <FormattedMessage {...messages.transaction_success} />
</span>{' '} </span>
transaction
</section> </section>
</span> </span>
)} )}

10
app/components/Wallet/messages.js

@ -0,0 +1,10 @@
import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
pay: 'Pay',
request: 'Request',
sending_tx: 'Sending your transaction…',
payment_success: 'Successfully sent payment',
transaction_success: 'Successfully sent transaction'
})

11
app/containers/Activity.js

@ -1,4 +1,5 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { setLocale } from 'reducers/locale'
import { setCurrency, setFiatTicker, tickerSelectors } from 'reducers/ticker' import { setCurrency, setFiatTicker, tickerSelectors } from 'reducers/ticker'
import { fetchBalance } from 'reducers/balance' import { fetchBalance } from 'reducers/balance'
import { fetchInvoices, setInvoice, invoiceSelectors } from 'reducers/invoice' import { fetchInvoices, setInvoice, invoiceSelectors } from 'reducers/invoice'
@ -26,6 +27,7 @@ import { setSettingsOpen, setActiveSubMenu, disableSubMenu } from 'reducers/sett
import Activity from 'components/Activity' import Activity from 'components/Activity'
const mapDispatchToProps = { const mapDispatchToProps = {
setLocale,
setCurrency, setCurrency,
setFiatTicker, setFiatTicker,
setPayment, setPayment,
@ -69,6 +71,9 @@ const mapStateToProps = state => ({
settings: state.settings, settings: state.settings,
currentLocale: state.intl.locale,
locales: state.locale,
paymentModalOpen: paymentSelectors.paymentModalOpen(state), paymentModalOpen: paymentSelectors.paymentModalOpen(state),
invoiceModalOpen: invoiceSelectors.invoiceModalOpen(state), invoiceModalOpen: invoiceSelectors.invoiceModalOpen(state),
@ -129,6 +134,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => ({
fiatTickers: stateProps.ticker.fiatTickers, fiatTickers: stateProps.ticker.fiatTickers,
disableSubMenu: dispatchProps.disableSubMenu, disableSubMenu: dispatchProps.disableSubMenu,
setFiatTicker: dispatchProps.setFiatTicker setFiatTicker: dispatchProps.setFiatTicker
},
localeProps: {
locales: stateProps.locales,
currentLocale: stateProps.currentLocale,
disableSubMenu: dispatchProps.disableSubMenu,
setLocale: dispatchProps.setLocale
} }
} }
} }

28
app/containers/Root.js

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import { Provider, connect } from 'react-redux' import { connect } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux' import { ConnectedRouter } from 'react-router-redux'
import { Switch, Route } from 'react-router' import { Switch, Route } from 'react-router'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
@ -205,14 +205,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
} }
} }
const Root = ({ const Root = ({ history, lnd, onboardingProps, syncingProps }) => {
store,
history,
lnd,
onboardingProps,
syncingProps
}) => {
// If we are onboarding show the onboarding screen. // If we are onboarding show the onboarding screen.
if (onboardingProps.onboarding.onboarding) { if (onboardingProps.onboarding.onboarding) {
return <Onboarding {...onboardingProps} /> return <Onboarding {...onboardingProps} />
@ -234,20 +227,17 @@ const Root = ({
} }
return ( return (
<Provider store={store}> <ConnectedRouter history={history}>
<ConnectedRouter history={history}> <App>
<App> <Switch>
<Switch> <Route path="/" component={Activity} />
<Route path="/" component={Activity} /> </Switch>
</Switch> </App>
</App> </ConnectedRouter>
</ConnectedRouter>
</Provider>
) )
} }
Root.propTypes = { Root.propTypes = {
store: PropTypes.object.isRequired,
history: PropTypes.object.isRequired, history: PropTypes.object.isRequired,
lnd: PropTypes.object.isRequired, lnd: PropTypes.object.isRequired,
onboardingProps: PropTypes.object.isRequired, onboardingProps: PropTypes.object.isRequired,

37
app/index.js

@ -1,21 +1,32 @@
import React from 'react' import React from 'react'
import { render } from 'react-dom' import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader' import { Provider } from 'react-intl-redux'
import jstz from 'jstimezonedetect'
import Root from './containers/Root' import Root from './containers/Root'
import { configureStore, history } from './store/configureStore' import { configureStore, history } from './store/configureStore'
import './styles/app.global.scss' import './styles/app.global.scss'
const store = configureStore() import { translationMessages, DEFAULT_LOCALE } from './lib/utils/i18n'
const initialState = {
intl: {
locale: DEFAULT_LOCALE,
messages: translationMessages[DEFAULT_LOCALE],
timeZone: jstz.determine().name()
}
}
render( const store = configureStore(initialState)
<AppContainer> const MOUNT_NODE = document.getElementById('root')
<Root store={store} history={history} />
</AppContainer>,
document.getElementById('root')
)
if (module.hot) { const render = () => {
module.hot.accept('./containers/Root', () => { ReactDOM.render(
render(<Root store={store} history={history} />, document.getElementById('root')) <Provider store={store}>
}) <Root history={history} />
</Provider>,
MOUNT_NODE
)
} }
render()

125
app/lib/utils/i18n.js

@ -0,0 +1,125 @@
import { app, remote } from 'electron'
import Store from 'electron-store'
import { addLocaleData } from 'react-intl'
// Load locale data.
import bg from 'react-intl/locale-data/bg'
import cs from 'react-intl/locale-data/cs'
import de from 'react-intl/locale-data/de'
import el from 'react-intl/locale-data/el'
import en from 'react-intl/locale-data/en'
import es from 'react-intl/locale-data/es'
import fr from 'react-intl/locale-data/fr'
import hr from 'react-intl/locale-data/hr'
import ja from 'react-intl/locale-data/ja'
import nl from 'react-intl/locale-data/nl'
import pt from 'react-intl/locale-data/pt'
import ro from 'react-intl/locale-data/ro'
import ru from 'react-intl/locale-data/ru'
import sv from 'react-intl/locale-data/sv'
import tr from 'react-intl/locale-data/tr'
import uk from 'react-intl/locale-data/uk'
import zh from 'react-intl/locale-data/zh'
// Load translation data.
import bgTranslationMessages from '../../translations/bg-BG.json'
import csTranslationMessages from '../../translations/cs-CZ.json'
import deTranslationMessages from '../../translations/de-DE.json'
import elTranslationMessages from '../../translations/el-GR.json'
import enTranslationMessages from '../../translations/en.json'
import esTranslationMessages from '../../translations/es-ES.json'
import frTranslationMessages from '../../translations/fr-FR.json'
import hrTranslationMessages from '../../translations/hr-HR.json'
import jaTranslationMessages from '../../translations/ja-JP.json'
import nlTranslationMessages from '../../translations/nl-NL.json'
import ptTranslationMessages from '../../translations/pt-BR.json'
import roTranslationMessages from '../../translations/ro-RO.json'
import ruTranslationMessages from '../../translations/ru-RU.json'
import svTranslationMessages from '../../translations/sv-SE.json'
import trTranslationMessages from '../../translations/tr-TR.json'
import ukTranslationMessages from '../../translations/uk-UA.json'
import zhCNTranslationMessages from '../../translations/zh-CN.json'
import zhTWTranslationMessages from '../../translations/zh-TW.json'
// Add locale data.
addLocaleData([
...bg,
...cs,
...de,
...el,
...en,
...es,
...fr,
...hr,
...ja,
...nl,
...pt,
...ro,
...ru,
...sv,
...tr,
...uk,
...zh
])
// Defaine list of language that we will support.
export const locales = [
'bg',
'cs',
'de',
'el',
'en',
'es',
'fr',
'hr',
'ja',
'nl',
'pt',
'ro',
'ru',
'sv',
'tr',
'uk',
'zh'
]
function getDefaltLocale() {
const store = new Store({ name: 'settings' })
// Detect user language.
let language = store.get('locale') || (app || remote.app).getLocale()
// If the detected language is not available, strip out any regional component and check again.
if (!locales.includes(language)) {
language = language.toLowerCase().split(/[_-]+/)[0]
}
// If we still can't find the users language, default to english.
if (!locales.includes(language)) {
language = 'en'
}
return language
}
export const DEFAULT_LOCALE = getDefaltLocale()
// Collate all translations.
export const translationMessages = {
en: enTranslationMessages,
bg: bgTranslationMessages,
'zh-CN': zhCNTranslationMessages,
'zh-TW': zhTWTranslationMessages,
hr: hrTranslationMessages,
cs: csTranslationMessages,
nl: nlTranslationMessages,
fr: frTranslationMessages,
de: deTranslationMessages,
el: elTranslationMessages,
ja: jaTranslationMessages,
pt: ptTranslationMessages,
ro: roTranslationMessages,
ru: ruTranslationMessages,
es: esTranslationMessages,
sv: svTranslationMessages,
tr: trTranslationMessages,
uk: ukTranslationMessages
}

40
app/lib/zap/menuBuilder.js

@ -1,16 +1,24 @@
// @flow // @flow
import { app, Menu, shell, BrowserWindow } from 'electron' import { app, Menu, shell, BrowserWindow, ipcMain } from 'electron'
import ISO6391 from 'iso-639-1'
import { locales, DEFAULT_LOCALE } from '../utils/i18n'
export default class ZapMenuBuilder { export default class ZapMenuBuilder {
mainWindow: BrowserWindow mainWindow: BrowserWindow
locale: string
constructor(mainWindow: BrowserWindow) { constructor(mainWindow: BrowserWindow) {
this.mainWindow = mainWindow this.mainWindow = mainWindow
this.locale = DEFAULT_LOCALE
ipcMain.on('setLocale', (event, locale) => this.buildMenu(locale))
} }
buildMenu() { buildMenu(locale?: string) {
let template if (locale) {
this.locale = locale
}
let template
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
template = this.buildDarwinTemplate() template = this.buildDarwinTemplate()
} else { } else {
@ -168,7 +176,14 @@ export default class ZapMenuBuilder {
const subMenuView = process.env.NODE_ENV === 'development' ? subMenuViewDev : subMenuViewProd const subMenuView = process.env.NODE_ENV === 'development' ? subMenuViewDev : subMenuViewProd
return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp] return [
subMenuAbout,
subMenuEdit,
subMenuView,
subMenuWindow,
subMenuHelp,
this.buildLanguageMenu()
]
} }
buildDefaultTemplate() { buildDefaultTemplate() {
@ -254,9 +269,24 @@ export default class ZapMenuBuilder {
} }
} }
] ]
} },
this.buildLanguageMenu()
] ]
return templateDefault return templateDefault
} }
buildLanguageMenu() {
return {
label: 'Language',
submenu: locales.map(locale => {
return {
label: ISO6391.getName(locale.split('-')[0]),
type: 'radio',
checked: this.locale === locale,
click: () => this.mainWindow.webContents.send('receiveLocale', locale)
}
})
}
}
} }

8
app/reducers/activity.js

@ -7,10 +7,10 @@ const initialState = {
filterPulldown: false, filterPulldown: false,
filter: { key: 'ALL_ACTIVITY', name: 'All Activity' }, filter: { key: 'ALL_ACTIVITY', name: 'All Activity' },
filters: [ filters: [
{ key: 'ALL_ACTIVITY', name: 'All' }, { key: 'ALL_ACTIVITY', name: 'all' },
{ key: 'SENT_ACTIVITY', name: 'Sent' }, { key: 'SENT_ACTIVITY', name: 'sent' },
{ key: 'REQUESTED_ACTIVITY', name: 'Requested' }, { key: 'REQUESTED_ACTIVITY', name: 'requested' },
{ key: 'PENDING_ACTIVITY', name: 'Pending' } { key: 'PENDING_ACTIVITY', name: 'pending' }
], ],
modal: { modal: {
itemType: null, itemType: null,

4
app/reducers/index.js

@ -1,5 +1,7 @@
import { combineReducers } from 'redux' import { combineReducers } from 'redux'
import { routerReducer as router } from 'react-router-redux' import { routerReducer as router } from 'react-router-redux'
import { intlReducer as intl } from 'react-intl-redux'
import locale from './locale'
import onboarding from './onboarding' import onboarding from './onboarding'
import lnd from './lnd' import lnd from './lnd'
import ticker from './ticker' import ticker from './ticker'
@ -25,6 +27,8 @@ import settings from './settings'
const rootReducer = combineReducers({ const rootReducer = combineReducers({
router, router,
intl,
locale,
onboarding, onboarding,
lnd, lnd,
ticker, ticker,

2
app/reducers/ipc.js

@ -1,4 +1,5 @@
import createIpc from 'redux-electron-ipc' import createIpc from 'redux-electron-ipc'
import { receiveLocale } from './locale'
import { import {
lndSyncStatus, lndSyncStatus,
currentBlockHeight, currentBlockHeight,
@ -58,6 +59,7 @@ import {
// Import all receiving IPC event handlers and pass them into createIpc // Import all receiving IPC event handlers and pass them into createIpc
const ipc = createIpc({ const ipc = createIpc({
receiveLocale,
lndSyncStatus, lndSyncStatus,
currentBlockHeight, currentBlockHeight,
lndBlockHeight, lndBlockHeight,

40
app/reducers/locale.js

@ -0,0 +1,40 @@
import Store from 'electron-store'
import { updateIntl } from 'react-intl-redux'
import { ipcRenderer } from 'electron'
import { translationMessages } from 'lib/utils/i18n'
// Settings store
const store = new Store({ name: 'settings' })
// ------------------------------------
// Actions
// ------------------------------------
export const setLocale = locale => (dispatch, getState) => {
const state = getState()
// Switch the active locale.
dispatch(
updateIntl({
locale,
messages: state.locale[locale]
})
)
// Save the new locale sa our language preference.
store.set('locale', locale)
// Let the main process know the locale has changed.
ipcRenderer.send('setLocale', locale)
}
export const receiveLocale = (event, locale) => dispatch => {
dispatch(setLocale(locale))
}
// ------------------------------------
// Reducer
// ------------------------------------
export default function localeReducer(state = translationMessages) {
return state
}

157
app/translations/bg-BG.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/cs-CZ.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/de-DE.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/el-GR.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/en.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "Expires in",
"components.Activity.Invoice.amount": "Invoice amount",
"components.Activity.Invoice.received": "Received payment",
"components.Activity.Invoice.requested": "Requested payment",
"components.Activity.Invoice.type_paid": "Lightning invoice (paid)",
"components.Activity.Invoice.type_unpaid": "Lightning invoice (unpaid)",
"components.Activity.InvoiceModal.copy": "Copy Request",
"components.Activity.InvoiceModal.memo": "Memo",
"components.Activity.InvoiceModal.not_paid": "Not Paid",
"components.Activity.InvoiceModal.paid": "Paid",
"components.Activity.InvoiceModal.pay_req": "Payment Request",
"components.Activity.InvoiceModal.request": "Request",
"components.Activity.InvoiceModal.save": "Save as image",
"components.Activity.Payment.amount": "Payment amount",
"components.Activity.Payment.fee": "Payment fee",
"components.Activity.Payment.type": "Lightning payment",
"components.Activity.PaymentModal.fee": "Fee",
"components.Activity.PaymentModal.lightning": "Lightning Network",
"components.Activity.PaymentModal.sent": "Sent",
"components.Activity.Transaction.amount": "Transaction amount",
"components.Activity.Transaction.fee": "Transaction fee",
"components.Activity.Transaction.received": "Received",
"components.Activity.Transaction.sent": "Sent",
"components.Activity.Transaction.type": "On-chain transaction",
"components.Activity.TransactionModal.fee": "Fee",
"components.Activity.TransactionModal.on_chain": "On-Chain",
"components.Activity.TransactionModal.received": "Received",
"components.Activity.TransactionModal.sent": "Sent",
"components.Activity.all": "All",
"components.Activity.hide_expired": "Hide Expired Requests",
"components.Activity.pending": "Pending",
"components.Activity.refresh": "Refresh",
"components.Activity.requested": "Requested",
"components.Activity.search": "Search",
"components.Activity.sent": "Sent",
"components.Activity.show_expired": "Show Expired Requests",
"components.Contacts.AddChannel.manual_button": "Connect Manually",
"components.Contacts.AddChannel.manual_description": "Hm, looks like we can't see that node from here, wanna try to manually connect?",
"components.Contacts.AddChannel.offline": "Offline",
"components.Contacts.AddChannel.online": "Online",
"components.Contacts.AddChannel.pending": "Pending",
"components.Contacts.AddChannel.private": "Private",
"components.Contacts.ConnectManually.description": "Please enter the peer’s pubkey@host",
"components.Contacts.ConnectManually.placeholder": "pubkey@host",
"components.Contacts.ConnectManually.submit": "Submit",
"components.Contacts.ConnectManually.title": "Connect Manually",
"components.Contacts.Network.closing": "closing",
"components.Contacts.Network.loading": "loading",
"components.Contacts.Network.offline": "offline",
"components.Contacts.Network.online": "online",
"components.Contacts.Network.open_channel": "Open a channel",
"components.Contacts.Network.pay_limit": "Pay Limit",
"components.Contacts.Network.pending": "pending",
"components.Contacts.Network.refresh": "Refresh",
"components.Contacts.Network.req_limit": "Request Limit",
"components.Contacts.Network.search_placeholder": "search by alias or pubkey",
"components.Contacts.Network.title": "My Network",
"components.Contacts.SubmitChannelForm.description": "Opening a channel will help you send and receive money on the Lightning Network. You aren't spending any money, rather moving the money you plan to use onto the network.",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "You currently have {activeChannels, plural, zero {no active channels} one {1 active channel} other {{activeChannels} active channels}} open to {aliasMsg, select, this_node {this node} other {{aliasMsg}}} with a capacity of",
"components.Contacts.SubmitChannelForm.submit": "Submit",
"components.Contacts.SubmitChannelForm.title": "Add Funds to Network",
"components.Contacts.SuggestedNodes.connect": "Connect",
"components.Contacts.SuggestedNodes.empty_description": "Hmmm, looks like you don't have any channels yet. Here are some suggested nodes to open a channel with to get started",
"components.Form.Pay.amount": "Amount",
"components.Form.Pay.destination": "Destination",
"components.Form.Pay.onchain_description": "On-Chain (~10 minutes)",
"components.Form.Pay.pay": "Pay",
"components.Form.Pay.request_placeholder": "Paste payment request or bitcoin address here",
"components.Form.Pay.title": "Make Payment",
"components.Form.Request.amount": "Amount",
"components.Form.Request.details": "Details about the request",
"components.Form.Request.memo": "Memo",
"components.Form.Request.request": "Request",
"components.Form.Request.title": "Request Payment",
"components.LoadingBolt.loading": "loading",
"components.Onboarding.Autopilot.disable": "Disable",
"components.Onboarding.Autopilot.enable": "Enable",
"components.Onboarding.BtcPayServer.btcpay_description": "Paste the full content of your BTCPay Server connection config file. This can be found by clicking the link entitled 'Click here to open the configuration file' in your BTCPay Server gRPC settings.",
"components.Onboarding.BtcPayServer.btcpay_error": "Invalid connection string.",
"components.Onboarding.BtcPayServer.connection_string_label": "Connection String",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "BTCPay Server Connection String",
"components.Onboarding.ConnectionConfirm.verify_host_description": "Please check the hostname carefully.",
"components.Onboarding.ConnectionConfirm.verify_host_title": "Are you sure you want to connect to",
"components.Onboarding.ConnectionDetails.cert_description": "Path to the lnd tls cert. Example: /path/to/tls.cert",
"components.Onboarding.ConnectionDetails.cert_title": "TLS Certificate",
"components.Onboarding.ConnectionDetails.hostname_description": "Hostname and port of the Lnd gRPC interface. Example: localhost:10009",
"components.Onboarding.ConnectionDetails.hostname_title": "Host",
"components.Onboarding.ConnectionDetails.macaroon_description": "Path to the lnd macaroon file. Example: /path/to/admin.macaroon",
"components.Onboarding.ConnectionType.btcpay_description": "Connect to your own BTCPay Server instance to access your BTCPay Server wallet.",
"components.Onboarding.ConnectionType.custom": "Custom",
"components.Onboarding.ConnectionType.custom_description": "Connect to your own node. You will need to provide your own connection settings so this is for advanced users only.",
"components.Onboarding.ConnectionType.default": "Default",
"components.Onboarding.ConnectionType.default_description": "By selecting the defualt mode we will do everything for you. Just click and go!",
"components.Onboarding.ConnectionType.only": "only",
"components.Onboarding.FormContainer.back": "back",
"components.Onboarding.FormContainer.help": "Need Help?",
"components.Onboarding.FormContainer.next": "Next",
"components.Onboarding.Login.password_placeholder": "Password",
"components.Onboarding.Login.unlock": "Unlock",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "Confirm Password",
"components.Onboarding.NewWalletPassword.password_error_length": "Password must be at least {passwordMinLength} characters long",
"components.Onboarding.NewWalletPassword.password_error_match": "Passwords do not match",
"components.Onboarding.NewWalletPassword.password_placeholder": "Password",
"components.Onboarding.NewWalletPassword.unlock": "Unlock",
"components.Onboarding.RecoverForm.word_placeholder": "word",
"components.Onboarding.Signup.signup_create": "Create new wallet",
"components.Onboarding.Signup.signup_import": "Import existing wallet",
"components.Onboarding.Syncing.block_progress": "Block {currentBlock} of {totalBlocks}",
"components.Onboarding.Syncing.filter_progress": "Commitment Filter {currentFilter} of {totalFilters}",
"components.Onboarding.Syncing.fund_description": "Might as well fund your wallet while you’re waiting to sync.",
"components.Onboarding.Syncing.fund_title": "Fund your Zap wallet",
"components.Onboarding.Syncing.grab_coffee": "It looks like this could take some time - you might want to grab a coffee or try again later!",
"components.Onboarding.Syncing.preparing": "Preparing…",
"components.Onboarding.Syncing.sync_caption": "Syncing to the blockchain",
"components.Onboarding.Syncing.sync_description": "Please wait a while whilst we fetch all of your latest data from the blockchain.",
"components.Onboarding.Syncing.sync_title": "Welcome back to your Zap wallet!",
"components.Onboarding.Syncing.waiting_for_peers": "Waiting for peers…",
"components.Onboarding.alias_description": "Set your nickname to help others connect with you on the Lightning Network",
"components.Onboarding.alias_title": "What should we call you?",
"components.Onboarding.autopilot_description": "Autopilot is an automatic network manager. Instead of manually adding people to build your network to make payments, enable autopilot to automatically connect you to the Lightning Network using 60% of your balance.",
"components.Onboarding.autopilot_title": "Autopilot",
"components.Onboarding.btcpay_description": "Enter the connection details for your BTCPay Server node.",
"components.Onboarding.btcpay_title": "BTCPay Server",
"components.Onboarding.confirm_connection_description": "Confirm the connection details for your Lightning node.",
"components.Onboarding.confirm_connection_title": "Confirm connection",
"components.Onboarding.connection_description": "By default Zap will spin up a node for you and handle all the nerdy stuff in the background. However you can also setup a custom node connection and use Zap to control a remote node if you desire (for advanced users).",
"components.Onboarding.connection_details_custom_description": "Enter the connection details for your Lightning node.",
"components.Onboarding.connection_details_custom_title": "Connection details",
"components.Onboarding.connection_title": "How do you want to connect to the Lightning Network?",
"components.Onboarding.create_wallet_password_description": "Looks like you are new here. Set a password to encrypt your wallet. This password will be needed to unlock Zap in the future",
"components.Onboarding.create_wallet_password_title": "Welcome!",
"components.Onboarding.import_description": "Recovering a wallet, nice. You don't need anyone else, you got yourself :)",
"components.Onboarding.import_title": "Import your seed",
"components.Onboarding.login_description": "It looks like you already have a wallet (wallet found at: `{walletDir}`). Please enter your wallet password to unlock it.",
"components.Onboarding.login_title": "Welcome back!",
"components.Onboarding.retype_seed_description": "Your seed is important! If you lose your seed you'll have no way to recover your wallet. To make sure that you have properly saved your seed, please retype words {word1}, {word2} & {word3}",
"components.Onboarding.retype_seed_title": "Retype your seed",
"components.Onboarding.save_seed_description": "Please save these 24 words securely! This will allow you to recover your wallet in the future",
"components.Onboarding.save_seed_title": "Save your wallet seed",
"components.Onboarding.signup_description": "Would you like to create a new wallet or import an existing one?",
"components.Onboarding.signup_title": "Alright, let's get set up",
"components.Settings.Fiat.title": "Fiat Currency",
"components.Settings.Locale.title": "Language",
"components.Settings.Menu.fiat": "Fiat Currency",
"components.Settings.Menu.locale": "Language",
"components.Wallet.ReceiveModal.bitcoin_address": "Bitcoin Address",
"components.Wallet.ReceiveModal.copy_address": "Copy address",
"components.Wallet.ReceiveModal.copy_pubkey": "Copy Pubkey",
"components.Wallet.ReceiveModal.node_pubkey": "Node Pubkey",
"components.Wallet.ReceiveModal.node_public_key": "Node Public Key",
"components.Wallet.pay": "Pay",
"components.Wallet.payment_success": "Successfully sent payment",
"components.Wallet.request": "Request",
"components.Wallet.sending_tx": "Sending your transaction…",
"components.Wallet.transaction_success": "Successfully sent transaction"
}

157
app/translations/es-ES.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/fr-FR.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/hr-HR.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/ja-JP.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/nl-NL.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/pt-BR.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/ro-RO.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/ru-RU.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/sv-SE.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/tr-TR.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/uk-UA.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

157
app/translations/zh-CN.json

@ -0,0 +1,157 @@
{
"components.Activity.Countdown.expires": "",
"components.Activity.Invoice.amount": "",
"components.Activity.Invoice.received": "",
"components.Activity.Invoice.requested": "",
"components.Activity.Invoice.type_paid": "",
"components.Activity.Invoice.type_unpaid": "",
"components.Activity.InvoiceModal.copy": "",
"components.Activity.InvoiceModal.memo": "",
"components.Activity.InvoiceModal.not_paid": "",
"components.Activity.InvoiceModal.paid": "",
"components.Activity.InvoiceModal.pay_req": "",
"components.Activity.InvoiceModal.request": "",
"components.Activity.InvoiceModal.save": "",
"components.Activity.Payment.amount": "",
"components.Activity.Payment.fee": "",
"components.Activity.Payment.type": "",
"components.Activity.PaymentModal.fee": "",
"components.Activity.PaymentModal.lightning": "",
"components.Activity.PaymentModal.sent": "",
"components.Activity.Transaction.amount": "",
"components.Activity.Transaction.fee": "",
"components.Activity.Transaction.received": "",
"components.Activity.Transaction.sent": "",
"components.Activity.Transaction.type": "",
"components.Activity.TransactionModal.fee": "",
"components.Activity.TransactionModal.on_chain": "",
"components.Activity.TransactionModal.received": "",
"components.Activity.TransactionModal.sent": "",
"components.Activity.all": "",
"components.Activity.hide_expired": "",
"components.Activity.pending": "",
"components.Activity.refresh": "",
"components.Activity.requested": "",
"components.Activity.search": "",
"components.Activity.sent": "",
"components.Activity.show_expired": "",
"components.Contacts.AddChannel.manual_button": "",
"components.Contacts.AddChannel.manual_description": "",
"components.Contacts.AddChannel.offline": "",
"components.Contacts.AddChannel.online": "",
"components.Contacts.AddChannel.pending": "",
"components.Contacts.AddChannel.private": "",
"components.Contacts.ConnectManually.description": "",
"components.Contacts.ConnectManually.placeholder": "",
"components.Contacts.ConnectManually.submit": "",
"components.Contacts.ConnectManually.title": "",
"components.Contacts.Network.closing": "",
"components.Contacts.Network.loading": "",
"components.Contacts.Network.offline": "",
"components.Contacts.Network.online": "",
"components.Contacts.Network.open_channel": "",
"components.Contacts.Network.pay_limit": "",
"components.Contacts.Network.pending": "",
"components.Contacts.Network.refresh": "",
"components.Contacts.Network.req_limit": "",
"components.Contacts.Network.search_placeholder": "",
"components.Contacts.Network.title": "",
"components.Contacts.SubmitChannelForm.description": "",
"components.Contacts.SubmitChannelForm.duplicate_warnig": "",
"components.Contacts.SubmitChannelForm.submit": "",
"components.Contacts.SubmitChannelForm.title": "",
"components.Contacts.SuggestedNodes.connect": "",
"components.Contacts.SuggestedNodes.empty_description": "",
"components.Form.Pay.amount": "",
"components.Form.Pay.destination": "",
"components.Form.Pay.onchain_description": "",
"components.Form.Pay.pay": "",
"components.Form.Pay.request_placeholder": "",
"components.Form.Pay.title": "",
"components.Form.Request.amount": "",
"components.Form.Request.details": "",
"components.Form.Request.memo": "",
"components.Form.Request.request": "",
"components.Form.Request.title": "",
"components.LoadingBolt.loading": "",
"components.Onboarding.Autopilot.disable": "",
"components.Onboarding.Autopilot.enable": "",
"components.Onboarding.BtcPayServer.btcpay_description": "",
"components.Onboarding.BtcPayServer.btcpay_error": "",
"components.Onboarding.BtcPayServer.connection_string_label": "",
"components.Onboarding.BtcPayServer.connection_string_placeholder": "",
"components.Onboarding.ConnectionConfirm.verify_host_description": "",
"components.Onboarding.ConnectionConfirm.verify_host_title": "",
"components.Onboarding.ConnectionDetails.cert_description": "",
"components.Onboarding.ConnectionDetails.cert_title": "",
"components.Onboarding.ConnectionDetails.hostname_description": "",
"components.Onboarding.ConnectionDetails.hostname_title": "",
"components.Onboarding.ConnectionDetails.macaroon_description": "",
"components.Onboarding.ConnectionType.btcpay_description": "",
"components.Onboarding.ConnectionType.custom": "",
"components.Onboarding.ConnectionType.custom_description": "",
"components.Onboarding.ConnectionType.default": "",
"components.Onboarding.ConnectionType.default_description": "",
"components.Onboarding.ConnectionType.only": "",
"components.Onboarding.FormContainer.back": "",
"components.Onboarding.FormContainer.help": "",
"components.Onboarding.FormContainer.next": "",
"components.Onboarding.Login.password_placeholder": "",
"components.Onboarding.Login.unlock": "",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "",
"components.Onboarding.NewWalletPassword.password_error_length": "",
"components.Onboarding.NewWalletPassword.password_error_match": "",
"components.Onboarding.NewWalletPassword.password_placeholder": "",
"components.Onboarding.NewWalletPassword.unlock": "",
"components.Onboarding.RecoverForm.word_placeholder": "",
"components.Onboarding.Signup.signup_create": "",
"components.Onboarding.Signup.signup_import": "",
"components.Onboarding.Syncing.block_progress": "",
"components.Onboarding.Syncing.filter_progress": "",
"components.Onboarding.Syncing.fund_description": "",
"components.Onboarding.Syncing.fund_title": "",
"components.Onboarding.Syncing.grab_coffee": "",
"components.Onboarding.Syncing.preparing": "",
"components.Onboarding.Syncing.sync_caption": "",
"components.Onboarding.Syncing.sync_description": "",
"components.Onboarding.Syncing.sync_title": "",
"components.Onboarding.Syncing.waiting_for_peers": "",
"components.Onboarding.alias_description": "",
"components.Onboarding.alias_title": "",
"components.Onboarding.autopilot_description": "",
"components.Onboarding.autopilot_title": "",
"components.Onboarding.btcpay_description": "",
"components.Onboarding.btcpay_title": "",
"components.Onboarding.confirm_connection_description": "",
"components.Onboarding.confirm_connection_title": "",
"components.Onboarding.connection_description": "",
"components.Onboarding.connection_details_custom_description": "",
"components.Onboarding.connection_details_custom_title": "",
"components.Onboarding.connection_title": "",
"components.Onboarding.create_wallet_password_description": "",
"components.Onboarding.create_wallet_password_title": "",
"components.Onboarding.import_description": "",
"components.Onboarding.import_title": "",
"components.Onboarding.login_description": "",
"components.Onboarding.login_title": "",
"components.Onboarding.retype_seed_description": "",
"components.Onboarding.retype_seed_title": "",
"components.Onboarding.save_seed_description": "",
"components.Onboarding.save_seed_title": "",
"components.Onboarding.signup_description": "",
"components.Onboarding.signup_title": "",
"components.Settings.Fiat.title": "",
"components.Settings.Locale.title": "",
"components.Settings.Menu.fiat": "",
"components.Settings.Menu.locale": "",
"components.Wallet.ReceiveModal.bitcoin_address": "",
"components.Wallet.ReceiveModal.copy_address": "",
"components.Wallet.ReceiveModal.copy_pubkey": "",
"components.Wallet.ReceiveModal.node_pubkey": "",
"components.Wallet.ReceiveModal.node_public_key": "",
"components.Wallet.pay": "",
"components.Wallet.payment_success": "",
"components.Wallet.request": "",
"components.Wallet.sending_tx": "",
"components.Wallet.transaction_success": ""
}

10
package.json

@ -13,6 +13,7 @@
"coverage": "open coverage/index.html", "coverage": "open coverage/index.html",
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", "coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"dev": "cross-env START_HOT=1 npm run start-renderer-dev", "dev": "cross-env START_HOT=1 npm run start-renderer-dev",
"extract-messages": "extract-messages -l=en -o app/translations -d en --flat true 'app/**/messages.js'",
"fetch-lnd": "node ./internals/scripts/fetch-lnd-for-packaging.js", "fetch-lnd": "node ./internals/scripts/fetch-lnd-for-packaging.js",
"flow": "flow", "flow": "flow",
"flow-typed": "rimraf flow-typed/npm && flow-typed install --overwrite || true", "flow-typed": "rimraf flow-typed/npm && flow-typed install --overwrite || true",
@ -203,6 +204,8 @@
"babel-plugin-dev-expression": "^0.2.1", "babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-dynamic-import-webpack": "^1.0.2", "babel-plugin-dynamic-import-webpack": "^1.0.2",
"babel-plugin-flow-runtime": "^0.17.0", "babel-plugin-flow-runtime": "^0.17.0",
"babel-plugin-react-intl": "^3.0.0",
"babel-plugin-react-intl-auto": "^1.1.1",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-es2015-classes": "^6.24.1", "babel-plugin-transform-es2015-classes": "^6.24.1",
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
@ -241,6 +244,7 @@
"eslint-plugin-prettier": "^2.6.2", "eslint-plugin-prettier": "^2.6.2",
"eslint-plugin-promise": "^4.0.1", "eslint-plugin-promise": "^4.0.1",
"eslint-plugin-react": "^7.11.1", "eslint-plugin-react": "^7.11.1",
"extract-react-intl-messages": "^0.10.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0", "extract-text-webpack-plugin": "^4.0.0-beta.0",
"fbjs-scripts": "^0.8.3", "fbjs-scripts": "^0.8.3",
"file-loader": "^2.0.0", "file-loader": "^2.0.0",
@ -291,18 +295,20 @@
"electron-store": "^2.0.0", "electron-store": "^2.0.0",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"history": "^4.7.2", "history": "^4.7.2",
"iso-639-1": "^2.0.3",
"javascript-state-machine": "^3.1.0", "javascript-state-machine": "^3.1.0",
"jstimezonedetect": "^1.0.6",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0", "lodash.pick": "^4.4.0",
"moment": "^2.22.2",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"qrcode.react": "0.8.0", "qrcode.react": "0.8.0",
"react": "^16.5.1", "react": "^16.5.1",
"react-dom": "^16.5.1", "react-dom": "^16.5.1",
"react-hot-loader": "^4.3.8", "react-hot-loader": "^4.3.8",
"react-inlinesvg": "^0.8.1", "react-inlinesvg": "^0.8.1",
"react-intl": "^2.5.0",
"react-intl-redux": "^2.0.2",
"react-modal": "^3.5.1", "react-modal": "^3.5.1",
"react-moment": "^0.7.9",
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-router-dom": "^4.3.1", "react-router-dom": "^4.3.1",
"react-router-redux": "^5.0.0-alpha.9", "react-router-redux": "^5.0.0-alpha.9",

41
test/unit/__helpers__/intl-enzyme-test-helper.js.js

@ -0,0 +1,41 @@
// See https://github.com/yahoo/react-intl/wiki/Testing-with-React-Intl#enzyme
/**
* Components using the react-intl module require access to the intl context.
* This is not available when mounting single components in Enzyme.
* These helper functions aim to address that and wrap a valid,
* English-locale intl context around them.
*/
import React from 'react'
import { IntlProvider, intlShape } from 'react-intl'
import { mount, shallow } from 'enzyme'
// Ppass default messages to the IntlProvider.
const messages = require('../../../app/translations/en.json')
// Create the IntlProvider to retrieve context for wrapping around.
const intlProvider = new IntlProvider({ locale: 'en', messages }, {})
const { intl } = intlProvider.getChildContext()
/**
* When using React-Intl `injectIntl` on components, props.intl is required.
*/
function nodeWithIntlProp(node) {
return React.cloneElement(node, { intl })
}
export function shallowWithIntl(node, { context, ...additionalOptions } = {}) {
return shallow(nodeWithIntlProp(node), {
context: Object.assign({}, context, { intl }),
...additionalOptions
})
}
export function mountWithIntl(node, { context, childContextTypes, ...additionalOptions } = {}) {
return mount(nodeWithIntlProp(node), {
context: Object.assign({}, context, { intl }),
childContextTypes: Object.assign({}, { intl: intlShape }, childContextTypes),
...additionalOptions
})
}

10
test/unit/components/Form/Pay.spec.js

@ -1,9 +1,11 @@
import React from 'react' import React from 'react'
import { configure, mount } from 'enzyme' import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16' import Adapter from 'enzyme-adapter-react-16'
import Pay from 'components/Form/Pay' import Pay from 'components/Form/Pay'
import { mountWithIntl } from '../../__helpers__/intl-enzyme-test-helper.js'
configure({ adapter: new Adapter() }) configure({ adapter: new Adapter() })
const defaultProps = { const defaultProps = {
@ -45,7 +47,7 @@ const defaultProps = {
describe('Form', () => { describe('Form', () => {
describe('should show the form without an input', () => { describe('should show the form without an input', () => {
const el = mount(<Pay {...defaultProps} />) const el = mountWithIntl(<Pay {...defaultProps} />)
it('should contain Pay', () => { it('should contain Pay', () => {
expect(el.find('input#paymentRequest').props.value).toBe(undefined) expect(el.find('input#paymentRequest').props.value).toBe(undefined)
@ -54,7 +56,7 @@ describe('Form', () => {
describe('should show lightning with a lightning input', () => { describe('should show lightning with a lightning input', () => {
const props = { ...defaultProps, isLn: true } const props = { ...defaultProps, isLn: true }
const el = mount(<Pay {...props} />) const el = mountWithIntl(<Pay {...props} />)
it('should contain Pay', () => { it('should contain Pay', () => {
expect(el.find('input#paymentRequest').props.value).toBe(undefined) expect(el.find('input#paymentRequest').props.value).toBe(undefined)
@ -63,7 +65,7 @@ describe('Form', () => {
describe('should show on-chain with an on-chain input', () => { describe('should show on-chain with an on-chain input', () => {
const props = { ...defaultProps, isOnchain: true } const props = { ...defaultProps, isOnchain: true }
const el = mount(<Pay {...props} />) const el = mountWithIntl(<Pay {...props} />)
it('should contain Pay', () => { it('should contain Pay', () => {
expect(el.find('input#paymentRequest').props.value).toBe(undefined) expect(el.find('input#paymentRequest').props.value).toBe(undefined)

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save