Browse Source

Merge pull request #96 from LN-Zap/fix/peers-channel-loading-ux

Fix/peers channel loading ux
renovate/lint-staged-8.x
JimmyMow 7 years ago
committed by GitHub
parent
commit
87db25b0ca
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/app.global.scss
  2. 4
      app/components/Channels/Channel.scss
  3. 25
      app/components/Channels/OpenPendingChannel.js
  4. 13
      app/components/Channels/OpenPendingChannel.scss
  5. 55
      app/components/Peers/PeerModal.js
  6. 42
      app/components/Peers/PeerModal.scss
  7. 54
      app/components/Wallet/ReceiveModal.js
  8. 79
      app/components/Wallet/ReceiveModal.scss
  9. 21
      app/components/Wallet/Wallet.js
  10. 4
      app/components/Wallet/Wallet.scss
  11. 9
      app/lnd/methods/paymentsController.js
  12. 2
      app/lnd/subscribe/transactions.js
  13. 1
      app/main.dev.js
  14. 15
      app/reducers/channels.js
  15. 5
      app/reducers/info.js
  16. 1
      app/routes/activity/components/components/Modal/Invoice/Invoice.js

3
app/app.global.scss

@ -86,7 +86,8 @@ body {
padding-bottom: 15px; padding-bottom: 15px;
border-radius: 2px; border-radius: 2px;
text-align: center; text-align: center;
font-size: 18px; font-size: 16px;
letter-spacing: 1.5px;
transition: none; transition: none;
position: relative; position: relative;
color: white; color: white;

4
app/components/Channels/Channel.scss

@ -2,15 +2,17 @@
.channel { .channel {
position: relative; position: relative;
background: $lightgrey; background: $white;
margin: 5px 0; margin: 5px 0;
padding: 10px; padding: 10px;
border-top: 1px solid $white; border-top: 1px solid $white;
cursor: pointer; cursor: pointer;
transition: all 0.25s; transition: all 0.25s;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
&:hover { &:hover {
opacity: 0.75; opacity: 0.75;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
} }
&:first-child { &:first-child {

25
app/components/Channels/OpenPendingChannel.js

@ -4,17 +4,20 @@ import PropTypes from 'prop-types'
import { btc } from 'utils' import { btc } from 'utils'
import styles from './OpenPendingChannel.scss' import styles from './OpenPendingChannel.scss'
const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explorerLinkBase }) => ( const OpenPendingChannel = ({ ticker, channel, currentTicker, explorerLinkBase }) => (
<li className={styles.channel} onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${channel.channel_point.split(':')[0]}`)}> <li className={styles.channel} onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${channel.channel.channel_point.split(':')[0]}`)}>
<h1 className={styles.pending}>Opening Channel...</h1> <div className={styles.pending}>
<h1>Opening Channel...</h1>
<span>Blocks till open: {channel.blocks_till_open}</span>
</div>
<div className={styles.left}> <div className={styles.left}>
<section className={styles.remotePubkey}> <section className={styles.remotePubkey}>
<span>Remote Pubkey</span> <span>Remote Pubkey</span>
<h4>{channel.remote_node_pub}</h4> <h4>{channel.channel.remote_node_pub}</h4>
</section> </section>
<section className={styles.channelPoint}> <section className={styles.channelPoint}>
<span>Channel Point</span> <span>Channel Point</span>
<h4>{channel.channel_point}</h4> <h4>{channel.channel.channel_point}</h4>
</section> </section>
</div> </div>
<div className={styles.right}> <div className={styles.right}>
@ -23,9 +26,9 @@ const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explo
<h2> <h2>
{ {
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.capacity) btc.satoshisToBtc(channel.channel.capacity)
: :
btc.satoshisToUsd(channel.capacity, currentTicker.price_usd) btc.satoshisToUsd(channel.channel.capacity, currentTicker.price_usd)
} }
</h2> </h2>
</section> </section>
@ -34,9 +37,9 @@ const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explo
<h4> <h4>
{ {
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.local_balance) btc.satoshisToBtc(channel.channel.local_balance)
: :
btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd) btc.satoshisToUsd(channel.channel.local_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Local</span> <span>Local</span>
@ -45,9 +48,9 @@ const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explo
<h4> <h4>
{ {
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.remote_balance) btc.satoshisToBtc(channel.channel.remote_balance)
: :
btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd) btc.satoshisToUsd(channel.channel.remote_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Remote</span> <span>Remote</span>

13
app/components/Channels/OpenPendingChannel.scss

@ -13,14 +13,21 @@
opacity: 0.5; opacity: 0.5;
.pending { .pending {
color: $main;
position: absolute; position: absolute;
top: 0; top: 0;
left: 10px; left: 10px;
padding: 10px; padding: 10px;
text-transform: uppercase; text-transform: uppercase;
font-weight: bold; font-weight: bold;
font-size: 10px;
h1 {
color: $main;
font-size: 10px;
}
span {
font-size: 8px;
}
} }
&:first-child { &:first-child {
@ -30,7 +37,7 @@
.left, .right { .left, .right {
padding: 0 10px; padding: 0 10px;
margin-bottom: 5; margin-bottom: 5;
margin-top: 25px; margin-top: 40px;
section { section {
margin-bottom: 20px; margin-bottom: 20px;

55
app/components/Peers/PeerModal.js

@ -1,6 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import ReactModal from 'react-modal' import ReactModal from 'react-modal'
import { MdClose } from 'react-icons/lib/md'
import styles from './PeerModal.scss' import styles from './PeerModal.scss'
const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => { const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => {
@ -16,7 +19,8 @@ const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => {
bottom: 'auto', bottom: 'auto',
width: '40%', width: '40%',
margin: '50px auto', margin: '50px auto',
padding: '40px' borderRadius: 'none',
padding: '0'
} }
} }
@ -30,32 +34,35 @@ const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => {
parentSelector={() => document.body} parentSelector={() => document.body}
style={customStyles} style={customStyles}
> >
<div className={styles.closeContainer}>
<span onClick={() => resetPeer(null)}>
<MdClose />
</span>
</div>
{ {
peer ? peer &&
<div className={styles.peer}> <div className={styles.peer}>
<header className={styles.header}> <header className={styles.header}>
<h1 data-hint='Peer address' className='hint--top-left'>{peer.address}</h1> <h1 data-hint='Peer address' className='hint--top-left'>{peer.address}</h1>
<h2 data-hint='Peer public key' className='hint--top-left'>{peer.pub_key}</h2> <h2 data-hint='Peer public key' className='hint--top-left'>{peer.pub_key}</h2>
</header> </header>
<div className={styles.details}> <div className={styles.details}>
<dl> <dl>
<dt>Satoshis Received</dt> <dt>Satoshis Received</dt>
<dd>{peer.sat_recv}</dd> <dd>{peer.sat_recv}</dd>
<dt>Satoshis Sent</dt> <dt>Satoshis Sent</dt>
<dd>{peer.sat_sent}</dd> <dd>{peer.sat_sent}</dd>
<dt>Bytes Received</dt> <dt>Bytes Received</dt>
<dd>{peer.bytes_recv}</dd> <dd>{peer.bytes_recv}</dd>
<dt>Bytes Sent</dt> <dt>Bytes Sent</dt>
<dd>{peer.bytes_sent}</dd> <dd>{peer.bytes_sent}</dd>
</dl> </dl>
</div> </div>
<div className={styles.close} onClick={() => disconnect({ pubkey: peer.pub_key })}> <div className={styles.close} onClick={() => disconnect({ pubkey: peer.pub_key })}>
<div>Disconnect peer</div> <div>Disconnect peer</div>
</div>
</div> </div>
: </div>
null
} }
</ReactModal> </ReactModal>
) )

42
app/components/Peers/PeerModal.scss

@ -1,29 +1,39 @@
@import '../../variables.scss'; @import '../../variables.scss';
.peer { .closeContainer {
padding: 40px; background: $lightgrey;
text-align: right;
padding: 10px;
span {
color: $darkestgrey;
font-size: 20px;
cursor: pointer;
}
} }
.header { .header {
margin-bottom: 50px; background: $lightgrey;
padding: 20px;
h1 { h1 {
color: $black; color: $black;
text-align: center; text-align: center;
margin-bottom: 5px; margin-bottom: 20px;
font-weight: bold; font-weight: bold;
} }
h2 { h2 {
color: $darkestgrey; color: $darkestgrey;
font-size: 14px; font-size: 12px;
text-align: center; text-align: center;
} }
} }
.details { .details {
width: 75%; dl {
margin: 20px auto; padding: 40px 40px 40px 40px;
}
dt { dt {
text-align: left; text-align: left;
@ -38,36 +48,28 @@
dd { dd {
text-align: right; text-align: right;
font-weight: 400; font-weight: 400;
padding: 19px 0; padding: 30px 0 10px 0;
margin-left: 0; margin-left: 0;
border-top: 1px solid $darkgrey; border-bottom: 1px solid $darkgrey;
} }
} }
.close { .close {
text-align: center; text-align: center;
padding-bottom: 40px;
div { div {
width: 35%;
margin: 0 auto; margin: 0 auto;
cursor: pointer; cursor: pointer;
height: 55px;
min-height: 55px;
text-transform: none;
font-size: 18px; font-size: 18px;
transition: opacity .2s ease-out; color: $red;
background: $red;
color: $white;
border: none; border: none;
font-weight: 500;
padding: 0; padding: 0;
text-align: center; text-align: center;
line-height: 55px;
transition: all 0.25s; transition: all 0.25s;
border-radius: 5px;
&:hover { &:hover {
background: darken($red, 10%); color: lighten($red, 10%);
} }
} }
} }

54
app/components/Wallet/ReceiveModal.js

@ -4,9 +4,11 @@ import ReactModal from 'react-modal'
import copy from 'copy-to-clipboard' import copy from 'copy-to-clipboard'
import QRCode from 'qrcode.react' import QRCode from 'qrcode.react'
import { showNotification } from 'notifications' import { showNotification } from 'notifications'
import { MdClose } from 'react-icons/lib/md'
import { FaCopy } from 'react-icons/lib/fa'
import styles from './ReceiveModal.scss' import styles from './ReceiveModal.scss'
const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress }) => { const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress, qrCodeType, changeQrCode }) => {
const customStyles = { const customStyles = {
overlay: { overlay: {
cursor: 'pointer' cursor: 'pointer'
@ -16,8 +18,10 @@ const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress }
left: '20%', left: '20%',
right: '0', right: '0',
bottom: 'auto', bottom: 'auto',
width: '60%', width: '40%',
margin: '50px auto' margin: '50px auto',
borderRadius: 'none',
padding: '0'
} }
} }
@ -36,22 +40,48 @@ const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress }
parentSelector={() => document.body} parentSelector={() => document.body}
style={customStyles} style={customStyles}
> >
<div className={styles.closeContainer}>
<span onClick={() => hideActivityModal()}>
<MdClose />
</span>
</div>
<div className={styles.container}> <div className={styles.container}>
<section> <header>
<h4>Node Public Key (<span onClick={() => copyOnClick(pubkey)}>Copy</span>)</h4> <div className={styles.qrcodes}>
<p>{pubkey}</p> <QRCode value={qrCodeType === 1 ? address : pubkey} />
</section> </div>
<ul className={styles.tabs}>
<li className={qrCodeType === 1 && styles.active} onClick={changeQrCode}>
Wallet address
</li>
<li className={qrCodeType === 2 && styles.active} onClick={changeQrCode}>
Node pubkey
</li>
</ul>
</header>
<section> <section>
<div className={styles.addressHeader}> <div className={styles.addressHeader}>
<h4>Deposit Address (<span onClick={() => copyOnClick(address)}>Copy</span>)</h4> <h4>Deposit Address</h4>
<span className={styles.newAddress} onClick={() => newAddress('p2pkh')}>New Address</span> <span className={styles.newAddress} onClick={() => newAddress('p2pkh')}>New Address</span>
</div> </div>
<p>{address}</p> <p>
<span>{address}</span>
<span onClick={() => copyOnClick(address)} className='hint--left' data-hint='Copy address'>
<FaCopy />
</span>
</p>
</section>
<div className={styles.qrcode}> <section>
<QRCode value={address} /> <h4>Node Public Key</h4>
</div> <p>
<span>{pubkey}</span>
<span onClick={() => copyOnClick(pubkey)} className='hint--left' data-hint='Copy pubkey'>
<FaCopy />
</span>
</p>
</section> </section>
</div> </div>
</ReactModal> </ReactModal>

79
app/components/Wallet/ReceiveModal.scss

@ -1,15 +1,59 @@
@import '../../variables.scss'; @import '../../variables.scss';
.closeContainer {
background: $lightgrey;
text-align: right;
padding: 10px;
span {
color: $darkestgrey;
font-size: 20px;
cursor: pointer;
}
}
.container { .container {
header {
background: $lightgrey;
padding: 10px 40px 40px;
text-align: center;
.qrcodes {
text-align: center;
margin-top: 20px;
}
.tabs {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 20px;
li {
margin: 0 20px;
color: $darkestgrey;
transition: all 0.25s;
&:hover {
color: $black;
}
&.active {
color: $black;
font-weight: bold;
}
}
}
}
section { section {
margin: 25px 0; margin: 25px 0;
padding: 25px; padding: 25px;
border-bottom: 1px solid $darkestgrey;
h4 { h4 {
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
text-transform: uppercase;
letter-spacing: 1.5px; letter-spacing: 1.5px;
margin-bottom: 10px; margin-bottom: 10px;
@ -19,20 +63,33 @@
} }
} }
.qrcode {
text-align: center;
margin-top: 20px;
}
p { p {
display: flex;
flex-direction: row;
font-family: 'Roboto'; font-family: 'Roboto';
text-align: center;
font-size: 14px; font-size: 14px;
font-weight: 200; font-weight: 200;
border-radius: 7px;
background: $lightgrey; background: $lightgrey;
border: 1px solid $main;
padding: 10px; span {
padding: 15px;
}
span:nth-child(1) {
flex: 9;
overflow-x: scroll;
}
span:nth-child(2) {
background: $darkgrey;
color: $black;
cursor: pointer;
transition: all 0.25s;
&:hover {
background: $darkestgrey;
}
}
} }
} }
} }

21
app/components/Wallet/Wallet.js

@ -13,7 +13,8 @@ class Wallet extends Component {
super(props) super(props)
this.state = { this.state = {
modalOpen: false modalOpen: false,
qrCodeType: 1
} }
} }
@ -25,19 +26,29 @@ class Wallet extends Component {
newAddress newAddress
} = this.props } = this.props
const { modalOpen } = this.state const { modalOpen, qrCodeType } = this.state
const changeQrCode = () => {
const qrCodeType = this.state.qrCodeType === 1 ? 2 : 1
this.setState({ qrCodeType })
}
return ( return (
<div className={styles.wallet}> <div className={styles.wallet}>
{ {
(modalOpen && (
modalOpen &&
<ReceiveModal <ReceiveModal
isOpen={modalOpen} isOpen={modalOpen}
hideActivityModal={() => this.setState({ modalOpen: false })} hideActivityModal={() => this.setState({ modalOpen: false })}
pubkey={info.data.identity_pubkey} pubkey={info.data.identity_pubkey}
address={address} address={address}
newAddress={newAddress} newAddress={newAddress}
/>) qrCodeType={qrCodeType}
changeQrCode={changeQrCode}
/>
)
} }
<div className={styles.content}> <div className={styles.content}>
<div className={styles.left}> <div className={styles.left}>
@ -52,7 +63,7 @@ class Wallet extends Component {
</div> </div>
<div className={styles.right}> <div className={styles.right}>
<div className={styles.rightContent}> <div className={styles.rightContent}>
<div onClick={() => this.setState({ modalOpen: true })}> <div className={'buttonPrimary'} onClick={() => this.setState({ modalOpen: true })}>
<FaQrcode /> <FaQrcode />
Address Address
</div> </div>

4
app/components/Wallet/Wallet.scss

@ -58,10 +58,10 @@
height: calc(100% - 50px); height: calc(100% - 50px);
div { div {
font-size: 20px; padding: 7px 20px;
padding: 10px 25px;
background: $main; background: $main;
transition: background 0.25s; transition: background 0.25s;
color: $black;
&:hover { &:hover {
background: darken($main, 10%); background: darken($main, 10%);

9
app/lnd/methods/paymentsController.js

@ -6,10 +6,13 @@
*/ */
export function sendPaymentSync(lnd, { paymentRequest }) { export function sendPaymentSync(lnd, { paymentRequest }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
lnd.sendPaymentSync({ payment_request: paymentRequest }, (err, data) => { lnd.sendPaymentSync({ payment_request: paymentRequest }, (error, data) => {
if (err) { reject(err) } if (error) {
reject({ error })
return
}
if (!data.payment_route) { reject({ error: data.payment_error }) } if (!data || !data.payment_route) { reject({ error: data.payment_error }) }
resolve(data) resolve(data)
}) })

2
app/lnd/subscribe/transactions.js

@ -9,5 +9,5 @@ export default function subscribeToTransactions(mainWindow, lnd) {
}) })
call.on('end', () => console.log('end')) call.on('end', () => console.log('end'))
call.on('error', error => console.log('error: ', error)) call.on('error', error => console.log('error: ', error))
call.on('status', status => console.log('status: ', status)) call.on('status', status => console.log('TRANSACTION STATUS: ', status))
} }

1
app/main.dev.js

@ -165,6 +165,7 @@ export const startLnd = () => {
'--bitcoin.active', '--bitcoin.active',
'--bitcoin.testnet', '--bitcoin.testnet',
'--neutrino.active', '--neutrino.active',
'--neutrino.connect=btcd0.lightning.computer:18333',
'--neutrino.connect=faucet.lightning.community:18333', '--neutrino.connect=faucet.lightning.community:18333',
'--autopilot.active', '--autopilot.active',
'--debuglevel=debug', '--debuglevel=debug',

15
app/reducers/channels.js

@ -165,27 +165,32 @@ export const closeChannel = ({ channel_point }) => (dispatch) => {
// TODO: Decide how to handle streamed updates for closing channels // TODO: Decide how to handle streamed updates for closing channels
// Receive IPC event for closeChannel // Receive IPC event for closeChannel
export const closeChannelSuccessful = () => (dispatch) => { export const closeChannelSuccessful = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL SUCCESSFUL: ', data)
dispatch(fetchChannels()) dispatch(fetchChannels())
} }
// Receive IPC event for updated closing channel // Receive IPC event for updated closing channel
export const pushclosechannelupdated = () => (dispatch) => { export const pushclosechannelupdated = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL UPDATED: ', data)
dispatch(fetchChannels()) dispatch(fetchChannels())
} }
// Receive IPC event for closing channel end // Receive IPC event for closing channel end
export const pushclosechannelend = () => (dispatch) => { export const pushclosechannelend = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL END: ', data)
dispatch(fetchChannels()) dispatch(fetchChannels())
} }
// Receive IPC event for closing channel error // Receive IPC event for closing channel error
export const pushclosechannelerror = () => (dispatch) => { export const pushclosechannelerror = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL END: ', data)
dispatch(fetchChannels()) dispatch(fetchChannels())
} }
// Receive IPC event for closing channel status // Receive IPC event for closing channel status
export const pushclosechannelstatus = () => (dispatch) => { export const pushclosechannelstatus = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL STATUS: ', data)
dispatch(fetchChannels()) dispatch(fetchChannels())
} }

5
app/reducers/info.js

@ -1,7 +1,6 @@
import { createSelector } from 'reselect' import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import { fetchBalance } from './balance'
import { newAddress } from './address'
// ------------------------------------ // ------------------------------------
// Constants // Constants
// ------------------------------------ // ------------------------------------
@ -25,8 +24,6 @@ export const fetchInfo = () => async (dispatch) => {
// Receive IPC event for info // Receive IPC event for info
export const receiveInfo = (event, data) => (dispatch) => { export const receiveInfo = (event, data) => (dispatch) => {
dispatch(fetchBalance())
dispatch(newAddress('p2pkh'))
dispatch({ type: RECEIVE_INFO, data }) dispatch({ type: RECEIVE_INFO, data })
} }

1
app/routes/activity/components/components/Modal/Invoice/Invoice.js

@ -6,7 +6,6 @@ import 'moment-timezone'
import QRCode from 'qrcode.react' import QRCode from 'qrcode.react'
import { MdCheck } from 'react-icons/lib/md'
import { FaCircle } from 'react-icons/lib/fa' import { FaCircle } from 'react-icons/lib/fa'
import CurrencyIcon from 'components/CurrencyIcon' import CurrencyIcon from 'components/CurrencyIcon'

Loading…
Cancel
Save