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. 54
      app/components/Activity/TransactionModal.js
  3. 129
      app/components/Activity/TransactionModal.scss
  4. 21
      app/components/Wallet/Wallet.js
  5. 53
      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;
} }
} }

54
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,10 +29,24 @@ 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>
</section>
<section className={styles.details}>
<div>
<Isvg src={link} />
<span className={styles.link} onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>On-Chain</span>
</div>
<div>
<Value value={transaction.total_fees} currency={ticker.currency} currentTicker={currentTicker} />
<span> {currencyName} fee</span>
</div>
</section>
</header>
<div className={styles.amount}>
<h1> <h1>
<i className={`${styles.symbol} ${transaction.amount > 0 && styles.active}`}> <i className={`${styles.symbol} ${transaction.amount > 0 && styles.active}`}>
{ {
@ -40,7 +60,6 @@ const TransactionModal = ({
</h1> </h1>
<section className={styles.currentCurrency} onClick={() => setActivityModalCurrencyFilters(!showCurrencyFilters)}> <section className={styles.currentCurrency} onClick={() => setActivityModalCurrencyFilters(!showCurrencyFilters)}>
<span>{currencyName}</span><span><FaAngleDown /></span> <span>{currencyName}</span><span><FaAngleDown /></span>
</section>
<ul className={showCurrencyFilters && styles.active}> <ul className={showCurrencyFilters && styles.active}>
{ {
currentCurrencyFilters.map(filter => currentCurrencyFilters.map(filter =>
@ -48,27 +67,16 @@ const TransactionModal = ({
} }
</ul> </ul>
</section> </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 className={styles.bottom}>
<div className={styles.txHash}>
<h4>Transaction</h4>
<p onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>{transaction.tx_hash}</p>
</div>
<div className={styles.blockHash}>
<h4>Block</h4>
<p onClick={() => blockExplorer.showBlock(transaction.block_hash)}>{transaction.block_hash}</p>
</div> </div>
</section>
<div className={styles.date}>
<Moment format='LLL'>{transaction.time_stamp * 1000}</Moment>
</div> </div>
<footer className={styles.footer}>
<p onClick={() => blockExplorer.showTransaction(transaction.tx_hash)}>{transaction.tx_hash}</p>
</footer>
</div> </div>
) )

129
app/components/Activity/TransactionModal.scss

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

53
app/components/Wallet/Wallet.scss

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