Jack Mallers
7 years ago
63 changed files with 97 additions and 3454 deletions
@ -1,90 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import ReactModal from 'react-modal' |
|||
|
|||
import { FaClose } from 'react-icons/lib/fa' |
|||
|
|||
import StepOne from './StepOne' |
|||
import StepTwo from './StepTwo' |
|||
import StepThree from './StepThree' |
|||
import StepFour from './StepFour' |
|||
import Footer from './Footer' |
|||
|
|||
import styles from './ChannelForm.scss' |
|||
|
|||
const ChannelForm = ({ |
|||
channelform, |
|||
openChannel, |
|||
closeChannelForm, |
|||
changeStep, |
|||
setNodeKey, |
|||
setLocalAmount, |
|||
setPushAmount, |
|||
channelFormHeader, |
|||
channelFormProgress, |
|||
stepTwoIsValid, |
|||
peers |
|||
}) => { |
|||
const renderStep = () => { |
|||
const { step } = channelform |
|||
|
|||
switch (step) { |
|||
case 1: |
|||
return <StepOne peers={peers} changeStep={changeStep} setNodeKey={setNodeKey} /> |
|||
case 2: |
|||
return <StepTwo local_amt={channelform.local_amt} setLocalAmount={setLocalAmount} /> |
|||
case 3: |
|||
return <StepThree push_amt={channelform.push_amt} setPushAmount={setPushAmount} /> |
|||
default: |
|||
return <StepFour node_key={channelform.node_key} local_amt={channelform.local_amt} push_amt={channelform.push_amt} /> |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<ReactModal |
|||
isOpen={channelform.isOpen} |
|||
ariaHideApp |
|||
shouldCloseOnOverlayClick |
|||
contentLabel='No Overlay Click Modal' |
|||
onRequestClose={closeChannelForm} |
|||
parentSelector={() => document.body} |
|||
className={styles.modal} |
|||
> |
|||
<div onClick={closeChannelForm} className={styles.modalClose}> |
|||
<FaClose /> |
|||
</div> |
|||
|
|||
<header className={styles.header}> |
|||
<h3>{channelFormHeader}</h3> |
|||
<div className={styles.progress} style={{ width: `${channelFormProgress}%` }} /> |
|||
</header> |
|||
|
|||
<div className={styles.content}> |
|||
{renderStep()} |
|||
</div> |
|||
|
|||
<Footer |
|||
step={channelform.step} |
|||
changeStep={changeStep} |
|||
stepTwoIsValid={stepTwoIsValid} |
|||
submit={() => openChannel({ pubkey: channelform.node_key, local_amt: channelform.local_amt, push_amt: channelform.push_amt })} |
|||
/> |
|||
</ReactModal> |
|||
) |
|||
} |
|||
|
|||
ChannelForm.propTypes = { |
|||
channelform: PropTypes.object.isRequired, |
|||
openChannel: PropTypes.func.isRequired, |
|||
closeChannelForm: PropTypes.func.isRequired, |
|||
changeStep: PropTypes.func.isRequired, |
|||
setNodeKey: PropTypes.func.isRequired, |
|||
setLocalAmount: PropTypes.func.isRequired, |
|||
setPushAmount: PropTypes.func.isRequired, |
|||
channelFormHeader: PropTypes.string.isRequired, |
|||
channelFormProgress: PropTypes.number.isRequired, |
|||
stepTwoIsValid: PropTypes.bool.isRequired, |
|||
peers: PropTypes.array.isRequired |
|||
} |
|||
|
|||
export default ChannelForm |
@ -1,57 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.modal { |
|||
width: 40%; |
|||
margin: 50px auto; |
|||
position: absolute; |
|||
top: auto; |
|||
left: 20%; |
|||
right: 0; |
|||
bottom: auto; |
|||
background: $white; |
|||
outline: none; |
|||
z-index: -2; |
|||
border: 1px solid $darkgrey; |
|||
} |
|||
|
|||
.modalClose { |
|||
position: absolute; |
|||
top: -13px; |
|||
right: -13px; |
|||
display: block; |
|||
font-size: 16px; |
|||
line-height: 27px; |
|||
width: 32px; |
|||
height: 32px; |
|||
background: $white; |
|||
border-radius: 50%; |
|||
color: $darkestgrey; |
|||
cursor: pointer; |
|||
text-align: center; |
|||
z-index: 2; |
|||
transition: all 0.25s; |
|||
} |
|||
|
|||
.modalClose:hover { |
|||
background: $darkgrey; |
|||
} |
|||
|
|||
.header { |
|||
padding: 20px; |
|||
background: $lightgrey; |
|||
text-align: center; |
|||
font-family: 'Jigsaw Light'; |
|||
text-transform: uppercase; |
|||
position: relative; |
|||
z-index: -2; |
|||
} |
|||
|
|||
.progress { |
|||
transition: all 0.2s ease; |
|||
background: $main; |
|||
position: absolute; |
|||
height: 100%; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: -1; |
|||
} |
@ -1,46 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './Footer.scss' |
|||
|
|||
const Footer = ({ |
|||
step, changeStep, stepTwoIsValid, submit |
|||
}) => { |
|||
if (step === 1) { return null } |
|||
|
|||
// See if the next button on step 2 should be active
|
|||
const nextIsInactive = step === 2 && !stepTwoIsValid |
|||
|
|||
// Function that's called when the user clicks "next" in the form
|
|||
const nextFunc = () => { |
|||
if (nextIsInactive) { return } |
|||
|
|||
changeStep(step + 1) |
|||
} |
|||
|
|||
const rightButtonText = step === 4 ? 'Submit' : 'Next' |
|||
const rightButtonOnClick = step === 4 ? () => submit() : nextFunc |
|||
|
|||
return ( |
|||
<div className={styles.footer}> |
|||
<div className='buttonContainer'> |
|||
<div className='buttonPrimary' onClick={() => changeStep(step - 1)}> |
|||
Back |
|||
</div> |
|||
</div> |
|||
<div className='buttonContainer' onClick={rightButtonOnClick}> |
|||
<div className={`buttonPrimary ${nextIsInactive && 'inactive'}`}> |
|||
{rightButtonText} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
Footer.propTypes = { |
|||
step: PropTypes.number.isRequired, |
|||
changeStep: PropTypes.func.isRequired, |
|||
stepTwoIsValid: PropTypes.bool.isRequired, |
|||
submit: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default Footer |
@ -1,17 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.footer { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
padding-bottom: 30px; |
|||
|
|||
div { |
|||
margin: 0 20px; |
|||
|
|||
div { |
|||
padding: 18px 60px 15px 60px; |
|||
color: $black; |
|||
} |
|||
} |
|||
} |
@ -1,37 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './StepFour.scss' |
|||
|
|||
const StepFour = ({ node_key, local_amt, push_amt }) => ( |
|||
<div className={styles.container}> |
|||
<div className={styles.nodekey}> |
|||
<h4>Peer</h4> |
|||
<h2>{node_key}</h2> |
|||
</div> |
|||
|
|||
<div className={styles.amounts}> |
|||
<div className={styles.localamt}> |
|||
<h4>Local Amount</h4> |
|||
<h3>{local_amt}</h3> |
|||
</div> |
|||
<div className={styles.pushamt}> |
|||
<h4>Push Amount</h4> |
|||
<h3>{push_amt}</h3> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
) |
|||
|
|||
StepFour.propTypes = { |
|||
node_key: PropTypes.string.isRequired, |
|||
local_amt: PropTypes.oneOfType([ |
|||
PropTypes.number, |
|||
PropTypes.string |
|||
]), |
|||
push_amt: PropTypes.oneOfType([ |
|||
PropTypes.number, |
|||
PropTypes.string |
|||
]) |
|||
} |
|||
|
|||
export default StepFour |
@ -1,36 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
padding: 50px; |
|||
|
|||
h4 { |
|||
text-transform: uppercase; |
|||
font-size: 14px; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
h3 { |
|||
text-align: center; |
|||
color: $main; |
|||
font-size: 50px; |
|||
} |
|||
} |
|||
|
|||
.nodekey { |
|||
margin-bottom: 50px; |
|||
padding: 20px; |
|||
border-bottom: 1px solid $main; |
|||
|
|||
h2 { |
|||
font-size: 12px; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.amounts { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-around; |
|||
margin-bottom: 50px; |
|||
padding: 20px; |
|||
} |
@ -1,74 +0,0 @@ |
|||
import React, { Component } from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { MdSearch } from 'react-icons/lib/md' |
|||
import styles from './StepOne.scss' |
|||
|
|||
class StepOne extends Component { |
|||
constructor(props) { |
|||
super(props) |
|||
this.state = { |
|||
peers: props.peers, |
|||
searchQuery: '' |
|||
} |
|||
|
|||
this.onSearchQuery = this.onSearchQuery.bind(this) |
|||
this.peerClicked = this.peerClicked.bind(this) |
|||
} |
|||
|
|||
onSearchQuery(searchQuery) { |
|||
const peers = this.props.peers.filter(peer => peer.pub_key.includes(searchQuery)) |
|||
|
|||
this.setState({ peers, searchQuery }) |
|||
} |
|||
|
|||
peerClicked(peer) { |
|||
const { setNodeKey, changeStep } = this.props |
|||
|
|||
setNodeKey(peer.pub_key) |
|||
changeStep(2) |
|||
} |
|||
|
|||
render() { |
|||
const { peers, searchQuery } = this.state |
|||
|
|||
return ( |
|||
<div> |
|||
<div className={styles.search}> |
|||
<label className={`${styles.label} ${styles.input}`} htmlFor='peersSearch'> |
|||
<MdSearch /> |
|||
</label> |
|||
<input |
|||
value={searchQuery} |
|||
onChange={event => this.onSearchQuery(event.target.value)} |
|||
className={`${styles.text} ${styles.input}`} |
|||
placeholder='Search your peers by their public key' |
|||
type='text' |
|||
id='peersSearch' |
|||
/> |
|||
</div> |
|||
|
|||
<ul className={styles.peers}> |
|||
{peers.length > 0 && |
|||
peers.map(peer => ( |
|||
<li |
|||
key={peer.peer_id} |
|||
className={styles.peer} |
|||
onClick={() => this.peerClicked(peer)} |
|||
> |
|||
<h4>{peer.address}</h4> |
|||
<h1>{peer.pub_key}</h1> |
|||
</li> |
|||
))} |
|||
</ul> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
StepOne.propTypes = { |
|||
peers: PropTypes.array.isRequired, |
|||
setNodeKey: PropTypes.func.isRequired, |
|||
changeStep: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default StepOne |
@ -1,74 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.peers { |
|||
h2 { |
|||
text-transform: uppercase; |
|||
font-weight: 200; |
|||
padding: 10px 0; |
|||
border-bottom: 1px solid $grey; |
|||
color: $darkestgrey; |
|||
} |
|||
} |
|||
|
|||
.search { |
|||
height: 50px; |
|||
padding: 2px; |
|||
border-bottom: 1px solid $darkgrey; |
|||
|
|||
.input { |
|||
display: inline-block; |
|||
vertical-align: top; |
|||
height: 100%; |
|||
} |
|||
|
|||
.label { |
|||
width: 5%; |
|||
line-height: 50px; |
|||
font-size: 16px; |
|||
text-align: center; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.text { |
|||
width: 95%; |
|||
outline: 0; |
|||
padding: 0; |
|||
border: 0; |
|||
border-radius: 0; |
|||
height: 50px; |
|||
font-size: 16px; |
|||
} |
|||
} |
|||
|
|||
.peer { |
|||
position: relative; |
|||
background: $white; |
|||
padding: 10px; |
|||
border-top: 1px solid $grey; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
|
|||
&:hover { |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
&:first-child { |
|||
border: none; |
|||
} |
|||
|
|||
h4, h1 { |
|||
margin: 10px 0; |
|||
} |
|||
|
|||
h4 { |
|||
font-size: 12px; |
|||
font-weight: bold; |
|||
color: $black; |
|||
} |
|||
|
|||
h1 { |
|||
font-size: 14px; |
|||
font-weight: 200; |
|||
color: $main; |
|||
} |
|||
} |
@ -1,50 +0,0 @@ |
|||
import React, { Component } from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import CurrencyIcon from 'components/CurrencyIcon' |
|||
import styles from './StepThree.scss' |
|||
|
|||
class StepThree extends Component { |
|||
render() { |
|||
const { push_amt, setPushAmount } = this.props |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
<div className={styles.explainer}> |
|||
<h2>Push Amount</h2> |
|||
<p> |
|||
The push amount is the amount of bitcoin (if any at all) you'd like |
|||
to "push" to the other side of the channel when it opens. |
|||
This amount will be set on the remote side of the channel as part of the initial commitment state. |
|||
</p> |
|||
</div> |
|||
|
|||
<form> |
|||
<label htmlFor='amount'> |
|||
<CurrencyIcon currency='btc' crypto='btc' /> |
|||
</label> |
|||
<input |
|||
type='number' |
|||
min='0' |
|||
max='0.16' |
|||
ref={(input) => { this.input = input }} |
|||
size='' |
|||
value={push_amt} |
|||
onChange={event => setPushAmount(event.target.value)} |
|||
id='amount' |
|||
style={{ width: isNaN((push_amt.length + 1) * 55) ? 140 : (push_amt.length + 1) * 55 }} |
|||
/> |
|||
</form> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
StepThree.propTypes = { |
|||
push_amt: PropTypes.oneOfType([ |
|||
PropTypes.number, |
|||
PropTypes.string |
|||
]).isRequired, |
|||
setPushAmount: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default StepThree |
@ -1,58 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
margin-bottom: 50px; |
|||
padding: 20px; |
|||
|
|||
.explainer { |
|||
margin: 0px 0 50px 0; |
|||
padding-bottom: 20px; |
|||
border-bottom: 1px solid $lightgrey; |
|||
|
|||
h2 { |
|||
margin: 0 0 20px 0; |
|||
font-size: 28px; |
|||
} |
|||
|
|||
p { |
|||
line-height: 1.5; |
|||
font-size: 16px; |
|||
} |
|||
} |
|||
|
|||
form { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
label { |
|||
height: 200px; |
|||
color: $main; |
|||
|
|||
svg { |
|||
width: 65px; |
|||
height: 65px; |
|||
} |
|||
|
|||
svg[data-icon='ltc'] { |
|||
margin-right: 10px; |
|||
|
|||
g { |
|||
transform: scale(1.75) translate(-5px, -5px); |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type=number] { |
|||
color: $main; |
|||
width: 30px; |
|||
height: 200px; |
|||
font-size: 100px; |
|||
font-weight: 200; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
} |
|||
} |
@ -1,49 +0,0 @@ |
|||
import React, { Component } from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import CurrencyIcon from 'components/CurrencyIcon' |
|||
import styles from './StepTwo.scss' |
|||
|
|||
class StepTwo extends Component { |
|||
render() { |
|||
const { local_amt, setLocalAmount } = this.props |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
<div className={styles.explainer}> |
|||
<h2>Local Amount</h2> |
|||
<p> |
|||
Local amount is the amount of bitcoin that you would like to commit to the channel. |
|||
This is the amount that will be sent in an on-chain transaction to open your Lightning channel. |
|||
</p> |
|||
</div> |
|||
|
|||
<form> |
|||
<label htmlFor='amount'> |
|||
<CurrencyIcon currency='btc' crypto='btc' /> |
|||
</label> |
|||
<input |
|||
type='number' |
|||
min='0' |
|||
max='0.16' |
|||
ref={(input) => { this.input = input }} |
|||
size='' |
|||
value={local_amt} |
|||
onChange={event => setLocalAmount(event.target.value)} |
|||
id='amount' |
|||
style={{ width: isNaN((local_amt.length + 1) * 55) ? 140 : (local_amt.length + 1) * 55 }} |
|||
/> |
|||
</form> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
StepTwo.propTypes = { |
|||
local_amt: PropTypes.oneOfType([ |
|||
PropTypes.string, |
|||
PropTypes.number |
|||
]).isRequired, |
|||
setLocalAmount: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default StepTwo |
@ -1,58 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
margin-bottom: 50px; |
|||
padding: 20px; |
|||
|
|||
.explainer { |
|||
margin: 0px 0 50px 0; |
|||
padding-bottom: 20px; |
|||
border-bottom: 1px solid $lightgrey; |
|||
|
|||
h2 { |
|||
margin: 0 0 20px 0; |
|||
font-size: 28px; |
|||
} |
|||
|
|||
p { |
|||
line-height: 1.5; |
|||
font-size: 16px; |
|||
} |
|||
} |
|||
|
|||
form { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
label { |
|||
height: 200px; |
|||
color: $main; |
|||
|
|||
svg { |
|||
width: 65px; |
|||
height: 65px; |
|||
} |
|||
|
|||
svg[data-icon='ltc'] { |
|||
margin-right: 10px; |
|||
|
|||
g { |
|||
transform: scale(1.75) translate(-5px, -5px); |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type=number] { |
|||
color: $main; |
|||
width: 30px; |
|||
height: 200px; |
|||
font-size: 100px; |
|||
font-weight: 200; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
} |
|||
} |
@ -1,3 +0,0 @@ |
|||
import ChannelForm from './ChannelForm' |
|||
|
|||
export default ChannelForm |
@ -1,95 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { FaCircle } from 'react-icons/lib/fa' |
|||
import { btc } from 'utils' |
|||
import styles from './Channel.scss' |
|||
|
|||
const Channel = ({ |
|||
ticker, channel, closeChannel, currentTicker |
|||
}) => ( |
|||
<li className={styles.channel}> |
|||
<header className={styles.header}> |
|||
<div> |
|||
<span className={styles.status}>Open</span> |
|||
{ |
|||
channel.active ? |
|||
<span className={styles.active}> |
|||
<FaCircle /> |
|||
<i>Active</i> |
|||
</span> |
|||
: |
|||
<span className={styles.notactive}> |
|||
<FaCircle /> |
|||
<i>Not Active</i> |
|||
</span> |
|||
} |
|||
</div> |
|||
<div> |
|||
<p |
|||
className={styles.close} |
|||
onClick={() => closeChannel({ channel_point: channel.channel_point })} |
|||
> |
|||
Close channel |
|||
</p> |
|||
</div> |
|||
</header> |
|||
<div className={styles.content}> |
|||
<div className={styles.left}> |
|||
<section className={styles.remotePubkey}> |
|||
<span>Remote Pubkey</span> |
|||
<h4>{channel.remote_pubkey}</h4> |
|||
</section> |
|||
<section className={styles.channelPoint}> |
|||
<span>Channel Point</span> |
|||
<h4>{channel.channel_point}</h4> |
|||
</section> |
|||
</div> |
|||
<div className={styles.right}> |
|||
<section className={styles.capacity}> |
|||
<span>Capacity</span> |
|||
<h2> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.capacity) |
|||
: |
|||
btc.satoshisToUsd(channel.capacity, currentTicker.price_usd) |
|||
} |
|||
</h2> |
|||
</section> |
|||
<div className={styles.balances}> |
|||
<section> |
|||
<span>Local</span> |
|||
<h4> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.local_balance) |
|||
: |
|||
btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd) |
|||
} |
|||
</h4> |
|||
</section> |
|||
<section> |
|||
<span>Remote</span> |
|||
<h4> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.remote_balance) |
|||
: |
|||
btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd) |
|||
} |
|||
</h4> |
|||
</section> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
) |
|||
|
|||
Channel.propTypes = { |
|||
ticker: PropTypes.object.isRequired, |
|||
channel: PropTypes.object.isRequired, |
|||
closeChannel: PropTypes.func.isRequired, |
|||
currentTicker: PropTypes.object.isRequired |
|||
} |
|||
|
|||
export default Channel |
@ -1,125 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.channel { |
|||
position: relative; |
|||
background: $white; |
|||
margin: 5px 0; |
|||
padding: 10px; |
|||
border-top: 1px solid $white; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); |
|||
|
|||
&:hover { |
|||
opacity: 0.75; |
|||
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); |
|||
} |
|||
|
|||
&:first-child { |
|||
border: none; |
|||
} |
|||
|
|||
.header { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
|
|||
.status, .active, .notactive { |
|||
padding: 10px; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
font-size: 10px; |
|||
} |
|||
|
|||
.status { |
|||
color: $main; |
|||
} |
|||
|
|||
.active i, .notactive i { |
|||
margin-left: 5px; |
|||
} |
|||
|
|||
.active { |
|||
color: $green; |
|||
} |
|||
|
|||
.notactive { |
|||
color: $red; |
|||
} |
|||
|
|||
.close { |
|||
padding: 10px; |
|||
font-size: 10px; |
|||
text-transform: uppercase; |
|||
color: $red; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
color: lighten($red, 10%); |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.content { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
|
|||
.left, .right { |
|||
padding: 0 10px; |
|||
margin-bottom: 5; |
|||
|
|||
section { |
|||
margin-bottom: 20px; |
|||
|
|||
span { |
|||
text-transform: uppercase; |
|||
letter-spacing: 1.6px; |
|||
color: $black; |
|||
font-size: 10px; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
h2 { |
|||
font-size: 30px; |
|||
padding: 5px 0; |
|||
color: $main; |
|||
} |
|||
|
|||
h4 { |
|||
margin-top: 5px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.left { |
|||
flex: 7; |
|||
} |
|||
|
|||
.right { |
|||
flex: 3; |
|||
|
|||
.capacity { |
|||
text-align: center; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.balances { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
section { |
|||
flex: 5; |
|||
text-align: center; |
|||
|
|||
h4 { |
|||
color: $main; |
|||
font-size: 16px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,128 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import ReactModal from 'react-modal' |
|||
import { FaUser } from 'react-icons/lib/fa' |
|||
import CurrencyIcon from 'components/CurrencyIcon' |
|||
import { usd, btc } from 'utils' |
|||
import styles from './ChannelForm.scss' |
|||
|
|||
const ChannelForm = ({ |
|||
form, setForm, ticker, peers, openChannel, currentTicker |
|||
}) => { |
|||
const submitClicked = () => { |
|||
const { node_key, local_amt, push_amt } = form |
|||
|
|||
const localamt = ticker.currency === 'usd' ? btc.btcToSatoshis(usd.usdToBtc(local_amt, currentTicker.price_usd)) : btc.btcToSatoshis(local_amt) |
|||
const pushamt = ticker.currency === 'usd' ? btc.btcToSatoshis(usd.usdToBtc(push_amt, currentTicker.price_usd)) : btc.btcToSatoshis(push_amt) |
|||
|
|||
openChannel({ pubkey: node_key, localamt, pushamt }) |
|||
// setForm({ isOpen: false })
|
|||
} |
|||
|
|||
const customStyles = { |
|||
overlay: { |
|||
cursor: 'pointer', |
|||
overflowY: 'auto' |
|||
}, |
|||
content: { |
|||
top: 'auto', |
|||
left: '20%', |
|||
right: '0', |
|||
bottom: 'auto', |
|||
width: '40%', |
|||
margin: '50px auto', |
|||
padding: '40px' |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<div> |
|||
<ReactModal |
|||
isOpen={form.isOpen} |
|||
contentLabel='No Overlay Click Modal' |
|||
ariaHideApp |
|||
shouldCloseOnOverlayClick |
|||
onRequestClose={() => setForm({ isOpen: false })} |
|||
parentSelector={() => document.body} |
|||
style={customStyles} |
|||
> |
|||
<div className={styles.form}> |
|||
<h1 className={styles.title}>Open a new channel</h1> |
|||
|
|||
<section className={styles.pubkey}> |
|||
<label htmlFor='nodekey'><FaUser /></label> |
|||
<input |
|||
type='text' |
|||
size='' |
|||
placeholder='Peer public key' |
|||
value={form.node_key} |
|||
onChange={event => setForm({ node_key: event.target.value })} |
|||
id='nodekey' |
|||
/> |
|||
</section> |
|||
<section className={styles.local}> |
|||
<label htmlFor='localamount'> |
|||
<CurrencyIcon currency={ticker.currency} crypto={ticker.crypto} /> |
|||
</label> |
|||
<input |
|||
type='text' |
|||
size='' |
|||
placeholder='Local amount' |
|||
value={form.local_amt} |
|||
onChange={event => setForm({ local_amt: event.target.value })} |
|||
id='localamount' |
|||
/> |
|||
</section> |
|||
<section className={styles.push}> |
|||
<label htmlFor='pushamount'> |
|||
<CurrencyIcon currency={ticker.currency} crypto={ticker.crypto} /> |
|||
</label> |
|||
<input |
|||
type='text' |
|||
size='' |
|||
placeholder='Push amount' |
|||
value={form.push_amt} |
|||
onChange={event => setForm({ push_amt: event.target.value })} |
|||
id='pushamount' |
|||
/> |
|||
</section> |
|||
|
|||
<ul className={styles.peers}> |
|||
<h2>Connected Peers</h2> |
|||
{ |
|||
peers.length ? |
|||
peers.map(peer => |
|||
( |
|||
<li |
|||
key={peer.peer_id} |
|||
className={styles.peer} |
|||
onClick={() => setForm({ node_key: peer.pub_key })} |
|||
> |
|||
<h4>{peer.address}</h4> |
|||
<h1>{peer.pub_key}</h1> |
|||
</li> |
|||
)) |
|||
: |
|||
null |
|||
} |
|||
</ul> |
|||
|
|||
<div className={styles.buttonGroup}> |
|||
<div className={styles.button} onClick={submitClicked}>Submit</div> |
|||
</div> |
|||
</div> |
|||
</ReactModal> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
ChannelForm.propTypes = { |
|||
form: PropTypes.object.isRequired, |
|||
setForm: PropTypes.func.isRequired, |
|||
ticker: PropTypes.object.isRequired, |
|||
peers: PropTypes.array.isRequired, |
|||
openChannel: PropTypes.func.isRequired, |
|||
currentTicker: PropTypes.object.isRequired |
|||
} |
|||
|
|||
export default ChannelForm |
@ -1,123 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.title { |
|||
text-align: center; |
|||
font-size: 24px; |
|||
color: $black; |
|||
margin-bottom: 50px; |
|||
} |
|||
|
|||
.pubkey, .local, .push { |
|||
display: flex; |
|||
justify-content: center; |
|||
font-size: 18px; |
|||
height: auto; |
|||
min-height: 55px; |
|||
margin-bottom: 20px; |
|||
border: 1px solid $traditionalgrey; |
|||
border-radius: 6px; |
|||
position: relative; |
|||
padding: 0 20px; |
|||
|
|||
label, input[type=text] { |
|||
font-size: inherit; |
|||
} |
|||
|
|||
label { |
|||
padding-top: 19px; |
|||
padding-bottom: 12px; |
|||
color: $traditionalgrey; |
|||
|
|||
svg[data-icon='ltc'] { |
|||
width: 18px; |
|||
height: 16px; |
|||
|
|||
g { |
|||
transform: scale(1.75) translate(-5px, -5px); |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type=text] { |
|||
width: 100%; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
height: 55px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
|
|||
.peers { |
|||
margin-bottom: 50px; |
|||
|
|||
h2 { |
|||
text-transform: uppercase; |
|||
font-weight: 200; |
|||
padding: 10px 0; |
|||
border-bottom: 1px solid $grey; |
|||
color: $darkestgrey; |
|||
} |
|||
} |
|||
|
|||
.peer { |
|||
position: relative; |
|||
background: $white; |
|||
padding: 10px; |
|||
border-top: 1px solid $grey; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
|
|||
&:hover { |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
&:first-child { |
|||
border: none; |
|||
} |
|||
|
|||
h4, h1 { |
|||
margin: 10px 0; |
|||
} |
|||
|
|||
h4 { |
|||
font-size: 12px; |
|||
font-weight: bold; |
|||
color: $black; |
|||
} |
|||
|
|||
h1 { |
|||
font-size: 14px; |
|||
font-weight: 200; |
|||
color: $main; |
|||
} |
|||
} |
|||
|
|||
.buttonGroup { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
|
|||
.button { |
|||
cursor: pointer; |
|||
height: 55px; |
|||
min-height: 55px; |
|||
text-transform: none; |
|||
font-size: 18px; |
|||
transition: opacity .2s ease-out; |
|||
background: $main; |
|||
color: $white; |
|||
border: none; |
|||
font-weight: 500; |
|||
padding: 0; |
|||
width: 100%; |
|||
text-align: center; |
|||
line-height: 55px; |
|||
|
|||
&:first-child { |
|||
border-right: 1px solid lighten($main, 20%); |
|||
} |
|||
} |
|||
} |
@ -1,103 +0,0 @@ |
|||
import { shell } from 'electron' |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import ReactModal from 'react-modal' |
|||
import styles from './ChannelModal.scss' |
|||
|
|||
const ChannelModal = ({ |
|||
isOpen, resetChannel, channel, explorerLinkBase, closeChannel |
|||
}) => { |
|||
const customStyles = { |
|||
overlay: { |
|||
cursor: 'pointer', |
|||
overflowY: 'auto' |
|||
}, |
|||
content: { |
|||
top: 'auto', |
|||
left: '20%', |
|||
right: '0', |
|||
bottom: 'auto', |
|||
width: '40%', |
|||
margin: '50px auto', |
|||
padding: '40px' |
|||
} |
|||
} |
|||
|
|||
const closeChannelClicked = () => { |
|||
closeChannel({ channel_point: channel.channel_point }) |
|||
resetChannel(null) |
|||
} |
|||
|
|||
return ( |
|||
<ReactModal |
|||
isOpen={isOpen} |
|||
contentLabel='No Overlay Click Modal' |
|||
ariaHideApp |
|||
shouldCloseOnOverlayClick |
|||
onRequestClose={() => resetChannel(null)} |
|||
parentSelector={() => document.body} |
|||
style={customStyles} |
|||
> |
|||
{ |
|||
channel ? |
|||
<div className={styles.channel}> |
|||
<header className={styles.header}> |
|||
<h1 data-hint='Remote public key' className='hint--top-left'>{channel.remote_pubkey}</h1> |
|||
<h2 |
|||
data-hint='Channel point' |
|||
className='hint--top-left' |
|||
onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${channel.channel_point.split(':')[0]}`)} |
|||
> |
|||
{channel.channel_point} |
|||
</h2> |
|||
</header> |
|||
|
|||
<div className={styles.balances}> |
|||
<section className={styles.capacity}> |
|||
<h3>{channel.capacity}</h3> |
|||
<span>Capacity</span> |
|||
</section> |
|||
<div className={styles.balance}> |
|||
<section className={styles.local}> |
|||
<h4>{channel.local_balance}</h4> |
|||
<span>Local</span> |
|||
</section> |
|||
<section className={styles.remote}> |
|||
<h4>{channel.remote_balance}</h4> |
|||
<span>Remote</span> |
|||
</section> |
|||
</div> |
|||
</div> |
|||
<div className={styles.details}> |
|||
<dl> |
|||
<dt>Sent</dt> |
|||
<dd>{channel.total_satoshis_sent}</dd> |
|||
<dt>Received</dt> |
|||
<dd>{channel.total_satoshis_received}</dd> |
|||
<dt>Updates</dt> |
|||
<dd>{channel.num_updates}</dd> |
|||
</dl> |
|||
</div> |
|||
<div className={styles.close} onClick={closeChannelClicked}> |
|||
<div>Close channel</div> |
|||
</div> |
|||
<footer className={styles.active}> |
|||
<p>{channel.active ? 'Active' : 'Not active'}</p> |
|||
</footer> |
|||
</div> |
|||
: |
|||
null |
|||
} |
|||
</ReactModal> |
|||
) |
|||
} |
|||
|
|||
ChannelModal.propTypes = { |
|||
isOpen: PropTypes.bool.isRequired, |
|||
resetChannel: PropTypes.func.isRequired, |
|||
channel: PropTypes.object, |
|||
explorerLinkBase: PropTypes.string.isRequired, |
|||
closeChannel: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default ChannelModal |
@ -1,124 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.modalChannel { |
|||
padding: 40px; |
|||
} |
|||
|
|||
.header { |
|||
margin-bottom: 50px; |
|||
|
|||
h1 { |
|||
color: $black; |
|||
text-align: center; |
|||
margin-bottom: 5px; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
h2 { |
|||
color: $darkestgrey; |
|||
font-size: 14px; |
|||
text-align: center; |
|||
|
|||
&:hover { |
|||
color: $main; |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.balances { |
|||
.capacity { |
|||
text-align: center; |
|||
align-items: center; |
|||
|
|||
h3 { |
|||
color: $main; |
|||
font-size: 40px; |
|||
} |
|||
|
|||
span { |
|||
color: $black; |
|||
font-size: 16px; |
|||
} |
|||
} |
|||
|
|||
.balance { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
|
|||
.local, .remote { |
|||
flex: 5; |
|||
padding: 10px 30px; |
|||
text-align: center; |
|||
|
|||
h4 { |
|||
font-size: 20px; |
|||
color: $main; |
|||
} |
|||
|
|||
span { |
|||
color: $black; |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.details { |
|||
width: 75%; |
|||
margin: 20px auto; |
|||
|
|||
dt { |
|||
text-align: left; |
|||
float: left; |
|||
clear: left; |
|||
font-weight: 500; |
|||
padding: 20px 35px 19px 0; |
|||
color: $black; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
dd { |
|||
text-align: right; |
|||
font-weight: 400; |
|||
padding: 19px 0; |
|||
margin-left: 0; |
|||
border-top: 1px solid $darkgrey; |
|||
} |
|||
} |
|||
|
|||
.close { |
|||
text-align: center; |
|||
|
|||
div { |
|||
width: 35%; |
|||
margin: 0 auto; |
|||
cursor: pointer; |
|||
height: 55px; |
|||
min-height: 55px; |
|||
text-transform: none; |
|||
font-size: 18px; |
|||
transition: opacity .2s ease-out; |
|||
background: $red; |
|||
color: $white; |
|||
border: none; |
|||
font-weight: 500; |
|||
padding: 0; |
|||
text-align: center; |
|||
line-height: 55px; |
|||
transition: all 0.25s; |
|||
border-radius: 5px; |
|||
|
|||
&:hover { |
|||
background: darken($red, 10%); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.active { |
|||
color: $darkestgrey; |
|||
text-align: center; |
|||
margin-top: 50px; |
|||
text-transform: uppercase; |
|||
} |
@ -1,140 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { TiPlus } from 'react-icons/lib/ti' |
|||
import { FaRepeat } from 'react-icons/lib/fa' |
|||
import ChannelModal from './ChannelModal' |
|||
import ChannelForm from './ChannelForm' |
|||
import Channel from './Channel' |
|||
import OpenPendingChannel from './OpenPendingChannel' |
|||
import ClosedPendingChannel from './ClosedPendingChannel' |
|||
import styles from './Channels.scss' |
|||
|
|||
const Channels = ({ |
|||
fetchChannels, |
|||
ticker, |
|||
peers, |
|||
channelsLoading, |
|||
modalChannel, |
|||
setChannel, |
|||
channelModalOpen, |
|||
channelForm, |
|||
setChannelForm, |
|||
allChannels, |
|||
openChannel, |
|||
closeChannel, |
|||
currentTicker, |
|||
explorerLinkBase |
|||
}) => { |
|||
const refreshClicked = (event) => { |
|||
// store event in icon so we dont get an error when react clears it
|
|||
const icon = event.currentTarget |
|||
|
|||
// fetch channels
|
|||
fetchChannels() |
|||
|
|||
// clear animation after the second so we can reuse it
|
|||
setTimeout(() => { icon.style.animation = '' }, 1000) |
|||
|
|||
// spin icon for 1 sec
|
|||
icon.style.animation = 'spin 1000ms linear 1' |
|||
} |
|||
|
|||
return ( |
|||
<div className={styles.channels}> |
|||
<ChannelModal |
|||
isOpen={channelModalOpen} |
|||
resetChannel={setChannel} |
|||
channel={modalChannel} |
|||
explorerLinkBase={explorerLinkBase} |
|||
closeChannel={closeChannel} |
|||
/> |
|||
<ChannelForm |
|||
form={channelForm} |
|||
setForm={setChannelForm} |
|||
ticker={ticker} |
|||
peers={peers} |
|||
openChannel={openChannel} |
|||
currentTicker={currentTicker} |
|||
/> |
|||
<div className={styles.header}> |
|||
<h3>Channels</h3> |
|||
<span |
|||
className={`${styles.refresh} hint--top`} |
|||
data-hint='Refresh your channels list' |
|||
|
|||
> |
|||
<FaRepeat |
|||
style={{ verticalAlign: 'baseline' }} |
|||
onClick={refreshClicked} |
|||
/> |
|||
</span> |
|||
<div |
|||
className={`${styles.openChannel} hint--top`} |
|||
data-hint='Open a channel' |
|||
onClick={() => setChannelForm({ isOpen: true })} |
|||
> |
|||
<TiPlus /> |
|||
</div> |
|||
</div> |
|||
<ul> |
|||
{ |
|||
!channelsLoading ? |
|||
allChannels.map((channel, index) => { |
|||
if (Object.prototype.hasOwnProperty.call(channel, 'blocks_till_open')) { |
|||
return ( |
|||
<OpenPendingChannel |
|||
key={index} |
|||
channel={channel} |
|||
ticker={ticker} |
|||
currentTicker={currentTicker} |
|||
explorerLinkBase={explorerLinkBase} |
|||
/> |
|||
) |
|||
} else if (Object.prototype.hasOwnProperty.call(channel, 'closing_txid')) { |
|||
return ( |
|||
<ClosedPendingChannel |
|||
key={index} |
|||
channel={channel} |
|||
ticker={ticker} |
|||
currentTicker={currentTicker} |
|||
explorerLinkBase={explorerLinkBase} |
|||
/> |
|||
) |
|||
} |
|||
return ( |
|||
<Channel |
|||
key={index} |
|||
ticker={ticker} |
|||
channel={channel} |
|||
setChannel={setChannel} |
|||
currentTicker={currentTicker} |
|||
closeChannel={closeChannel} |
|||
/> |
|||
) |
|||
}) |
|||
: |
|||
'Loading...' |
|||
} |
|||
</ul> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
Channels.propTypes = { |
|||
fetchChannels: PropTypes.func.isRequired, |
|||
ticker: PropTypes.object.isRequired, |
|||
peers: PropTypes.array.isRequired, |
|||
channelsLoading: PropTypes.bool.isRequired, |
|||
modalChannel: PropTypes.object, |
|||
setChannel: PropTypes.func.isRequired, |
|||
channelModalOpen: PropTypes.bool.isRequired, |
|||
channelForm: PropTypes.object.isRequired, |
|||
setChannelForm: PropTypes.func.isRequired, |
|||
allChannels: PropTypes.array.isRequired, |
|||
openChannel: PropTypes.func.isRequired, |
|||
closeChannel: PropTypes.func.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
explorerLinkBase: PropTypes.string.isRequired |
|||
} |
|||
|
|||
export default Channels |
@ -1,69 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
@keyframes spin { |
|||
from { |
|||
transform: rotate(0deg) |
|||
} |
|||
|
|||
to { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
.channels { |
|||
width: 75%; |
|||
margin: 50px auto; |
|||
|
|||
.header { |
|||
margin-bottom: 10px; |
|||
|
|||
h3, .openChannel { |
|||
display: inline-block; |
|||
} |
|||
|
|||
h3 { |
|||
text-align: left; |
|||
} |
|||
|
|||
.refresh { |
|||
cursor: pointer; |
|||
margin-left: 5px; |
|||
font-size: 12px; |
|||
vertical-align: top; |
|||
color: $darkestgrey; |
|||
line-height: 14px; |
|||
transition: color 0.25s; |
|||
|
|||
&:hover { |
|||
color: $main; |
|||
} |
|||
} |
|||
|
|||
.openChannel { |
|||
float: right; |
|||
cursor: pointer; |
|||
|
|||
svg { |
|||
padding: 3px; |
|||
border-radius: 50%; |
|||
border: 1px solid $main; |
|||
color: $main; |
|||
transition: all 0.25s; |
|||
|
|||
&:hover { |
|||
border-color: darken($main, 10%); |
|||
color: darken($main, 10%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
h3 { |
|||
text-transform: uppercase; |
|||
color: $darkestgrey; |
|||
letter-spacing: 1.6px; |
|||
font-size: 14px; |
|||
font-weight: 400; |
|||
margin-bottom: 10px; |
|||
} |
|||
} |
@ -1,69 +0,0 @@ |
|||
import { shell } from 'electron' |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { btc } from 'utils' |
|||
import styles from './ClosedPendingChannel.scss' |
|||
|
|||
const ClosedPendingChannel = ({ |
|||
ticker, channel: { channel, closing_txid }, currentTicker, explorerLinkBase |
|||
}) => ( |
|||
<li className={styles.channel} onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${closing_txid}`)}> |
|||
<h1 className={styles.closing}>Closing Channel...</h1> |
|||
<div className={styles.left}> |
|||
<section className={styles.remotePubkey}> |
|||
<span>Remote Pubkey</span> |
|||
<h4>{channel.remote_node_pub}</h4> |
|||
</section> |
|||
<section className={styles.channelPoint}> |
|||
<span>Channel Point</span> |
|||
<h4>{channel.channel_point}</h4> |
|||
</section> |
|||
</div> |
|||
<div className={styles.right}> |
|||
<section className={styles.capacity}> |
|||
<span>Capacity</span> |
|||
<h2> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.capacity) |
|||
: |
|||
btc.satoshisToUsd(channel.capacity, currentTicker.price_usd) |
|||
} |
|||
</h2> |
|||
</section> |
|||
<div className={styles.balances}> |
|||
<section> |
|||
<h4> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.local_balance) |
|||
: |
|||
btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd) |
|||
} |
|||
</h4> |
|||
<span>Local</span> |
|||
</section> |
|||
<section> |
|||
<h4> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.remote_balance) |
|||
: |
|||
btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd) |
|||
} |
|||
</h4> |
|||
<span>Remote</span> |
|||
</section> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
) |
|||
|
|||
ClosedPendingChannel.propTypes = { |
|||
ticker: PropTypes.object.isRequired, |
|||
channel: PropTypes.object.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
explorerLinkBase: PropTypes.string.isRequired |
|||
} |
|||
|
|||
export default ClosedPendingChannel |
@ -1,95 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.channel { |
|||
position: relative; |
|||
background: $white; |
|||
padding: 10px; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
border-top: 1px solid $grey; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
opacity: 0.5; |
|||
|
|||
&:hover { |
|||
opacity: 0.35; |
|||
} |
|||
|
|||
&:first-child { |
|||
border: none; |
|||
} |
|||
|
|||
.closing { |
|||
color: $red; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 10px; |
|||
padding: 10px; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
font-size: 10px; |
|||
} |
|||
|
|||
.left, .right { |
|||
padding: 0 10px; |
|||
margin-bottom: 5; |
|||
margin-top: 25px; |
|||
|
|||
section { |
|||
margin-bottom: 20px; |
|||
|
|||
span { |
|||
text-transform: uppercase; |
|||
letter-spacing: 1.6px; |
|||
color: $black; |
|||
font-size: 10px; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
h2 { |
|||
font-size: 30px; |
|||
padding: 5px 0; |
|||
color: $main; |
|||
} |
|||
|
|||
h4 { |
|||
margin-top: 5px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.left { |
|||
flex: 7; |
|||
border-right: 1px solid $grey; |
|||
} |
|||
|
|||
.right { |
|||
flex: 3; |
|||
|
|||
.capacity { |
|||
text-align: center; |
|||
border-bottom: 1px solid $grey; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.balances { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
section { |
|||
flex: 5; |
|||
text-align: center; |
|||
|
|||
h4 { |
|||
color: $main; |
|||
font-size: 16px; |
|||
} |
|||
|
|||
&:first-child { |
|||
border-right: 1px solid $grey; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,72 +0,0 @@ |
|||
import { shell } from 'electron' |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { btc } from 'utils' |
|||
import styles from './OpenPendingChannel.scss' |
|||
|
|||
const OpenPendingChannel = ({ |
|||
ticker, channel, currentTicker, explorerLinkBase |
|||
}) => ( |
|||
<li className={styles.channel} onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${channel.channel.channel_point.split(':')[0]}`)}> |
|||
<div className={styles.pending}> |
|||
<h1>Opening Channel...</h1> |
|||
<span>Blocks till open: {channel.blocks_till_open}</span> |
|||
</div> |
|||
<div className={styles.left}> |
|||
<section className={styles.remotePubkey}> |
|||
<span>Remote Pubkey</span> |
|||
<h4>{channel.channel.remote_node_pub}</h4> |
|||
</section> |
|||
<section className={styles.channelPoint}> |
|||
<span>Channel Point</span> |
|||
<h4>{channel.channel.channel_point}</h4> |
|||
</section> |
|||
</div> |
|||
<div className={styles.right}> |
|||
<section className={styles.capacity}> |
|||
<span>Capacity</span> |
|||
<h2> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.channel.capacity) |
|||
: |
|||
btc.satoshisToUsd(channel.channel.capacity, currentTicker.price_usd) |
|||
} |
|||
</h2> |
|||
</section> |
|||
<div className={styles.balances}> |
|||
<section> |
|||
<h4> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.channel.local_balance) |
|||
: |
|||
btc.satoshisToUsd(channel.channel.local_balance, currentTicker.price_usd) |
|||
} |
|||
</h4> |
|||
<span>Local</span> |
|||
</section> |
|||
<section> |
|||
<h4> |
|||
{ |
|||
ticker.currency === 'btc' ? |
|||
btc.satoshisToBtc(channel.channel.remote_balance) |
|||
: |
|||
btc.satoshisToUsd(channel.channel.remote_balance, currentTicker.price_usd) |
|||
} |
|||
</h4> |
|||
<span>Remote</span> |
|||
</section> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
) |
|||
|
|||
OpenPendingChannel.propTypes = { |
|||
ticker: PropTypes.object.isRequired, |
|||
channel: PropTypes.object.isRequired, |
|||
currentTicker: PropTypes.object.isRequired, |
|||
explorerLinkBase: PropTypes.string.isRequired |
|||
} |
|||
|
|||
export default OpenPendingChannel |
@ -1,98 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.channel { |
|||
position: relative; |
|||
background: $lightgrey; |
|||
padding: 10px; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
border-top: 1px solid $grey; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
opacity: 0.5; |
|||
|
|||
.pending { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 10px; |
|||
padding: 10px; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
|
|||
h1 { |
|||
color: $main; |
|||
font-size: 10px; |
|||
} |
|||
|
|||
span { |
|||
font-size: 8px; |
|||
} |
|||
} |
|||
|
|||
&:first-child { |
|||
border: none; |
|||
} |
|||
|
|||
.left, .right { |
|||
padding: 0 10px; |
|||
margin-bottom: 5; |
|||
margin-top: 40px; |
|||
|
|||
section { |
|||
margin-bottom: 20px; |
|||
|
|||
span { |
|||
text-transform: uppercase; |
|||
letter-spacing: 1.6px; |
|||
color: $black; |
|||
font-size: 10px; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
h2 { |
|||
font-size: 30px; |
|||
padding: 5px 0; |
|||
color: $main; |
|||
} |
|||
|
|||
h4 { |
|||
margin-top: 5px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.left { |
|||
flex: 7; |
|||
border-right: 1px solid $grey; |
|||
} |
|||
|
|||
.right { |
|||
flex: 3; |
|||
|
|||
.capacity { |
|||
text-align: center; |
|||
border-bottom: 1px solid $grey; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.balances { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
section { |
|||
flex: 5; |
|||
text-align: center; |
|||
|
|||
h4 { |
|||
color: $main; |
|||
font-size: 16px; |
|||
} |
|||
|
|||
&:first-child { |
|||
border-right: 1px solid $grey; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,3 +0,0 @@ |
|||
import Channels from './Channels' |
|||
|
|||
export default Channels |
@ -1,31 +0,0 @@ |
|||
import React, { Component } from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './Donut.scss' |
|||
|
|||
const Donut = ({ value, size, strokewidth }) => { |
|||
console.log('value: ', value) |
|||
console.log('size: ', size) |
|||
console.log('strokewidth: ', strokewidth) |
|||
|
|||
const halfsize = (size * 0.5) |
|||
const radius = halfsize - (strokewidth * 0.5) |
|||
const circumference = 2 * Math.PI * radius |
|||
const strokeval = ((value * circumference) / 100) |
|||
const dashval = (`${strokeval} ${circumference}`) |
|||
|
|||
const trackstyle = { strokeWidth: 5 } |
|||
const indicatorstyle = { strokeWidth: strokewidth, strokeDasharray: dashval } |
|||
const rotateval = `rotate(-90 ${37.5},${37.5})` |
|||
|
|||
return ( |
|||
<svg width={75} height={75} className={styles.donutchart}> |
|||
<circle r={30} cx={37.5} cy={37.5} transform={rotateval} style={trackstyle} className={styles.donutchartTrack} /> |
|||
<circle r={30} cx={37.5} cy={37.5} transform={rotateval} style={indicatorstyle} className={styles.donutchartIndicator} /> |
|||
</svg> |
|||
) |
|||
} |
|||
|
|||
Donut.propTypes = { |
|||
} |
|||
|
|||
export default Donut |
@ -1,20 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.donutchartTrack{ |
|||
fill: transparent; |
|||
stroke: $lightgrey; |
|||
stroke-width: 26; |
|||
} |
|||
.donutchartIndicator { |
|||
fill: transparent; |
|||
stroke: $main; |
|||
stroke-width: 26; |
|||
stroke-dasharray: 0 10000; |
|||
transition: stroke-dasharray .3s ease; |
|||
} |
|||
|
|||
.donutchart { |
|||
margin: 0 auto; |
|||
border-radius: 50%; |
|||
display: block; |
|||
} |
@ -1,20 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './Peer.scss' |
|||
|
|||
const Peer = ({ peer, setPeer }) => ( |
|||
<li className={styles.peer} onClick={() => setPeer(peer)}> |
|||
<h4>{peer.address}</h4> |
|||
<h1>{peer.pub_key}</h1> |
|||
</li> |
|||
) |
|||
|
|||
Peer.propTypes = { |
|||
peer: PropTypes.shape({ |
|||
address: PropTypes.string.isRequired, |
|||
pub_key: PropTypes.string.isRequired |
|||
}).isRequired, |
|||
setPeer: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default Peer |
@ -1,38 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.peer { |
|||
position: relative; |
|||
margin: 5px 0; |
|||
padding: 10px; |
|||
border-top: 1px solid $white; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
list-style: none; |
|||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); |
|||
transition: 0.3s; |
|||
|
|||
&:hover { |
|||
opacity: 0.75; |
|||
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); |
|||
} |
|||
|
|||
&:first-child { |
|||
border: none; |
|||
} |
|||
|
|||
h4, h1 { |
|||
margin: 10px 0; |
|||
} |
|||
|
|||
h4 { |
|||
font-size: 14px; |
|||
font-weight: bold; |
|||
color: $black; |
|||
} |
|||
|
|||
h1 { |
|||
font-size: 18px; |
|||
font-weight: 200; |
|||
color: $main; |
|||
} |
|||
} |
@ -1,71 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import ReactModal from 'react-modal' |
|||
import { FaClose } from 'react-icons/lib/fa' |
|||
import styles from './PeerForm.scss' |
|||
|
|||
const PeerForm = ({ form, setForm, connect }) => { |
|||
const submit = () => { |
|||
const { pubkey, host } = form |
|||
connect({ pubkey, host }) |
|||
} |
|||
|
|||
return ( |
|||
<div> |
|||
<ReactModal |
|||
isOpen={form.isOpen} |
|||
contentLabel='No Overlay Click Modal' |
|||
ariaHideApp |
|||
shouldCloseOnOverlayClick |
|||
onRequestClose={() => setForm({ isOpen: false })} |
|||
parentSelector={() => document.body} |
|||
className={styles.modal} |
|||
> |
|||
<div onClick={() => setForm({ isOpen: false })} className={styles.modalClose}> |
|||
<FaClose /> |
|||
</div> |
|||
|
|||
<div className={styles.form} onKeyPress={event => event.charCode === 13 && submit()}> |
|||
<h1 className={styles.title}>Connect to a peer</h1> |
|||
|
|||
<section className={styles.pubkey}> |
|||
<label htmlFor='pubkey'>Pubkey</label> |
|||
<input |
|||
type='text' |
|||
size='' |
|||
placeholder='Public key' |
|||
value={form.pubkey} |
|||
onChange={event => setForm({ pubkey: event.target.value })} |
|||
id='pubkey' |
|||
/> |
|||
</section> |
|||
<section className={styles.local}> |
|||
<label htmlFor='address'>Address</label> |
|||
<input |
|||
type='text' |
|||
size='' |
|||
placeholder='Host address' |
|||
value={form.host} |
|||
onChange={event => setForm({ host: event.target.value })} |
|||
id='address' |
|||
/> |
|||
</section> |
|||
|
|||
<div className='buttonContainer' onClick={submit}> |
|||
<div className='buttonPrimary'> |
|||
Submit |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</ReactModal> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
PeerForm.propTypes = { |
|||
form: PropTypes.object.isRequired, |
|||
setForm: PropTypes.func.isRequired, |
|||
connect: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default PeerForm |
@ -1,107 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.modal { |
|||
position: relative; |
|||
width: 40%; |
|||
margin: 50px auto; |
|||
padding: 40px; |
|||
position: absolute; |
|||
top: auto; |
|||
left: 20%; |
|||
right: 0; |
|||
bottom: auto; |
|||
background: $white; |
|||
outline: none; |
|||
z-index: -2; |
|||
border: 1px solid $darkgrey; |
|||
} |
|||
|
|||
.modalClose { |
|||
position: absolute; |
|||
top: -13px; |
|||
right: -13px; |
|||
display: block; |
|||
font-size: 16px; |
|||
line-height: 27px; |
|||
width: 32px; |
|||
height: 32px; |
|||
background: $white; |
|||
border-radius: 50%; |
|||
color: $darkestgrey; |
|||
cursor: pointer; |
|||
text-align: center; |
|||
z-index: 2; |
|||
transition: all 0.25s; |
|||
} |
|||
|
|||
.modalClose:hover { |
|||
background: $darkgrey; |
|||
} |
|||
|
|||
.title { |
|||
text-align: center; |
|||
font-size: 24px; |
|||
color: $black; |
|||
margin-bottom: 50px; |
|||
} |
|||
|
|||
.pubkey, .local, .push { |
|||
display: flex; |
|||
justify-content: center; |
|||
font-size: 18px; |
|||
height: auto; |
|||
min-height: 55px; |
|||
margin-bottom: 20px; |
|||
border: 1px solid $traditionalgrey; |
|||
border-radius: 6px; |
|||
position: relative; |
|||
padding: 0 20px; |
|||
|
|||
label, input[type=text] { |
|||
font-size: inherit; |
|||
} |
|||
|
|||
label { |
|||
padding-top: 19px; |
|||
padding-bottom: 12px; |
|||
color: $traditionalgrey; |
|||
} |
|||
|
|||
input[type=text] { |
|||
width: 100%; |
|||
border: none; |
|||
outline: 0; |
|||
-webkit-appearance: none; |
|||
height: 55px; |
|||
padding: 0 10px; |
|||
} |
|||
} |
|||
|
|||
.buttonGroup { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
|
|||
.button { |
|||
cursor: pointer; |
|||
height: 55px; |
|||
min-height: 55px; |
|||
text-transform: none; |
|||
font-size: 18px; |
|||
transition: opacity .2s ease-out; |
|||
background: $main; |
|||
color: $white; |
|||
border: none; |
|||
font-weight: 500; |
|||
padding: 0; |
|||
width: 100%; |
|||
text-align: center; |
|||
line-height: 55px; |
|||
|
|||
&:first-child { |
|||
border-right: 1px solid lighten($main, 20%); |
|||
} |
|||
} |
|||
} |
@ -1,80 +0,0 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
|
|||
import ReactModal from 'react-modal' |
|||
import { FaClose } from 'react-icons/lib/fa' |
|||
|
|||
import styles from './PeerModal.scss' |
|||
|
|||
const PeerModal = ({ |
|||
isOpen, resetPeer, peer, disconnect |
|||
}) => { |
|||
const customStyles = { |
|||
overlay: { |
|||
cursor: 'pointer', |
|||
overflowY: 'auto' |
|||
}, |
|||
content: { |
|||
top: 'auto', |
|||
left: '20%', |
|||
right: '0', |
|||
bottom: 'auto', |
|||
width: '40%', |
|||
margin: '50px auto', |
|||
borderRadius: 'none', |
|||
padding: '0' |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<ReactModal |
|||
isOpen={isOpen} |
|||
contentLabel='No Overlay Click Modal' |
|||
ariaHideApp |
|||
shouldCloseOnOverlayClick |
|||
onRequestClose={() => resetPeer(null)} |
|||
parentSelector={() => document.body} |
|||
style={customStyles} |
|||
> |
|||
<div className={styles.closeContainer}> |
|||
<span onClick={() => resetPeer(null)}> |
|||
<FaClose /> |
|||
</span> |
|||
</div> |
|||
{ |
|||
peer && |
|||
<div className={styles.peer}> |
|||
<header className={styles.header}> |
|||
<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> |
|||
</header> |
|||
|
|||
<div className={styles.details}> |
|||
<dl> |
|||
<dt>Satoshis Received</dt> |
|||
<dd>{peer.sat_recv}</dd> |
|||
<dt>Satoshis Sent</dt> |
|||
<dd>{peer.sat_sent}</dd> |
|||
<dt>Bytes Received</dt> |
|||
<dd>{peer.bytes_recv}</dd> |
|||
<dt>Bytes Sent</dt> |
|||
<dd>{peer.bytes_sent}</dd> |
|||
</dl> |
|||
</div> |
|||
<div className={styles.close} onClick={() => disconnect({ pubkey: peer.pub_key })}> |
|||
<div>Disconnect peer</div> |
|||
</div> |
|||
</div> |
|||
} |
|||
</ReactModal> |
|||
) |
|||
} |
|||
|
|||
PeerModal.propTypes = { |
|||
isOpen: PropTypes.bool.isRequired, |
|||
resetPeer: PropTypes.func.isRequired, |
|||
peer: PropTypes.object, |
|||
disconnect: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default PeerModal |
@ -1,75 +0,0 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.closeContainer { |
|||
background: $lightgrey; |
|||
text-align: right; |
|||
padding: 10px; |
|||
|
|||
span { |
|||
color: $darkestgrey; |
|||
font-size: 20px; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
|
|||
.header { |
|||
background: $lightgrey; |
|||
padding: 20px; |
|||
|
|||
h1 { |
|||
color: $black; |
|||
text-align: center; |
|||
margin-bottom: 20px; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
h2 { |
|||
color: $darkestgrey; |
|||
font-size: 12px; |
|||
text-align: center; |
|||
} |
|||
} |
|||
|
|||
.details { |
|||
dl { |
|||
padding: 40px 40px 40px 40px; |
|||
} |
|||
|
|||
dt { |
|||
text-align: left; |
|||
float: left; |
|||
clear: left; |
|||
font-weight: 500; |
|||
padding: 20px 35px 19px 0; |
|||
color: $black; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
dd { |
|||
text-align: right; |
|||
font-weight: 400; |
|||
padding: 30px 0 10px 0; |
|||
margin-left: 0; |
|||
border-bottom: 1px solid $darkgrey; |
|||
} |
|||
} |
|||
|
|||
.close { |
|||
text-align: center; |
|||
padding-bottom: 40px; |
|||
|
|||
div { |
|||
margin: 0 auto; |
|||
cursor: pointer; |
|||
font-size: 18px; |
|||
color: $red; |
|||
border: none; |
|||
padding: 0; |
|||
text-align: center; |
|||
transition: all 0.25s; |
|||
|
|||
&:hover { |
|||
color: lighten($red, 10%); |
|||
} |
|||
} |
|||
} |
@ -1,11 +1,6 @@ |
|||
export default function subscribeToChannelGraph(mainWindow, lnd, meta) { |
|||
console.log('subscribeChannelGraph is happening') |
|||
|
|||
|
|||
const call = lnd.subscribeChannelGraph({}, meta) |
|||
|
|||
call.on('data', channelGraphData => mainWindow.send('channelGraphData', { channelGraphData })) |
|||
call.on('end', () => console.log('channel graph end')) |
|||
call.on('error', error => console.log('channelgraph error: ', error)) |
|||
call.on('status', channelGraphStatus => mainWindow.send('channelGraphStatus', { channelGraphStatus })) |
|||
} |
|||
|
@ -1,125 +0,0 @@ |
|||
import React from 'react' |
|||
import { shallow } from 'enzyme' |
|||
|
|||
import { TiPlus } from 'react-icons/lib/ti' |
|||
import Channels from '../../app/components/Channels' |
|||
import ChannelModal from '../../app/components/Channels/ChannelModal' |
|||
import ChannelForm from '../../app/components/Channels/ChannelForm' |
|||
import Channel from '../../app/components/Channels/Channel' |
|||
import OpenPendingChannel from '../../app/components/Channels/OpenPendingChannel' |
|||
import ClosedPendingChannel from '../../app/components/Channels/ClosedPendingChannel' |
|||
|
|||
const defaultProps = { |
|||
ticker: {}, |
|||
peers: [], |
|||
channelsLoading: false, |
|||
modalChannel: {}, |
|||
setChannel: () => {}, |
|||
channelModalOpen: false, |
|||
channelForm: {}, |
|||
setChannelForm: () => {}, |
|||
allChannels: [], |
|||
openChannel: () => {}, |
|||
closeChannel: () => {}, |
|||
fetchChannels: () => {}, |
|||
currentTicker: {}, |
|||
explorerLinkBase: 'https://testnet.smartbit.com.au' |
|||
} |
|||
|
|||
const channel_open = { |
|||
active: true, |
|||
capacity: '10000000', |
|||
chan_id: '1322138543153545216', |
|||
channel_point: '7efb80bf568cf55eb43ba439fdafea99b43f53493ec9ae7c0eae88de2d2b4577:0', |
|||
commit_fee: '8688', |
|||
commit_weight: '600', |
|||
fee_per_kw: '12000', |
|||
local_balance: '9991312', |
|||
num_updates: '0', |
|||
pending_htlcs: [], |
|||
remote_balance: '0', |
|||
remote_pubkey: '020178567c0f881b579a7ddbcd8ce362a33ebba2b3c2d218e667f7e3b390e40d4e', |
|||
total_satoshis_received: '0', |
|||
total_satoshis_sent: '0', |
|||
unsettled_balance: '0' |
|||
} |
|||
|
|||
const channel_pending = { |
|||
capacity: '10000000', |
|||
channel_point: '7efb80bf568cf55eb43ba439fdafea99b43f53493ec9ae7c0eae88de2d2b4577:0', |
|||
local_balance: '9991312', |
|||
remote_balance: '0', |
|||
remote_node_pub: '020178567c0f881b579a7ddbcd8ce362a33ebba2b3c2d218e667f7e3b390e40d4e' |
|||
} |
|||
|
|||
const pending_open_channels = { |
|||
blocks_till_open: 0, |
|||
channel: channel_pending, |
|||
commit_fee: '8688', |
|||
commit_weight: '600', |
|||
confirmation_height: 0, |
|||
fee_per_kw: '12000' |
|||
} |
|||
|
|||
const pending_closing_channels = { |
|||
channel: channel_pending, |
|||
closing_txid: '8d623d1ddd32945cace3351d511df2b5be3e0f7c7e5622989d2fc0215e8a2a7e' |
|||
} |
|||
|
|||
describe('Channels', () => { |
|||
describe('should show default components', () => { |
|||
const props = { ...defaultProps, channelsLoading: true } |
|||
const el = shallow(<Channels {...props} />) |
|||
it('should contain Modal and Form', () => { |
|||
expect(el.find(ChannelModal)).toHaveLength(1) |
|||
expect(el.find(ChannelForm)).toHaveLength(1) |
|||
}) |
|||
it('should have Channels header, and plus button', () => { |
|||
expect(el.contains('Channels')).toBe(true) |
|||
expect(el.find(TiPlus)).toHaveLength(1) |
|||
}) |
|||
}) |
|||
|
|||
describe('channels are loading', () => { |
|||
const props = { ...defaultProps, channelsLoading: true } |
|||
const el = shallow(<Channels {...props} />) |
|||
it('should display loading msg', () => { |
|||
expect(el.contains('Loading...')).toBe(true) |
|||
}) |
|||
}) |
|||
|
|||
describe('channels are loaded', () => { |
|||
describe('no channels', () => { |
|||
const props = { ...defaultProps, allChannels: [] } |
|||
const el = shallow(<Channels {...props} />) |
|||
it('should not show channels or loading', () => { |
|||
expect(el.contains('Loading...')).toBe(false) |
|||
expect(el.find(Channel)).toHaveLength(0) |
|||
}) |
|||
}) |
|||
|
|||
describe('channel is open-pending', () => { |
|||
const props = { ...defaultProps, allChannels: [pending_open_channels] } |
|||
const el = shallow(<Channels {...props} />) |
|||
it('should display open-pending', () => { |
|||
expect(el.find(OpenPendingChannel)).toHaveLength(1) |
|||
}) |
|||
}) |
|||
|
|||
describe('channel is open', () => { |
|||
const props = { ...defaultProps, allChannels: [channel_open] } |
|||
const el = shallow(<Channels {...props} />) |
|||
it('should display open channel', () => { |
|||
expect(el.find(Channel)).toHaveLength(1) |
|||
}) |
|||
}) |
|||
|
|||
describe('channel is closed-pending', () => { |
|||
const props = { ...defaultProps, allChannels: [pending_closing_channels] } |
|||
const el = shallow(<Channels {...props} />) |
|||
it('should display closed-pending', () => { |
|||
expect(el.find(ClosedPendingChannel)).toHaveLength(1) |
|||
}) |
|||
}) |
|||
}) |
|||
}) |
@ -1,72 +0,0 @@ |
|||
import React from 'react' |
|||
import { shallow } from 'enzyme' |
|||
|
|||
import Peers from '../../app/routes/peers/components/Peers' |
|||
import PeerModal from '../../app/components/Peers/PeerModal' |
|||
import PeerForm from '../../app/components/Peers/PeerForm' |
|||
import Peer from '../../app/components/Peers/Peer' |
|||
|
|||
const defaultProps = { |
|||
fetchPeers: () => {}, |
|||
peerFormProps: { |
|||
form: {}, |
|||
setForm: () => {}, |
|||
connect: () => {} |
|||
}, |
|||
setPeerForm: () => {}, |
|||
setPeer: () => {}, |
|||
updateSearchQuery: () => {}, |
|||
disconnectRequest: () => {}, |
|||
|
|||
peerModalOpen: false, |
|||
filteredPeers: [], |
|||
peers: { |
|||
peer: null, |
|||
searchQuery: '' |
|||
} |
|||
} |
|||
|
|||
const peer = { |
|||
address: '45.77.115.33:9735', |
|||
bytes_recv: '63322', |
|||
bytes_sent: '68714', |
|||
inbound: true, |
|||
peer_id: 3, |
|||
ping_time: '261996', |
|||
pub_key: '0293cb97aac77eacjc5377d761640f1b51ebba350902801e1aa62853fa7bc3a1f30', |
|||
sat_recv: '0', |
|||
sat_sent: '0' |
|||
} |
|||
|
|||
describe('component.Peers', () => { |
|||
describe('default components', () => { |
|||
const props = { ...defaultProps } |
|||
const el = shallow(<Peers {...props} />) |
|||
it('should contain Modal and Form', () => { |
|||
expect(el.find(PeerModal)).toHaveLength(1) |
|||
expect(el.find(PeerForm)).toHaveLength(1) |
|||
}) |
|||
it('should have Peers header, and plus button', () => { |
|||
expect(el.contains('Peers')).toBe(true) |
|||
expect(el.contains('Add new peer')).toBe(true) |
|||
}) |
|||
}) |
|||
|
|||
describe('peers are loaded', () => { |
|||
describe('no peers', () => { |
|||
const props = { ...defaultProps } |
|||
const el = shallow(<Peers {...props} />) |
|||
it('should show no peers', () => { |
|||
expect(el.find(Peer)).toHaveLength(0) |
|||
}) |
|||
}) |
|||
|
|||
describe('peer connected', () => { |
|||
const props = { ...defaultProps, filteredPeers: [peer] } |
|||
const el = shallow(<Peers {...props} />) |
|||
it('should show peer information', () => { |
|||
expect(el.find(Peer)).toHaveLength(1) |
|||
}) |
|||
}) |
|||
}) |
|||
}) |
@ -1,33 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers balanceReducer should handle DECREMENT_COUNTER 1`] = ` |
|||
Object { |
|||
"balanceLoading": false, |
|||
"channelBalance": undefined, |
|||
"walletBalance": undefined, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers balanceReducer should handle INCREMENT_COUNTER 1`] = ` |
|||
Object { |
|||
"balanceLoading": true, |
|||
"channelBalance": null, |
|||
"walletBalance": null, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers balanceReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"balanceLoading": false, |
|||
"channelBalance": null, |
|||
"walletBalance": null, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers balanceReducer should handle unknown action type 1`] = ` |
|||
Object { |
|||
"balanceLoading": false, |
|||
"channelBalance": null, |
|||
"walletBalance": null, |
|||
} |
|||
`; |
@ -1,308 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers channelsReducer should correctly getChannels 1`] = ` |
|||
Object { |
|||
"channel": null, |
|||
"channelForm": Object { |
|||
"isOpen": false, |
|||
"local_amt": "", |
|||
"node_key": "", |
|||
"push_amt": "", |
|||
}, |
|||
"channels": Array [], |
|||
"channelsLoading": true, |
|||
"closingChannel": false, |
|||
"filter": Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
"filterPulldown": false, |
|||
"filters": Array [ |
|||
Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
Object { |
|||
"key": "ACTIVE_CHANNELS", |
|||
"name": "Active Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_CHANNELS", |
|||
"name": "Open Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_PENDING_CHANNELS", |
|||
"name": "Open Pending Channels", |
|||
}, |
|||
Object { |
|||
"key": "CLOSING_PENDING_CHANNELS", |
|||
"name": "Closing Pending Channels", |
|||
}, |
|||
], |
|||
"openingChannel": false, |
|||
"pendingChannels": Object { |
|||
"pending_closing_channels": Array [], |
|||
"pending_force_closing_channels": Array [], |
|||
"pending_open_channels": Array [], |
|||
"total_limbo_balance": "", |
|||
}, |
|||
"searchQuery": "", |
|||
"viewType": 0, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers channelsReducer should correctly openingChannel 1`] = ` |
|||
Object { |
|||
"channel": null, |
|||
"channelForm": Object { |
|||
"isOpen": false, |
|||
"local_amt": "", |
|||
"node_key": "", |
|||
"push_amt": "", |
|||
}, |
|||
"channels": Array [], |
|||
"channelsLoading": false, |
|||
"closingChannel": false, |
|||
"filter": Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
"filterPulldown": false, |
|||
"filters": Array [ |
|||
Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
Object { |
|||
"key": "ACTIVE_CHANNELS", |
|||
"name": "Active Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_CHANNELS", |
|||
"name": "Open Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_PENDING_CHANNELS", |
|||
"name": "Open Pending Channels", |
|||
}, |
|||
Object { |
|||
"key": "CLOSING_PENDING_CHANNELS", |
|||
"name": "Closing Pending Channels", |
|||
}, |
|||
], |
|||
"openingChannel": true, |
|||
"pendingChannels": Object { |
|||
"pending_closing_channels": Array [], |
|||
"pending_force_closing_channels": Array [], |
|||
"pending_open_channels": Array [], |
|||
"total_limbo_balance": "", |
|||
}, |
|||
"searchQuery": "", |
|||
"viewType": 0, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers channelsReducer should correctly receiveChannel 1`] = ` |
|||
Object { |
|||
"channel": null, |
|||
"channelForm": Object { |
|||
"isOpen": false, |
|||
"local_amt": "", |
|||
"node_key": "", |
|||
"push_amt": "", |
|||
}, |
|||
"channels": Array [ |
|||
1, |
|||
2, |
|||
], |
|||
"channelsLoading": false, |
|||
"closingChannel": false, |
|||
"filter": Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
"filterPulldown": false, |
|||
"filters": Array [ |
|||
Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
Object { |
|||
"key": "ACTIVE_CHANNELS", |
|||
"name": "Active Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_CHANNELS", |
|||
"name": "Open Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_PENDING_CHANNELS", |
|||
"name": "Open Pending Channels", |
|||
}, |
|||
Object { |
|||
"key": "CLOSING_PENDING_CHANNELS", |
|||
"name": "Closing Pending Channels", |
|||
}, |
|||
], |
|||
"openingChannel": false, |
|||
"pendingChannels": Array [ |
|||
3, |
|||
4, |
|||
], |
|||
"searchQuery": "", |
|||
"viewType": 0, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers channelsReducer should correctly setChannel 1`] = ` |
|||
Object { |
|||
"channel": "channel", |
|||
"channelForm": Object { |
|||
"isOpen": false, |
|||
"local_amt": "", |
|||
"node_key": "", |
|||
"push_amt": "", |
|||
}, |
|||
"channels": Array [], |
|||
"channelsLoading": false, |
|||
"closingChannel": false, |
|||
"filter": Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
"filterPulldown": false, |
|||
"filters": Array [ |
|||
Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
Object { |
|||
"key": "ACTIVE_CHANNELS", |
|||
"name": "Active Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_CHANNELS", |
|||
"name": "Open Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_PENDING_CHANNELS", |
|||
"name": "Open Pending Channels", |
|||
}, |
|||
Object { |
|||
"key": "CLOSING_PENDING_CHANNELS", |
|||
"name": "Closing Pending Channels", |
|||
}, |
|||
], |
|||
"openingChannel": false, |
|||
"pendingChannels": Object { |
|||
"pending_closing_channels": Array [], |
|||
"pending_force_closing_channels": Array [], |
|||
"pending_open_channels": Array [], |
|||
"total_limbo_balance": "", |
|||
}, |
|||
"searchQuery": "", |
|||
"viewType": 0, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers channelsReducer should correctly setChannelForm 1`] = ` |
|||
Object { |
|||
"channel": null, |
|||
"channelForm": Object { |
|||
"isOpen": true, |
|||
"local_amt": "", |
|||
"node_key": "", |
|||
"push_amt": "", |
|||
}, |
|||
"channels": Array [], |
|||
"channelsLoading": false, |
|||
"closingChannel": false, |
|||
"filter": Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
"filterPulldown": false, |
|||
"filters": Array [ |
|||
Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
Object { |
|||
"key": "ACTIVE_CHANNELS", |
|||
"name": "Active Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_CHANNELS", |
|||
"name": "Open Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_PENDING_CHANNELS", |
|||
"name": "Open Pending Channels", |
|||
}, |
|||
Object { |
|||
"key": "CLOSING_PENDING_CHANNELS", |
|||
"name": "Closing Pending Channels", |
|||
}, |
|||
], |
|||
"openingChannel": false, |
|||
"pendingChannels": Object { |
|||
"pending_closing_channels": Array [], |
|||
"pending_force_closing_channels": Array [], |
|||
"pending_open_channels": Array [], |
|||
"total_limbo_balance": "", |
|||
}, |
|||
"searchQuery": "", |
|||
"viewType": 0, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers channelsReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"channel": null, |
|||
"channelForm": Object { |
|||
"isOpen": false, |
|||
"local_amt": "", |
|||
"node_key": "", |
|||
"push_amt": "", |
|||
}, |
|||
"channels": Array [], |
|||
"channelsLoading": false, |
|||
"closingChannel": false, |
|||
"filter": Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
"filterPulldown": false, |
|||
"filters": Array [ |
|||
Object { |
|||
"key": "ALL_CHANNELS", |
|||
"name": "All Channels", |
|||
}, |
|||
Object { |
|||
"key": "ACTIVE_CHANNELS", |
|||
"name": "Active Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_CHANNELS", |
|||
"name": "Open Channels", |
|||
}, |
|||
Object { |
|||
"key": "OPEN_PENDING_CHANNELS", |
|||
"name": "Open Pending Channels", |
|||
}, |
|||
Object { |
|||
"key": "CLOSING_PENDING_CHANNELS", |
|||
"name": "Closing Pending Channels", |
|||
}, |
|||
], |
|||
"openingChannel": false, |
|||
"pendingChannels": Object { |
|||
"pending_closing_channels": Array [], |
|||
"pending_force_closing_channels": Array [], |
|||
"pending_open_channels": Array [], |
|||
"total_limbo_balance": "", |
|||
}, |
|||
"searchQuery": "", |
|||
"viewType": 0, |
|||
} |
|||
`; |
@ -1,13 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers formReducer should correctly setFormType 1`] = ` |
|||
Object { |
|||
"formType": "FOO", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers formReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"formType": null, |
|||
} |
|||
`; |
@ -1,22 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers infoReducer should correctly getInfo 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"infoLoading": true, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers infoReducer should correctly receiveInfo 1`] = ` |
|||
Object { |
|||
"data": "foo", |
|||
"infoLoading": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers infoReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"infoLoading": false, |
|||
} |
|||
`; |
@ -1,171 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers invoiceReducer should correctly getInvoice 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": true, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly getInvoices 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": true, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly invcoiceFailed 1`] = ` |
|||
Object { |
|||
"data": null, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": false, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly invcoiceSuccessful 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": false, |
|||
"invoices": Array [ |
|||
"foo", |
|||
], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly receiveFormInvoice 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": false, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly receiveInvoice 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": "foo", |
|||
"invoiceLoading": false, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly receiveInvoices 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": false, |
|||
"invoices": Array [ |
|||
1, |
|||
2, |
|||
], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly searchInvoices 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": false, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "foo", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly sendInvoice 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": true, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should correctly setInvoice 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": "foo", |
|||
"invoiceLoading": false, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers invoiceReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"data": Object {}, |
|||
"formInvoice": Object { |
|||
"amount": "0", |
|||
"payreq": "", |
|||
"r_hash": "", |
|||
}, |
|||
"invoice": null, |
|||
"invoiceLoading": false, |
|||
"invoices": Array [], |
|||
"invoicesSearchText": "", |
|||
} |
|||
`; |
@ -1,49 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers paymentReducer should correctly getPayments 1`] = ` |
|||
Object { |
|||
"payment": null, |
|||
"paymentLoading": true, |
|||
"payments": Array [], |
|||
"sendingPayment": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers paymentReducer should correctly paymentSuccessful 1`] = ` |
|||
Object { |
|||
"payment": null, |
|||
"paymentLoading": false, |
|||
"payments": Array [], |
|||
"sendingPayment": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers paymentReducer should correctly receivePayments 1`] = ` |
|||
Object { |
|||
"payment": null, |
|||
"paymentLoading": false, |
|||
"payments": Array [ |
|||
1, |
|||
2, |
|||
], |
|||
"sendingPayment": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers paymentReducer should correctly sendPayment 1`] = ` |
|||
Object { |
|||
"payment": "foo", |
|||
"paymentLoading": false, |
|||
"payments": Array [], |
|||
"sendingPayment": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers paymentReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"payment": null, |
|||
"paymentLoading": false, |
|||
"payments": Array [], |
|||
"sendingPayment": false, |
|||
} |
|||
`; |
@ -1,182 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers peersReducer should correctly connectFailure 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly connectPeer 1`] = ` |
|||
Object { |
|||
"connecting": true, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly connectSuccess 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [ |
|||
"foo", |
|||
], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly disconnectFailure 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly disconnectPeer 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": true, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly disconnectSuccess 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly getPeers 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": true, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly receivePeers 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": "foo", |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly setPeer 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": "foo", |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should correctly setPeerForm 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"0": "f", |
|||
"1": "o", |
|||
"2": "o", |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers peersReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"connecting": false, |
|||
"disconnecting": false, |
|||
"peer": null, |
|||
"peerForm": Object { |
|||
"host": "", |
|||
"isOpen": false, |
|||
"pubkey": "", |
|||
}, |
|||
"peers": Array [], |
|||
"peersLoading": false, |
|||
"searchQuery": "", |
|||
} |
|||
`; |
@ -1,51 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`reducers tickerReducer should correctly getTicker 1`] = ` |
|||
Object { |
|||
"btcTicker": null, |
|||
"crypto": "", |
|||
"currency": "", |
|||
"ltcTicker": null, |
|||
"tickerLoading": true, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers tickerReducer should correctly receiveTicker 1`] = ` |
|||
Object { |
|||
"btcTicker": undefined, |
|||
"crypto": "", |
|||
"currency": "", |
|||
"ltcTicker": undefined, |
|||
"tickerLoading": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers tickerReducer should correctly setCrypto 1`] = ` |
|||
Object { |
|||
"btcTicker": null, |
|||
"crypto": "foo", |
|||
"currency": "", |
|||
"ltcTicker": null, |
|||
"tickerLoading": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers tickerReducer should correctly setCurrency 1`] = ` |
|||
Object { |
|||
"btcTicker": null, |
|||
"crypto": "", |
|||
"currency": "foo", |
|||
"ltcTicker": null, |
|||
"tickerLoading": false, |
|||
} |
|||
`; |
|||
|
|||
exports[`reducers tickerReducer should handle initial state 1`] = ` |
|||
Object { |
|||
"btcTicker": null, |
|||
"crypto": "", |
|||
"currency": "", |
|||
"ltcTicker": null, |
|||
"tickerLoading": false, |
|||
} |
|||
`; |
Loading…
Reference in new issue