Browse Source

fix(on-chain): fix on chain modal to new styles

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
91eb5e32c5
  1. 10
      app/animated_checkmark.scss
  2. 90
      app/components/Activity/TransactionModal.js
  3. 203
      app/components/Activity/TransactionModal.scss
  4. 21
      app/components/Wallet/Wallet.js
  5. 65
      app/components/Wallet/Wallet.scss
  6. 1
      app/lnd/methods/paymentsController.js
  7. 50
      app/reducers/payment.js
  8. 4
      app/routes/activity/components/Activity.js
  9. 1
      app/routes/activity/containers/ActivityContainer.js

10
app/animated_checkmark.scss

@ -5,19 +5,19 @@ $curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);
stroke-dashoffset: 166;
stroke-width: 2;
stroke-miterlimit: 10;
stroke: $gold;
stroke: $green;
fill: none;
animation: stroke .6s $curve forwards;
}
.checkmark {
width: 56px;
height: 56px;
width: 20px;
height: 20px;
border-radius: 50%;
stroke-width: 2;
stroke: #fff;
stroke-miterlimit: 10;
box-shadow: inset 0px 0px 0px $gold;
box-shadow: inset 0px 0px 0px $green;
animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both;
}
@ -45,6 +45,6 @@ $curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);
@keyframes fill {
100% {
box-shadow: inset 0px 0px 0px 30px $gold;
box-shadow: inset 0px 0px 0px 30px $green;
}
}

90
app/components/Activity/TransactionModal.js

@ -1,8 +1,14 @@
import React from 'react'
import PropTypes from 'prop-types'
import Moment from 'react-moment'
import 'moment-timezone'
import { FaAngleDown } from 'react-icons/lib/fa'
import Isvg from 'react-inlinesvg'
import paperPlane from 'icons/paper_plane.svg'
import link from 'icons/link.svg'
import { blockExplorer } from 'utils'
import Value from 'components/Value'
@ -23,52 +29,54 @@ const TransactionModal = ({
}
}) => (
<div className={styles.container}>
<div className={styles.content}>
<section className={styles.top}>
<div className={styles.details}>
<section className={styles.amount}>
<h1>
<i className={`${styles.symbol} ${transaction.amount > 0 && styles.active}`}>
{
transaction.amount > 0 ?
'+'
:
'-'
}
</i>
<Value value={transaction.amount} currency={ticker.currency} currentTicker={currentTicker} />
</h1>
<section className={styles.currentCurrency} onClick={() => setActivityModalCurrencyFilters(!showCurrencyFilters)}>
<span>{currencyName}</span><span><FaAngleDown /></span>
</section>
<ul className={showCurrencyFilters && styles.active}>
{
currentCurrencyFilters.map(filter =>
<li key={filter.key} onClick={() => onCurrencyFilterClick(filter.key)}>{filter.name}</li>)
}
</ul>
</section>
<section className={styles.date}>
<p>{transaction.num_confirmations} {transaction.num_confirmations > 1 ? 'confirmations' : 'confirmation'}</p>
<p>
<Value value={transaction.total_fees} currency={ticker.currency} currentTicker={currentTicker} />
<span> {currencyName} fee</span>
</p>
</section>
</div>
<header className={styles.header}>
<section>
<Isvg src={paperPlane} />
<span>Sent</span>
</section>
<section className={styles.bottom}>
<div className={styles.txHash}>
<h4>Transaction</h4>
<p onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>{transaction.tx_hash}</p>
<section className={styles.details}>
<div>
<Isvg src={link} />
<span className={styles.link} onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>On-Chain</span>
</div>
<div className={styles.blockHash}>
<h4>Block</h4>
<p onClick={() => blockExplorer.showBlock(transaction.block_hash)}>{transaction.block_hash}</p>
<div>
<Value value={transaction.total_fees} currency={ticker.currency} currentTicker={currentTicker} />
<span> {currencyName} fee</span>
</div>
</section>
</header>
<div className={styles.amount}>
<h1>
<i className={`${styles.symbol} ${transaction.amount > 0 && styles.active}`}>
{
transaction.amount > 0 ?
'+'
:
'-'
}
</i>
<Value value={transaction.amount} currency={ticker.currency} currentTicker={currentTicker} />
</h1>
<section className={styles.currentCurrency} onClick={() => setActivityModalCurrencyFilters(!showCurrencyFilters)}>
<span>{currencyName}</span><span><FaAngleDown /></span>
<ul className={showCurrencyFilters && styles.active}>
{
currentCurrencyFilters.map(filter =>
<li key={filter.key} onClick={() => onCurrencyFilterClick(filter.key)}>{filter.name}</li>)
}
</ul>
</section>
</div>
<div className={styles.date}>
<Moment format='LLL'>{transaction.time_stamp * 1000}</Moment>
</div>
<footer className={styles.footer}>
<p onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>{transaction.tx_hash}</p>
</footer>
</div>
)

203
app/components/Activity/TransactionModal.scss

@ -2,126 +2,133 @@
.container {
color: $white;
font-size: 12px;
width: 75%;
margin: 0 auto;
background: $spaceblue;
}
.content {
background: $spaceblue;
width: 85%;
margin: 50px auto;
padding-top: 30px;
.top {
padding: 10px 60px;
.details {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 40px;
.amount {
display: flex;
flex-direction: row;
align-items: center;
position: relative;
.symbol {
color: $red;
&.active {
color: $green;
}
}
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 20px;
section {
&:nth-child(1) {
font-size: 16px;
color: $green;
svg {
width: 16px;
height: 16px;
vertical-align: top;
fill: $green;
}
h1 {
font-size: 40px;
margin-right: 10px;
}
span:nth-child(2) {
margin-left: 5px;
}
}
.currentCurrency {
cursor: pointer;
transition: 0.25s all;
&.details {
text-align: right;
&:hover {
opacity: 0.5;
}
div:nth-child(1) {
margin-bottom: 5px;
}
span {
font-size: 14px;
&:nth-child(1) {
font-weight: bold;
}
}
svg {
width: 12px;
height: 12px;
vertical-align: middle;
}
}
.link {
text-decoration: underline;
margin-left: 5px;
cursor: pointer;
transition: all 0.25s;
ul {
visibility: hidden;
position: absolute;
top: 40px;
right: -50px;
&.active {
visibility: visible;
}
li {
padding: 8px 15px;
background: #191919;
cursor: pointer;
transition: 0.25s hover;
border-bottom: 1px solid #0f0f0f;
&:hover {
background: #0f0f0f;
}
}
&:hover {
opacity: 0.5;
}
}
}
}
}
.date {
font-size: 12px;
text-align: right;
.amount {
margin-top: 50px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 20px;
.notPaid {
color: #FF8A65;
margin-top: 5px;
}
h1 {
font-size: 40px;
}
section {
font-size: 20px;
margin-left: 10px;
position: relative;
cursor: pointer;
&:hover {
span {
opacity: 0.5;
}
}
span {
transition: all 0.25s;
}
ul {
visibility: hidden;
position: absolute;
top: 40px;
right: -50px;
font-size: 12px;
&.active {
visibility: visible;
}
p {
margin-bottom: 5px;
li {
padding: 8px 15px;
background: #191919;
cursor: pointer;
transition: 0.25s hover;
border-bottom: 1px solid #0f0f0f;
&:nth-child(2) {
opacity: 0.5;
}
&:hover {
background: #0f0f0f;
}
}
}
}
}
.bottom {
background: #31343f;
padding: 40px;
.date {
text-align: center;
margin: 20px 0 50px 0;
padding: 20px;
}
.txHash, .blockHash {
margin: 40px 0;
h4 {
font-size: 10px;
margin-bottom: 10px;
}
.footer {
background: #31343f;
padding: 20px;
text-align: center;
p {
font-size: 14px;
text-decoration: underline;
cursor: pointer;
transition: all 0.25s;
p {
text-decoration: underline;
cursor: pointer;
&:hover {
opacity: 0.5;
}
&:hover {
opacity: 0.5;
}
}
}
}

21
app/components/Wallet/Wallet.js

@ -5,6 +5,7 @@ import Isvg from 'react-inlinesvg'
import { btc } from 'utils'
import Value from 'components/Value'
import AnimatedCheckmark from 'components/AnimatedCheckmark'
import bitcoinIcon from 'icons/bitcoin.svg'
import zapLogo from 'icons/zap_logo.svg'
@ -19,7 +20,9 @@ const Wallet = ({
ticker,
currentTicker,
openPayForm,
openRequestForm
openRequestForm,
showPayLoadingScreen,
showSuccessPayScreen
}) => {
const usdAmount = btc.satoshisToUsd((parseInt(balance.walletBalance, 10) + parseInt(balance.channelBalance, 10)), currentTicker.price_usd)
@ -66,8 +69,20 @@ const Wallet = ({
<div className={styles.request} onClick={openRequestForm}>Request</div>
</div>
<div className={styles.notificationBox}>
<section className={styles.spinner} />
<section>Gang gang gang baby</section>
{
showPayLoadingScreen &&
<span>
<section className={`${styles.spinner} ${styles.icon}`} />
<section>Sending your lightning payment...</section>
</span>
}
{
showSuccessPayScreen &&
<span>
<section className={styles.icon}><AnimatedCheckmark /></section>
<section>Successfully sent payment</section>
</span>
}
</div>
</div>
</div>

65
app/components/Wallet/Wallet.scss

@ -142,26 +142,57 @@
}
}
.notificationBox {
text-align: right;
font-size: 12px;
}
.notificationBox {
text-align: right;
font-size: 12px;
section {
display: inline-block;
vertical-align: middle;
transition: all 0.25s;
}
.spinner {
height: 20px;
width: 20px;
border: 1px solid rgba(235, 184, 100, 0.1);
border-left-color: rgba(235, 184, 100, 0.4);
-webkit-border-radius: 999px;
-moz-border-radius: 999px;
border-radius: 999px;
-webkit-animation: animation-rotate 1000ms linear infinite;
-moz-animation: animation-rotate 1000ms linear infinite;
-o-animation: animation-rotate 1000ms linear infinite;
animation: animation-rotate 1000ms linear infinite;
}
.icon {
margin-right: 5px;
}
}
.spinner {
border: 1px solid rgba(0, 0, 0, 0.1);
border-left-color: rgba(0, 0, 0, 0.4);
-webkit-border-radius: 999px;
-moz-border-radius: 999px;
border-radius: 999px;
@-webkit-keyframes animation-rotate {
100% {
-webkit-transform: rotate(360deg);
}
}
.spinner {
margin: 0 auto;
height: 20px;
width: 20px;
-webkit-animation: animation-rotate 1000ms linear infinite;
-moz-animation: animation-rotate 1000ms linear infinite;
-o-animation: animation-rotate 1000ms linear infinite;
animation: animation-rotate 1000ms linear infinite;
@-moz-keyframes animation-rotate {
100% {
-moz-transform: rotate(360deg);
}
}
@-o-keyframes animation-rotate {
100% {
-o-transform: rotate(360deg);
}
}
@keyframes animation-rotate {
100% {
transform: rotate(360deg);
}
}

1
app/lnd/methods/paymentsController.js

@ -14,6 +14,7 @@ export function sendPaymentSync(lnd, meta, { paymentRequest }) {
if (!data || !data.payment_route) { reject({ error: data.payment_error }) }
console.log('data: ', data)
resolve(data)
})
})

50
app/reducers/payment.js

@ -19,6 +19,9 @@ export const SEND_PAYMENT = 'SEND_PAYMENT'
export const PAYMENT_SUCCESSFULL = 'PAYMENT_SUCCESSFULL'
export const PAYMENT_FAILED = 'PAYMENT_FAILED'
export const SHOW_SUCCESS_SCREEN = 'SHOW_SUCCESS_SCREEN'
export const HIDE_SUCCESS_SCREEN = 'HIDE_SUCCESS_SCREEN'
// ------------------------------------
// Actions
// ------------------------------------
@ -48,6 +51,18 @@ export function paymentSuccessfull(payment) {
}
}
export function showSuccessScreen() {
return {
type: SHOW_SUCCESS_SCREEN
}
}
export function hideSuccessScreen() {
return {
type: HIDE_SUCCESS_SCREEN
}
}
// Send IPC event for payments
export const fetchPayments = () => (dispatch) => {
dispatch(getPayments())
@ -62,11 +77,10 @@ export const receivePayments = (event, { payments }) => dispatch => dispatch({ t
export const paymentSuccessful = () => (dispatch) => {
// Dispatch successful payment to stop loading screen
dispatch(paymentSuccessfull())
// Close the form modal once the payment was succesful
dispatch(setFormType(null))
// Show successful payment state
dispatch(showModal('SUCCESSFUL_SEND_PAYMENT'))
// Show successful payment state for 5 seconds
dispatch(showSuccessScreen())
setTimeout(() => dispatch(hideSuccessScreen()), 5000)
// Refetch payments (TODO: dont do a full refetch, rather append new tx to list)
dispatch(fetchPayments())
@ -86,14 +100,17 @@ export const payInvoice = paymentRequest => (dispatch, getState) => {
dispatch(sendPayment())
ipcRenderer.send('lnd', { msg: 'sendPayment', data: { paymentRequest } })
// Close the form modal once the payment has been sent
dispatch(setFormType(null))
// if LND hangs on sending the payment we'll cut it after 10 seconds and return an error
setTimeout(() => {
const { payment } = getState()
// setTimeout(() => {
// const { payment } = getState()
if (payment.sendingPayment) {
dispatch(paymentFailed(null, { error: 'Shoot, we\'re having some trouble sending your payment.' }))
}
}, 10000)
// if (payment.sendingPayment) {
// dispatch(paymentFailed(null, { error: 'Shoot, we\'re having some trouble sending your payment.' }))
// }
// }, 10000)
}
@ -101,12 +118,16 @@ export const payInvoice = paymentRequest => (dispatch, getState) => {
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[SET_PAYMENT]: (state, { payment }) => ({ ...state, payment }),
[GET_PAYMENTS]: state => ({ ...state, paymentLoading: true }),
[SEND_PAYMENT]: state => ({ ...state, sendingPayment: true }),
[RECEIVE_PAYMENTS]: (state, { payments }) => ({ ...state, paymentLoading: false, payments }),
[SET_PAYMENT]: (state, { payment }) => ({ ...state, payment }),
[SEND_PAYMENT]: state => ({ ...state, sendingPayment: true }),
[PAYMENT_SUCCESSFULL]: state => ({ ...state, sendingPayment: false }),
[PAYMENT_FAILED]: state => ({ ...state, sendingPayment: false })
[PAYMENT_FAILED]: state => ({ ...state, sendingPayment: false }),
[SHOW_SUCCESS_SCREEN]: state => ({ ...state, showSuccessPayScreen: true }),
[HIDE_SUCCESS_SCREEN]: state => ({ ...state, showSuccessPayScreen: false })
}
const paymentSelectors = {}
@ -126,7 +147,8 @@ const initialState = {
sendingPayment: false,
paymentLoading: false,
payments: [],
payment: null
payment: null,
showSuccessPayScreen: false
}
export default function paymentReducer(state = initialState, action) {

4
app/routes/activity/components/Activity.js

@ -56,8 +56,8 @@ class Activity extends Component {
walletProps
} = this.props
if (invoiceLoading || paymentLoading) { return <LoadingBolt /> }
if (balance.balanceLoading) { return <LoadingBolt /> }
// if (invoiceLoading || paymentLoading) { return <LoadingBolt /> }
// if (balance.balanceLoading) { return <LoadingBolt /> }
if (!balance.channelBalance || !balance.walletBalance) { return <LoadingBolt /> }
return (

1
app/routes/activity/containers/ActivityContainer.js

@ -78,6 +78,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
ticker: stateProps.ticker,
currentTicker: stateProps.currentTicker,
showPayLoadingScreen: stateProps.showPayLoadingScreen,
showSuccessPayScreen: stateProps.payment.showSuccessPayScreen,
setCurrency: dispatchProps.setCurrency,
newAddress: dispatchProps.newAddress,

Loading…
Cancel
Save