Browse Source

feature(wallet): build new wallet modal/refactor current wallet component

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
54c31e2de3
  1. 1
      app/components/Form/Form.scss
  2. 4
      app/components/Form/Pay.js
  3. 75
      app/components/Wallet/ReceiveModal.js
  4. 25
      app/components/Wallet/ReceiveModal.scss
  5. 51
      app/components/Wallet/Wallet.js
  6. 21
      app/components/Wallet/Wallet.scss
  7. 23
      app/reducers/address.js
  8. 11
      app/routes/activity/containers/ActivityContainer.js
  9. 3
      app/routes/app/components/App.js
  10. 13
      app/routes/app/containers/AppContainer.js

1
app/components/Form/Form.scss

@ -24,4 +24,3 @@
color: $white;
}
}

4
app/components/Form/Pay.js

@ -60,9 +60,6 @@ class Pay extends Component {
setCurrency
} = this.props
console.log('errors: ', errors)
console.log('showErrors: ', showErrors)
const displayNodeName = (pubkey) => {
const node = find(nodes, n => n.pub_key === pubkey)
@ -83,7 +80,6 @@ class Pay extends Component {
return (
<div className={styles.container}>
{showPayLoadingScreen && <LoadingBolt />}
<header className={styles.header}>
<Isvg src={paperPlane} />
<h1>Make Payment</h1>

75
app/components/Wallet/ReceiveModal.js

@ -1,55 +1,57 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactModal from 'react-modal'
import copy from 'copy-to-clipboard'
import QRCode from 'qrcode.react'
import { showNotification } from 'notifications'
import { FaCopy } from 'react-icons/lib/fa'
import { MdClose } from 'react-icons/lib/md'
import Isvg from 'react-inlinesvg'
import x from 'icons/x.svg'
import { showNotification } from 'notifications'
import styles from './ReceiveModal.scss'
const ReceiveModal = ({
isOpen, hideActivityModal, pubkey, address, newAddress, qrCodeType, changeQrCode
}) => {
const customStyles = {
overlay: {
cursor: 'pointer'
},
content: {
top: 'auto',
left: '0',
right: '0',
bottom: 'auto',
width: '40%',
margin: '50px auto',
borderRadius: 'none',
padding: '0'
class ReceiveModal extends React.Component {
constructor(props) {
super(props)
this.state = {
qrCodeType: 1
}
}
render() {
const copyOnClick = (data) => {
copy(data)
showNotification('Noice', 'Successfully copied to clipboard')
}
const changeQrCode = () => {
if (this.state.qrCodeType === 1) {
this.setState({ qrCodeType: 2 })
} else {
this.setState({ qrCodeType: 1 })
}
}
const {
isOpen,
pubkey,
address,
newAddress,
closeReceiveModal
} = this.props
const { qrCodeType } = this.state
if (!isOpen) { return null }
return (
<ReactModal
isOpen={isOpen}
ariaHideApp
shouldCloseOnOverlayClick
contentLabel='No Overlay Click Modal'
onRequestClose={() => hideActivityModal()}
parentSelector={() => document.body}
style={customStyles}
>
<div className={styles.container}>
<div className={styles.closeContainer}>
<span onClick={() => hideActivityModal()}>
<MdClose />
<span onClick={closeReceiveModal}>
<Isvg src={x} />
</span>
</div>
<div className={styles.container}>
<header>
<header className={styles.header}>
<div className={styles.qrcodes}>
<QRCode value={qrCodeType === 1 ? address : pubkey} />
</div>
@ -86,18 +88,15 @@ const ReceiveModal = ({
</p>
</section>
</div>
</ReactModal>
)
}
}
ReceiveModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
hideActivityModal: PropTypes.func.isRequired,
pubkey: PropTypes.string.isRequired,
address: PropTypes.string.isRequired,
newAddress: PropTypes.func.isRequired,
changeQrCode: PropTypes.func.isRequired,
qrCodeType: PropTypes.number.isRequired
newAddress: PropTypes.func.isRequired
}
export default ReceiveModal

25
app/components/Wallet/ReceiveModal.scss

@ -1,19 +1,31 @@
@import '../../variables.scss';
.container {
position: relative;
height: 100vh;
background: $bluegrey;
}
.closeContainer {
background: $lightgrey;
text-align: right;
padding: 10px;
padding: 20px 40px 0px;
span {
color: $darkestgrey;
font-size: 20px;
cursor: pointer;
opacity: 1.0;
transition: 0.25s all;
&:hover {
opacity: 0.5;
}
}
.container {
header {
svg {
color: $white;
}
}
.header {
background: $lightgrey;
padding: 10px 40px 40px;
text-align: center;
@ -92,7 +104,6 @@
}
}
}
}
.addressHeader {
display: flex;

51
app/components/Wallet/Wallet.js

@ -2,62 +2,32 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { FaAngleDown } from 'react-icons/lib/fa'
import Isvg from 'react-inlinesvg'
import { btc } from 'utils'
import Value from 'components/Value'
import bitcoinIcon from 'icons/bitcoin.svg'
import zapLogo from 'icons/zap_logo.svg'
import qrCode from 'icons/qrcode.svg'
import ReceiveModal from './ReceiveModal'
import styles from './Wallet.scss'
class Wallet extends Component {
constructor(props) {
super(props)
this.state = {
modalOpen: false,
qrCodeType: 1
}
}
render() {
const {
const Wallet = ({
balance,
address,
info,
newAddress,
openReceiveModal,
ticker,
currentTicker,
openPayForm,
openRequestForm
} = this.props
const { modalOpen, qrCodeType } = this.state
openRequestForm,
showPayLoadingScreen
}) => {
const usdAmount = btc.satoshisToUsd((parseInt(balance.walletBalance, 10) + parseInt(balance.channelBalance, 10)), currentTicker.price_usd)
const changeQrCode = () => {
const qrCodeNum = this.state.qrCodeType === 1 ? 2 : 1
this.setState({ qrCodeType: qrCodeNum })
}
return (
<div className={styles.wallet}>
{
(
modalOpen &&
<ReceiveModal
isOpen={modalOpen}
hideActivityModal={() => this.setState({ modalOpen: false })}
pubkey={info.data.identity_pubkey}
address={address}
newAddress={newAddress}
qrCodeType={qrCodeType}
changeQrCode={changeQrCode}
/>
)
}
<div className={styles.content}>
<header className={styles.header}>
<section className={styles.logo}>
@ -85,7 +55,7 @@ class Wallet extends Component {
/>
<i className={styles.currency}>{btc.renderCurrency(ticker.currency)}</i>
</span>
<span onClick={() => this.setState({ modalOpen: true })}>
<span onClick={openReceiveModal}>
<Isvg className={styles.bitcoinLogo} src={qrCode} />
</span>
</h1>
@ -98,12 +68,15 @@ class Wallet extends Component {
<div className={styles.pay} onClick={openPayForm}>Pay</div>
<div className={styles.request} onClick={openRequestForm}>Request</div>
</div>
<div className={styles.notificationBox}>
<section className={styles.spinner} />
<section>Gang gang gang baby</section>
</div>
</div>
</div>
</div>
)
}
}
Wallet.propTypes = {
balance: PropTypes.object.isRequired,

21
app/components/Wallet/Wallet.scss

@ -141,6 +141,27 @@
margin-right: 20px;
}
}
.notificationBox {
text-align: right;
font-size: 12px;
}
}
.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;
}
.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;
}

23
app/reducers/address.js

@ -5,6 +5,9 @@ import { ipcRenderer } from 'electron'
export const GET_ADDRESS = 'GET_ADDRESS'
export const RECEIVE_ADDRESS = 'RECEIVE_ADDRESS'
export const OPEN_WALLET_MODAL = 'OPEN_WALLET_MODAL'
export const CLOSE_WALLET_MODAL = 'CLOSE_WALLET_MODAL'
// LND expects types to be sent as int, so this object will allow mapping from string to int
const addressTypes = {
p2wkh: 0,
@ -21,6 +24,18 @@ export function getAddress() {
}
}
export function openWalletModal() {
return {
type: OPEN_WALLET_MODAL
}
}
export function closeWalletModal() {
return {
type: CLOSE_WALLET_MODAL
}
}
// Send IPC event for getinfo
export const newAddress = type => async (dispatch) => {
dispatch(getAddress())
@ -35,7 +50,10 @@ export const receiveAddress = (event, address) => dispatch => dispatch({ type: R
// ------------------------------------
const ACTION_HANDLERS = {
[GET_ADDRESS]: state => ({ ...state, addressLoading: true }),
[RECEIVE_ADDRESS]: (state, { address }) => ({ ...state, addressLoading: false, address })
[RECEIVE_ADDRESS]: (state, { address }) => ({ ...state, addressLoading: false, address }),
[OPEN_WALLET_MODAL]: state => ({ ...state, walletModal: true }),
[CLOSE_WALLET_MODAL]: state => ({ ...state, walletModal: false })
}
// ------------------------------------
@ -43,7 +61,8 @@ const ACTION_HANDLERS = {
// ------------------------------------
const initialState = {
addressLoading: false,
address: ''
address: '',
walletModal: false
}
export default function addressReducer(state = initialState, action) {

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

@ -20,9 +20,11 @@ import {
activitySelectors,
updateSearchText
} from 'reducers/activity'
import { newAddress } from 'reducers/address'
import { newAddress, openWalletModal } from 'reducers/address'
import { setFormType } from 'reducers/form'
import { payFormSelectors } from 'reducers/payform'
import Activity from '../components/Activity'
const mapDispatchToProps = {
@ -37,6 +39,7 @@ const mapDispatchToProps = {
changeFilter,
toggleFilterPulldown,
newAddress,
openWalletModal,
fetchBalance,
updateSearchText,
setFormType
@ -62,7 +65,9 @@ const mapStateToProps = state => ({
currentTicker: tickerSelectors.currentTicker(state),
currentActivity: activitySelectors.currentActivity(state)(state),
nonActiveFilters: activitySelectors.nonActiveFilters(state)
nonActiveFilters: activitySelectors.nonActiveFilters(state),
showPayLoadingScreen: payFormSelectors.showPayLoadingScreen(state),
})
const mergeProps = (stateProps, dispatchProps, ownProps) => {
@ -72,9 +77,11 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
info: stateProps.info,
ticker: stateProps.ticker,
currentTicker: stateProps.currentTicker,
showPayLoadingScreen: stateProps.showPayLoadingScreen,
setCurrency: dispatchProps.setCurrency,
newAddress: dispatchProps.newAddress,
openReceiveModal: dispatchProps.openWalletModal,
openPayForm: () => dispatchProps.setFormType('PAY_FORM'),
openRequestForm: () => dispatchProps.setFormType('REQUEST_FORM')
}

3
app/routes/app/components/App.js

@ -11,6 +11,7 @@ import Network from 'components/Contacts/Network'
import ContactModal from 'components/Contacts/ContactModal'
import ContactsForm from 'components/Contacts/ContactsForm'
import ReceiveModal from 'components/Wallet/ReceiveModal'
import ActivityModal from 'components/Activity/ActivityModal'
import styles from './App.scss'
@ -57,6 +58,7 @@ class App extends Component {
contactModalProps,
contactsFormProps,
networkTabProps,
receiveModalProps,
activityModalProps,
children
@ -81,6 +83,7 @@ class App extends Component {
<Form formType={form.formType} formProps={formProps} closeForm={closeForm} />
<ReceiveModal {...receiveModalProps} />
<ActivityModal {...activityModalProps} />
<div className={styles.content}>

13
app/routes/app/containers/AppContainer.js

@ -3,7 +3,7 @@ import { connect } from 'react-redux'
import { fetchTicker, setCurrency, tickerSelectors } from 'reducers/ticker'
import { newAddress } from 'reducers/address'
import { newAddress, closeWalletModal } from 'reducers/address'
import { fetchInfo } from 'reducers/info'
@ -61,6 +61,7 @@ const mapDispatchToProps = {
setCurrency,
newAddress,
closeWalletModal,
fetchInfo,
@ -339,6 +340,14 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
}
}
const receiveModalProps = {
isOpen: stateProps.address.walletModal,
pubkey: stateProps.info.data.identity_pubkey,
address: stateProps.address.address,
newAddress: dispatchProps.newAddress,
closeReceiveModal: dispatchProps.closeWalletModal
}
return {
...stateProps,
...dispatchProps,
@ -350,6 +359,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
contactsFormProps,
// props for the contact modal
contactModalProps,
// props for the receive modal
receiveModalProps,
// props for the activity modals
activityModalProps,
// Props to pass to the pay form

Loading…
Cancel
Save