From c4c11f7552e9dc967ed9b8f672576a0d8529da4d Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Mon, 2 Oct 2017 22:46:10 -0500 Subject: [PATCH 1/4] feature(ln-payment-links): POC for LN payment links --- app/main.dev.js | 14 +++++-- app/reducers/ipc.js | 3 ++ app/reducers/payform.js | 8 ++++ app/reducers/payment.js | 3 ++ .../components/ModalRoot/ModalRoot.js | 4 +- .../SuccessfulSendPayment.js | 26 +++++++++++++ .../SuccessfulSendPayment.scss | 37 +++++++++++++++++++ .../ModalRoot/SuccessfulSendPayment/index.js | 3 ++ 8 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.js create mode 100644 app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss create mode 100644 app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js diff --git a/app/main.dev.js b/app/main.dev.js index 8d6b5416..86758411 100644 --- a/app/main.dev.js +++ b/app/main.dev.js @@ -27,9 +27,6 @@ if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') const path = require('path'); const p = path.join(__dirname, '..', 'app', 'node_modules'); require('module').globalPaths.push(p); - - // set icon - // app.dock.setIcon(`${path.join(__dirname, '..', 'resources')}/zap_2.png`) } const installExtensions = async () => { @@ -69,6 +66,8 @@ app.on('ready', async () => { frame: false }); + mainWindow.setTitle('Zap') + mainWindow.maximize(); mainWindow.loadURL(`file://${__dirname}/app.html`); @@ -99,3 +98,12 @@ app.on('ready', async () => { lndMethods(event, msg, data) }) }); + +app.setAsDefaultProtocolClient('lightning') + +app.on('open-url', function (event, url) { + event.preventDefault() + const payreq = url.split(':')[1] + mainWindow.webContents.send('lightningPaymentUri', { payreq }) + mainWindow.show() +}) diff --git a/app/reducers/ipc.js b/app/reducers/ipc.js index b1c58f1a..2d819b31 100644 --- a/app/reducers/ipc.js +++ b/app/reducers/ipc.js @@ -19,6 +19,7 @@ import { pushclosechannelstatus } from './channels' +import { lightningPaymentUri } from './payform' import { receivePayments, paymentSuccessful } from './payment' import { receiveInvoices, createdInvoice, receiveFormInvoice, invoiceUpdate } from './invoice' import { receiveBalance } from './balance' @@ -46,6 +47,8 @@ const ipc = createIpc({ receiveBalance, + lightningPaymentUri, + paymentSuccessful, channelSuccessful, diff --git a/app/reducers/payform.js b/app/reducers/payform.js index b031b8ff..17827ad6 100644 --- a/app/reducers/payform.js +++ b/app/reducers/payform.js @@ -3,6 +3,7 @@ import bitcoin from 'bitcoinjs-lib' import isEmpty from 'lodash/isEmpty' +import { setFormType } from './form' import { tickerSelectors } from './ticker' import { btc, bech32 } from '../utils' @@ -64,6 +65,13 @@ export function updatePayErrors(errorsObject) { } } +export const lightningPaymentUri = (event, { payreq }) => (dispatch) => { + // Open pay form + dispatch(setFormType('PAY_FORM')) + // Set payreq + dispatch(setPayInput(payreq)) +} + // ------------------------------------ // Action Handlers // ------------------------------------ diff --git a/app/reducers/payment.js b/app/reducers/payment.js index 5666b42a..41883562 100644 --- a/app/reducers/payment.js +++ b/app/reducers/payment.js @@ -2,6 +2,7 @@ import { createSelector } from 'reselect' import { ipcRenderer } from 'electron' import { setFormType } from './form' import { resetPayForm } from './payform' +import { showModal } from './modal' // ------------------------------------ // Constants @@ -73,6 +74,8 @@ export const paymentSuccessful = () => (dispatch) => { // Close the form modal once the payment was succesful dispatch(setFormType(null)) + // Show successful payment state + dispatch(showModal('SUCCESSFUL_SEND_PAYMENT')) // Refetch payments (TODO: dont do a full refetch, rather append new tx to list) dispatch(fetchPayments()) diff --git a/app/routes/app/components/components/ModalRoot/ModalRoot.js b/app/routes/app/components/components/ModalRoot/ModalRoot.js index 1146c57e..2241d0da 100644 --- a/app/routes/app/components/components/ModalRoot/ModalRoot.js +++ b/app/routes/app/components/components/ModalRoot/ModalRoot.js @@ -2,10 +2,12 @@ import React from 'react' import PropTypes from 'prop-types' import { MdClose } from 'react-icons/lib/md' import SuccessfulSendCoins from './SuccessfulSendCoins' +import SuccessfulSendPayment from './SuccessfulSendPayment' import styles from './ModalRoot.scss' const MODAL_COMPONENTS = { - SUCCESSFUL_SEND_COINS: SuccessfulSendCoins + SUCCESSFUL_SEND_COINS: SuccessfulSendCoins, + SUCCESSFUL_SEND_PAYMENT: SuccessfulSendPayment /* other modals */ } diff --git a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.js b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.js new file mode 100644 index 00000000..e409251d --- /dev/null +++ b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.js @@ -0,0 +1,26 @@ +import { shell } from 'electron' +import React from 'react' +import PropTypes from 'prop-types' +import AnimatedCheckmark from 'components/AnimatedCheckmark' +import { btc } from 'utils' +import styles from './SuccessfulSendPayment.scss' + +const SuccessfulSendPayment = ({ hideModal }) => { + return ( +
+ +

+ Successfully sent payment  +

+
+ Done +
+
+ ) +} + +SuccessfulSendPayment.propTypes = { + hideModal: PropTypes.func.isRequired +} + +export default SuccessfulSendPayment diff --git a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss new file mode 100644 index 00000000..b562cf30 --- /dev/null +++ b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss @@ -0,0 +1,37 @@ +@import '../../../../../../variables.scss'; + +.container { + position: relative; + min-height: 250px; + top: calc(50% - 250px); + text-align: center; + + h1 { + font-size: 20px; + margin: 50px 0; + + .link { + cursor: pointer; + color: $main; + text-decoration: underline; + } + + .amount, .addr { + font-weight: bold; + } + } + + .button { + text-align: center; + border-radius: 8px; + background: $main; + padding: 20px 10px; + font-weight: bold; + cursor: pointer; + text-transform: uppercase; + letter-spacing: .2px; + color: $white; + width: 15%; + margin: 0 auto; + } +} \ No newline at end of file diff --git a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js new file mode 100644 index 00000000..f6f1b05a --- /dev/null +++ b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js @@ -0,0 +1,3 @@ +import SuccessfulSendPayment from './SuccessfulSendPayment' + +export default SuccessfulSendPayment From a88d1c4e15bfc93208e6192878cc2915f24f0761 Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Sun, 8 Oct 2017 23:24:52 -0500 Subject: [PATCH 2/4] fix(setTitle): remove unused setTitle --- app/main.dev.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/main.dev.js b/app/main.dev.js index 86758411..52ba7a30 100644 --- a/app/main.dev.js +++ b/app/main.dev.js @@ -66,8 +66,6 @@ app.on('ready', async () => { frame: false }); - mainWindow.setTitle('Zap') - mainWindow.maximize(); mainWindow.loadURL(`file://${__dirname}/app.html`); @@ -103,6 +101,7 @@ app.setAsDefaultProtocolClient('lightning') app.on('open-url', function (event, url) { event.preventDefault() + const payreq = url.split(':')[1] mainWindow.webContents.send('lightningPaymentUri', { payreq }) mainWindow.show() From ab5c59540a6918e6ae5f0acfcfa329a54739817c Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Mon, 9 Oct 2017 15:13:42 -0500 Subject: [PATCH 3/4] fix(SuccessfulSendPayment): move to components folder, remove old components folder --- .../ModalRoot}/SuccessfulSendPayment.js | 0 .../ModalRoot}/SuccessfulSendPayment.scss | 2 +- .../components/ModalRoot/SuccessfulSendPayment/index.js | 3 --- 3 files changed, 1 insertion(+), 4 deletions(-) rename app/{routes/app/components/components/ModalRoot/SuccessfulSendPayment => components/ModalRoot}/SuccessfulSendPayment.js (100%) rename app/{routes/app/components/components/ModalRoot/SuccessfulSendPayment => components/ModalRoot}/SuccessfulSendPayment.scss (92%) delete mode 100644 app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js diff --git a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.js b/app/components/ModalRoot/SuccessfulSendPayment.js similarity index 100% rename from app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.js rename to app/components/ModalRoot/SuccessfulSendPayment.js diff --git a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss b/app/components/ModalRoot/SuccessfulSendPayment.scss similarity index 92% rename from app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss rename to app/components/ModalRoot/SuccessfulSendPayment.scss index b562cf30..297541bc 100644 --- a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/SuccessfulSendPayment.scss +++ b/app/components/ModalRoot/SuccessfulSendPayment.scss @@ -1,4 +1,4 @@ -@import '../../../../../../variables.scss'; +@import '../../variables.scss'; .container { position: relative; diff --git a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js b/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js deleted file mode 100644 index f6f1b05a..00000000 --- a/app/routes/app/components/components/ModalRoot/SuccessfulSendPayment/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import SuccessfulSendPayment from './SuccessfulSendPayment' - -export default SuccessfulSendPayment From 642c61db449354f486db0eb7d8440e6f603a1e63 Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Mon, 9 Oct 2017 15:24:22 -0500 Subject: [PATCH 4/4] fix(lint): fix linting errors --- .../ModalRoot/SuccessfulSendPayment.js | 22 ++++++++----------- app/reducers/ipc.js | 2 +- test/components/ModalRoot.spec.js | 15 ++++++++++++- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/components/ModalRoot/SuccessfulSendPayment.js b/app/components/ModalRoot/SuccessfulSendPayment.js index e409251d..d8d74380 100644 --- a/app/components/ModalRoot/SuccessfulSendPayment.js +++ b/app/components/ModalRoot/SuccessfulSendPayment.js @@ -1,23 +1,19 @@ -import { shell } from 'electron' import React from 'react' import PropTypes from 'prop-types' import AnimatedCheckmark from 'components/AnimatedCheckmark' -import { btc } from 'utils' import styles from './SuccessfulSendPayment.scss' -const SuccessfulSendPayment = ({ hideModal }) => { - return ( -
- -

- Successfully sent payment  -

-
+const SuccessfulSendPayment = ({ hideModal }) => ( +
+ +

+ Successfully sent payment  +

+
Done -
- ) -} +
+) SuccessfulSendPayment.propTypes = { hideModal: PropTypes.func.isRequired diff --git a/app/reducers/ipc.js b/app/reducers/ipc.js index 2d819b31..bc67489e 100644 --- a/app/reducers/ipc.js +++ b/app/reducers/ipc.js @@ -48,7 +48,7 @@ const ipc = createIpc({ receiveBalance, lightningPaymentUri, - + paymentSuccessful, channelSuccessful, diff --git a/test/components/ModalRoot.spec.js b/test/components/ModalRoot.spec.js index cbd99af7..05a6dcf2 100644 --- a/test/components/ModalRoot.spec.js +++ b/test/components/ModalRoot.spec.js @@ -2,6 +2,7 @@ import React from 'react' import { shallow } from 'enzyme' import ModalRoot from '../../app/components/ModalRoot' import SuccessfulSendCoins from '../../app/components/ModalRoot/SuccessfulSendCoins' +import SuccessfulSendPayment from '../../app/components/ModalRoot/SuccessfulSendPayment' const defaultProps = { hideModal: () => {}, @@ -32,4 +33,16 @@ describe('SuccessfulSendCoins modal', () => { it('should render specific modal', () => { expect(el.find(SuccessfulSendCoins).length).toBe(1) }) -}); +}) + +describe('SuccessfulSendPayment modal', () => { + const props = { + ...defaultProps, + modalType: 'SUCCESSFUL_SEND_PAYMENT', + modalProps: {} + } + const el = shallow() + it('should render specific modal', () => { + expect(el.find(SuccessfulSendPayment).length).toBe(1) + }) +})