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-dashoffset: 166;
stroke-width: 2; stroke-width: 2;
stroke-miterlimit: 10; stroke-miterlimit: 10;
stroke: $gold; stroke: $green;
fill: none; fill: none;
animation: stroke .6s $curve forwards; animation: stroke .6s $curve forwards;
} }
.checkmark { .checkmark {
width: 56px; width: 20px;
height: 56px; height: 20px;
border-radius: 50%; border-radius: 50%;
stroke-width: 2; stroke-width: 2;
stroke: #fff; stroke: #fff;
stroke-miterlimit: 10; 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; 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 { @keyframes fill {
100% { 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 React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Moment from 'react-moment'
import 'moment-timezone'
import { FaAngleDown } from 'react-icons/lib/fa' 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 { blockExplorer } from 'utils'
import Value from 'components/Value' import Value from 'components/Value'
@ -23,52 +29,54 @@ const TransactionModal = ({
} }
}) => ( }) => (
<div className={styles.container}> <div className={styles.container}>
<div className={styles.content}> <header className={styles.header}>
<section className={styles.top}> <section>
<div className={styles.details}> <Isvg src={paperPlane} />
<section className={styles.amount}> <span>Sent</span>
<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>
</section> </section>
<section className={styles.bottom}> <section className={styles.details}>
<div className={styles.txHash}> <div>
<h4>Transaction</h4> <Isvg src={link} />
<p onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>{transaction.tx_hash}</p> <span className={styles.link} onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>On-Chain</span>
</div> </div>
<div>
<div className={styles.blockHash}> <Value value={transaction.total_fees} currency={ticker.currency} currentTicker={currentTicker} />
<h4>Block</h4> <span> {currencyName} fee</span>
<p onClick={() => blockExplorer.showBlock(transaction.block_hash)}>{transaction.block_hash}</p>
</div> </div>
</section> </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>
<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> </div>
) )

203
app/components/Activity/TransactionModal.scss

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

21
app/components/Wallet/Wallet.js

@ -5,6 +5,7 @@ import Isvg from 'react-inlinesvg'
import { btc } from 'utils' import { btc } from 'utils'
import Value from 'components/Value' import Value from 'components/Value'
import AnimatedCheckmark from 'components/AnimatedCheckmark'
import bitcoinIcon from 'icons/bitcoin.svg' import bitcoinIcon from 'icons/bitcoin.svg'
import zapLogo from 'icons/zap_logo.svg' import zapLogo from 'icons/zap_logo.svg'
@ -19,7 +20,9 @@ const Wallet = ({
ticker, ticker,
currentTicker, currentTicker,
openPayForm, openPayForm,
openRequestForm openRequestForm,
showPayLoadingScreen,
showSuccessPayScreen
}) => { }) => {
const usdAmount = btc.satoshisToUsd((parseInt(balance.walletBalance, 10) + parseInt(balance.channelBalance, 10)), currentTicker.price_usd) 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 className={styles.request} onClick={openRequestForm}>Request</div>
</div> </div>
<div className={styles.notificationBox}> <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> </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 { @-webkit-keyframes animation-rotate {
border: 1px solid rgba(0, 0, 0, 0.1); 100% {
border-left-color: rgba(0, 0, 0, 0.4); -webkit-transform: rotate(360deg);
-webkit-border-radius: 999px; }
-moz-border-radius: 999px;
border-radius: 999px;
} }
.spinner { @-moz-keyframes animation-rotate {
margin: 0 auto; 100% {
height: 20px; -moz-transform: rotate(360deg);
width: 20px; }
-webkit-animation: animation-rotate 1000ms linear infinite; }
-moz-animation: animation-rotate 1000ms linear infinite;
-o-animation: animation-rotate 1000ms linear infinite; @-o-keyframes animation-rotate {
animation: animation-rotate 1000ms linear infinite; 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 }) } if (!data || !data.payment_route) { reject({ error: data.payment_error }) }
console.log('data: ', data)
resolve(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_SUCCESSFULL = 'PAYMENT_SUCCESSFULL'
export const PAYMENT_FAILED = 'PAYMENT_FAILED' export const PAYMENT_FAILED = 'PAYMENT_FAILED'
export const SHOW_SUCCESS_SCREEN = 'SHOW_SUCCESS_SCREEN'
export const HIDE_SUCCESS_SCREEN = 'HIDE_SUCCESS_SCREEN'
// ------------------------------------ // ------------------------------------
// Actions // 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 // Send IPC event for payments
export const fetchPayments = () => (dispatch) => { export const fetchPayments = () => (dispatch) => {
dispatch(getPayments()) dispatch(getPayments())
@ -62,11 +77,10 @@ export const receivePayments = (event, { payments }) => dispatch => dispatch({ t
export const paymentSuccessful = () => (dispatch) => { export const paymentSuccessful = () => (dispatch) => {
// Dispatch successful payment to stop loading screen // Dispatch successful payment to stop loading screen
dispatch(paymentSuccessfull()) dispatch(paymentSuccessfull())
// Close the form modal once the payment was succesful
dispatch(setFormType(null))
// Show successful payment state // Show successful payment state for 5 seconds
dispatch(showModal('SUCCESSFUL_SEND_PAYMENT')) dispatch(showSuccessScreen())
setTimeout(() => dispatch(hideSuccessScreen()), 5000)
// Refetch payments (TODO: dont do a full refetch, rather append new tx to list) // Refetch payments (TODO: dont do a full refetch, rather append new tx to list)
dispatch(fetchPayments()) dispatch(fetchPayments())
@ -86,14 +100,17 @@ export const payInvoice = paymentRequest => (dispatch, getState) => {
dispatch(sendPayment()) dispatch(sendPayment())
ipcRenderer.send('lnd', { msg: 'sendPayment', data: { paymentRequest } }) 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 // if LND hangs on sending the payment we'll cut it after 10 seconds and return an error
setTimeout(() => { // setTimeout(() => {
const { payment } = getState() // const { payment } = getState()
if (payment.sendingPayment) { // if (payment.sendingPayment) {
dispatch(paymentFailed(null, { error: 'Shoot, we\'re having some trouble sending your payment.' })) // dispatch(paymentFailed(null, { error: 'Shoot, we\'re having some trouble sending your payment.' }))
} // }
}, 10000) // }, 10000)
} }
@ -101,12 +118,16 @@ export const payInvoice = paymentRequest => (dispatch, getState) => {
// Action Handlers // Action Handlers
// ------------------------------------ // ------------------------------------
const ACTION_HANDLERS = { const ACTION_HANDLERS = {
[SET_PAYMENT]: (state, { payment }) => ({ ...state, payment }),
[GET_PAYMENTS]: state => ({ ...state, paymentLoading: true }), [GET_PAYMENTS]: state => ({ ...state, paymentLoading: true }),
[SEND_PAYMENT]: state => ({ ...state, sendingPayment: true }),
[RECEIVE_PAYMENTS]: (state, { payments }) => ({ ...state, paymentLoading: false, payments }), [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_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 = {} const paymentSelectors = {}
@ -126,7 +147,8 @@ const initialState = {
sendingPayment: false, sendingPayment: false,
paymentLoading: false, paymentLoading: false,
payments: [], payments: [],
payment: null payment: null,
showSuccessPayScreen: false
} }
export default function paymentReducer(state = initialState, action) { export default function paymentReducer(state = initialState, action) {

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

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

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

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

Loading…
Cancel
Save