Jack Mallers
7 years ago
20 changed files with 890 additions and 95 deletions
@ -0,0 +1,38 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
import { FaCircle } from 'react-icons/lib/fa' |
||||
|
import { btc } from 'utils' |
||||
|
import styles from './Contact.scss' |
||||
|
|
||||
|
const ClosingContact = ({ channel }) => ( |
||||
|
<li className={styles.friend} key={index}> |
||||
|
<section className={styles.info}> |
||||
|
<p className={styles.closing}> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> |
||||
|
<span> |
||||
|
Removing |
||||
|
<i onClick={() => shell.openExternal(`${'https://testnet.smartbit.com.au'}/tx/${channel.closing_txid}`)}> |
||||
|
(Details) |
||||
|
</i> |
||||
|
</span> |
||||
|
</p> |
||||
|
<h2>{channel.channel.remote_node_pub}</h2> |
||||
|
</section> |
||||
|
<section className={styles.limits}> |
||||
|
<div> |
||||
|
<h4>Can Pay</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.channel.local_balance)}BTC</p> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4>Can Receive</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.channel.remote_balance)}BTC</p> |
||||
|
</div> |
||||
|
</section> |
||||
|
</li> |
||||
|
) |
||||
|
|
||||
|
ClosingContact.propTypes = { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export default ClosingContact |
@ -0,0 +1,102 @@ |
|||||
|
@import '../../variables.scss'; |
||||
|
|
||||
|
.friend { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
padding: 30px 0; |
||||
|
border-bottom: 1px solid $traditionalgrey; |
||||
|
|
||||
|
.limits { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
div { |
||||
|
margin: 0 10px; |
||||
|
|
||||
|
h4 { |
||||
|
font-size: 12px; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.info { |
||||
|
p { |
||||
|
margin-bottom: 20px; |
||||
|
|
||||
|
&.online { |
||||
|
color: $green; |
||||
|
|
||||
|
svg { |
||||
|
color: $green; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.pending { |
||||
|
color: $orange; |
||||
|
|
||||
|
svg { |
||||
|
color: $orange; |
||||
|
} |
||||
|
|
||||
|
i { |
||||
|
margin-left: 5px; |
||||
|
color: $darkestgrey; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&:hover { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.closing { |
||||
|
color: $red; |
||||
|
|
||||
|
svg { |
||||
|
color: $red; |
||||
|
} |
||||
|
|
||||
|
i { |
||||
|
margin-left: 5px; |
||||
|
color: $darkestgrey; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
&:hover { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
svg, span { |
||||
|
display: inline-block; |
||||
|
vertical-align: top; |
||||
|
} |
||||
|
|
||||
|
svg { |
||||
|
margin-right: 5px; |
||||
|
width: 12px; |
||||
|
height: 12px; |
||||
|
color: $darkestgrey; |
||||
|
} |
||||
|
|
||||
|
span { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
h2 { |
||||
|
color: $black; |
||||
|
font-size: 14px; |
||||
|
font-weight: bold; |
||||
|
letter-spacing: 1.3px; |
||||
|
|
||||
|
span { |
||||
|
color: $darkestgrey; |
||||
|
margin-left: 5px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
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 |
@ -0,0 +1,20 @@ |
|||||
|
@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; |
||||
|
} |
@ -0,0 +1,146 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
import ReactModal from 'react-modal' |
||||
|
import { MdClose } from 'react-icons/lib/md' |
||||
|
import { FaCircle } from 'react-icons/lib/fa' |
||||
|
import styles from './FriendsForm.scss' |
||||
|
|
||||
|
const FriendsForm = ({ |
||||
|
friendsform, |
||||
|
closeFriendsForm, |
||||
|
updateFriendFormSearchQuery, |
||||
|
openChannel, |
||||
|
|
||||
|
activeChannelPubkeys, |
||||
|
nonActiveChannelPubkeys, |
||||
|
pendingOpenChannelPubkeys, |
||||
|
filteredNetworkNodes |
||||
|
}) => { |
||||
|
console.log('pendingOpenChannelPubkeys: ', pendingOpenChannelPubkeys) |
||||
|
const renderRightSide = (node) => { |
||||
|
if (node.addresses.length > 1) { |
||||
|
console.log('node: ', node) |
||||
|
} |
||||
|
|
||||
|
if (activeChannelPubkeys.includes(node.pub_key)) { |
||||
|
return ( |
||||
|
<span className={`${styles.online} ${styles.inactive}`}> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> <span>Online</span> |
||||
|
</span> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
if (nonActiveChannelPubkeys.includes(node.pub_key)) { |
||||
|
return ( |
||||
|
<span className={`${styles.offline} ${styles.inactive}`}> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> <span>Offline</span> |
||||
|
</span> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
if (pendingOpenChannelPubkeys.includes(node.pub_key)) { |
||||
|
return ( |
||||
|
<span className={`${styles.pending} ${styles.inactive}`}> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> <span>Pending</span> |
||||
|
</span> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
if (!node.addresses.length) { |
||||
|
return ( |
||||
|
<span className={`${styles.private} ${styles.inactive}`}> |
||||
|
Private |
||||
|
</span> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<span |
||||
|
className={`${styles.connect} hint--left`} |
||||
|
data-hint='Connect with 0.1 BTC' |
||||
|
onClick={() => openChannel({ pubkey: node.pub_key, host: node.addresses[0].addr, local_amt: 0.1 })} |
||||
|
> |
||||
|
Connect |
||||
|
</span> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<div> |
||||
|
<ReactModal |
||||
|
isOpen={friendsform.isOpen} |
||||
|
contentLabel='No Overlay Click Modal' |
||||
|
ariaHideApp |
||||
|
shouldCloseOnOverlayClick |
||||
|
onRequestClose={() => closeFriendsForm} |
||||
|
parentSelector={() => document.body} |
||||
|
className={styles.modal} |
||||
|
> |
||||
|
<header> |
||||
|
<div> |
||||
|
<h1>Add Contact</h1> |
||||
|
</div> |
||||
|
<div onClick={closeFriendsForm} className={styles.modalClose}> |
||||
|
<MdClose /> |
||||
|
</div> |
||||
|
</header> |
||||
|
|
||||
|
<div className={styles.form} onKeyPress={event => event.charCode === 13 && console.log('gaaaang')}> |
||||
|
<div className={styles.search}> |
||||
|
<input |
||||
|
type='text' |
||||
|
placeholder='Find friend by alias or pubkey' |
||||
|
className={styles.searchInput} |
||||
|
value={friendsform.searchQuery} |
||||
|
onChange={event => updateFriendFormSearchQuery(event.target.value)} |
||||
|
autoFocus |
||||
|
/> |
||||
|
</div> |
||||
|
|
||||
|
<ul className={styles.networkResults}> |
||||
|
{ |
||||
|
friendsform.searchQuery.length > 0 && filteredNetworkNodes.map(node => { |
||||
|
return ( |
||||
|
<li key={node.pub_key}> |
||||
|
<section> |
||||
|
{ |
||||
|
node.alias.length > 0 ? |
||||
|
<h2> |
||||
|
<span>{node.alias.trim()}</span> |
||||
|
<span>({node.pub_key.substr(0, 10)}...{node.pub_key.substr(node.pub_key.length - 10)})</span> |
||||
|
</h2> |
||||
|
: |
||||
|
<h2> |
||||
|
<span>{node.pub_key}</span> |
||||
|
</h2> |
||||
|
} |
||||
|
</section> |
||||
|
<section> |
||||
|
{renderRightSide(node)} |
||||
|
</section> |
||||
|
</li> |
||||
|
) |
||||
|
}) |
||||
|
} |
||||
|
</ul> |
||||
|
</div> |
||||
|
<footer className={styles.footer}> |
||||
|
<div> |
||||
|
<span className={styles.amount}> |
||||
|
0.1 |
||||
|
</span> |
||||
|
<span className={styles.caption}> |
||||
|
BTC per contact |
||||
|
</span> |
||||
|
</div> |
||||
|
</footer> |
||||
|
</ReactModal> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
FriendsForm.propTypes = { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export default FriendsForm |
@ -0,0 +1,135 @@ |
|||||
|
@import '../../variables.scss'; |
||||
|
|
||||
|
.modal { |
||||
|
position: relative; |
||||
|
width: 50%; |
||||
|
margin: 50px auto; |
||||
|
position: absolute; |
||||
|
top: auto; |
||||
|
left: 20%; |
||||
|
right: 0; |
||||
|
bottom: auto; |
||||
|
background: $white; |
||||
|
outline: none; |
||||
|
z-index: -2; |
||||
|
border: 1px solid $darkgrey; |
||||
|
|
||||
|
header { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
padding: 15px; |
||||
|
border-bottom: 1px solid $darkgrey; |
||||
|
|
||||
|
h1, svg { |
||||
|
font-size: 22px; |
||||
|
} |
||||
|
|
||||
|
svg { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.form { |
||||
|
padding: 30px 15px; |
||||
|
|
||||
|
.search { |
||||
|
.searchInput { |
||||
|
width: calc(100% - 30px); |
||||
|
padding: 10px 15px; |
||||
|
outline: 0; |
||||
|
border: 0; |
||||
|
background: $lightgrey; |
||||
|
color: $darkestgrey; |
||||
|
border-radius: 5px; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.networkResults { |
||||
|
overflow-y: scroll; |
||||
|
height: 400px; |
||||
|
margin-top: 30px; |
||||
|
padding: 20px 0; |
||||
|
|
||||
|
li { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
padding: 10px 0; |
||||
|
|
||||
|
h2 { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
letter-spacing: 1.3px; |
||||
|
|
||||
|
span { |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
|
||||
|
&:nth-child(1) { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
letter-spacing: 1.3px; |
||||
|
} |
||||
|
|
||||
|
&:nth-child(2) { |
||||
|
color: $darkestgrey; |
||||
|
font-size: 12px; |
||||
|
line-height: 16px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.connect { |
||||
|
cursor: pointer; |
||||
|
color: $darkestgrey; |
||||
|
transition: all 0.25s; |
||||
|
font-size: 12px; |
||||
|
|
||||
|
&:hover { |
||||
|
color: $main; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.inactive { |
||||
|
font-size: 12px; |
||||
|
|
||||
|
display: inline-block; |
||||
|
vertical-align: top; |
||||
|
|
||||
|
&.online { |
||||
|
color: $green; |
||||
|
} |
||||
|
|
||||
|
&.offline { |
||||
|
color: $darkestgrey; |
||||
|
} |
||||
|
|
||||
|
&.pending { |
||||
|
color: $orange; |
||||
|
} |
||||
|
|
||||
|
&.private { |
||||
|
color: darken($darkestgrey, 50%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
padding: 10px 15px; |
||||
|
border-top: 1px solid $darkgrey; |
||||
|
|
||||
|
span { |
||||
|
&:nth-child(1) { |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
&:nth-child(2) { |
||||
|
margin-left: 2px; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
import { FaCircle } from 'react-icons/lib/fa' |
||||
|
import { btc } from 'utils' |
||||
|
import styles from './Contact.scss' |
||||
|
|
||||
|
const OfflineContact = ({ channel }) => ( |
||||
|
<li className={styles.friend} key={channel.chan_id}> |
||||
|
<section className={styles.info}> |
||||
|
<p> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> |
||||
|
<span>Offline</span> |
||||
|
</p> |
||||
|
<h2>{channel.remote_pubkey}</h2> |
||||
|
</section> |
||||
|
<section className={styles.limits}> |
||||
|
<div> |
||||
|
<h4>Can Pay</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.local_balance)}BTC</p> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4>Can Receive</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.remote_balance)}BTC</p> |
||||
|
</div> |
||||
|
</section> |
||||
|
</li> |
||||
|
) |
||||
|
|
||||
|
OfflineContact.propTypes = { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export default OfflineContact |
@ -0,0 +1,33 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
import { FaCircle } from 'react-icons/lib/fa' |
||||
|
import { btc } from 'utils' |
||||
|
import styles from './Contact.scss' |
||||
|
|
||||
|
const OnlineContact = ({ channel }) => ( |
||||
|
<li className={styles.friend} key={channel.chan_id}> |
||||
|
<section className={styles.info}> |
||||
|
<p className={styles.online}> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> |
||||
|
<span>Online</span> |
||||
|
</p> |
||||
|
<h2>{channel.remote_pubkey}</h2> |
||||
|
</section> |
||||
|
<section className={styles.limits}> |
||||
|
<div> |
||||
|
<h4>Can Pay</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.local_balance)}BTC</p> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4>Can Receive</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.remote_balance)}BTC</p> |
||||
|
</div> |
||||
|
</section> |
||||
|
</li> |
||||
|
) |
||||
|
|
||||
|
OnlineContact.propTypes = { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export default OnlineContact |
@ -0,0 +1,38 @@ |
|||||
|
import React from 'react' |
||||
|
import PropTypes from 'prop-types' |
||||
|
import { FaCircle } from 'react-icons/lib/fa' |
||||
|
import { btc } from 'utils' |
||||
|
import styles from './Contact.scss' |
||||
|
|
||||
|
const PendingContact = ({ channel }) => ( |
||||
|
<li className={styles.friend} key={channel.chan_id}> |
||||
|
<section className={styles.info}> |
||||
|
<p className={styles.pending}> |
||||
|
<FaCircle style={{ verticalAlign: 'top' }} /> |
||||
|
<span> |
||||
|
Pending |
||||
|
<i onClick={() => shell.openExternal(`${'https://testnet.smartbit.com.au'}/tx/${channel.channel.channel_point.split(':')[0]}`)}> |
||||
|
(~{channel.blocks_till_open * 10} minutes) |
||||
|
</i> |
||||
|
</span> |
||||
|
</p> |
||||
|
<h2>{channel.channel.remote_node_pub}</h2> |
||||
|
</section> |
||||
|
<section className={styles.limits}> |
||||
|
<div> |
||||
|
<h4>Can Pay</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.channel.local_balance)}BTC</p> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4>Can Receive</h4> |
||||
|
<p>{btc.satoshisToBtc(channel.channel.remote_balance)}BTC</p> |
||||
|
</div> |
||||
|
</section> |
||||
|
</li> |
||||
|
) |
||||
|
|
||||
|
PendingContact.propTypes = { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export default PendingContact |
@ -0,0 +1,74 @@ |
|||||
|
import { createSelector } from 'reselect' |
||||
|
|
||||
|
import filter from 'lodash/filter' |
||||
|
|
||||
|
// Initial State
|
||||
|
const initialState = { |
||||
|
isOpen: false, |
||||
|
searchQuery: '', |
||||
|
friend: '' |
||||
|
} |
||||
|
|
||||
|
// Constants
|
||||
|
// ------------------------------------
|
||||
|
export const OPEN_FRIENDS_FORM = 'OPEN_FRIENDS_FORM' |
||||
|
export const CLOSE_FRIENDS_FORM = 'CLOSE_FRIENDS_FORM' |
||||
|
|
||||
|
export const UPDATE_FRIEND_FORM_SEARCH_QUERY = 'UPDATE_FRIEND_FORM_SEARCH_QUERY' |
||||
|
|
||||
|
// ------------------------------------
|
||||
|
// Actions
|
||||
|
// ------------------------------------
|
||||
|
export function openFriendsForm() { |
||||
|
return { |
||||
|
type: OPEN_FRIENDS_FORM |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export function closeFriendsForm() { |
||||
|
return { |
||||
|
type: CLOSE_FRIENDS_FORM |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export function updateFriendFormSearchQuery(searchQuery) { |
||||
|
return { |
||||
|
type: UPDATE_FRIEND_FORM_SEARCH_QUERY, |
||||
|
searchQuery |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ------------------------------------
|
||||
|
// Action Handlers
|
||||
|
// ------------------------------------
|
||||
|
const ACTION_HANDLERS = { |
||||
|
[OPEN_FRIENDS_FORM]: state => ({ ...state, isOpen: true }), |
||||
|
[CLOSE_FRIENDS_FORM]: state => ({ ...state, isOpen: false }), |
||||
|
|
||||
|
[UPDATE_FRIEND_FORM_SEARCH_QUERY]: (state, { searchQuery }) => ({ ...state, searchQuery }) |
||||
|
} |
||||
|
|
||||
|
// ------------------------------------
|
||||
|
// Selector
|
||||
|
// ------------------------------------
|
||||
|
const friendFormSelectors = {} |
||||
|
const networkNodesSelector = state => state.network.nodes |
||||
|
const searchQuerySelector = state => state.friendsform.searchQuery |
||||
|
|
||||
|
|
||||
|
friendFormSelectors.filteredNetworkNodes = createSelector( |
||||
|
networkNodesSelector, |
||||
|
searchQuerySelector, |
||||
|
(nodes, searchQuery) => filter(nodes, node => node.alias.includes(searchQuery) || node.pub_key.includes(searchQuery)) |
||||
|
) |
||||
|
|
||||
|
export { friendFormSelectors } |
||||
|
|
||||
|
// ------------------------------------
|
||||
|
// Reducer
|
||||
|
// ------------------------------------
|
||||
|
export default function friendFormReducer(state = initialState, action) { |
||||
|
const handler = ACTION_HANDLERS[action.type] |
||||
|
|
||||
|
return handler ? handler(state, action) : state |
||||
|
} |
@ -1,24 +1,76 @@ |
|||||
import { withRouter } from 'react-router' |
import { withRouter } from 'react-router' |
||||
import { connect } from 'react-redux' |
import { connect } from 'react-redux' |
||||
|
|
||||
import { fetchChannels, channelsSelectors } from 'reducers/channels' |
import { |
||||
|
fetchChannels, |
||||
|
openChannel, |
||||
|
currentChannels, |
||||
|
channelsSelectors |
||||
|
} from 'reducers/channels' |
||||
|
|
||||
import { fetchPeers } from 'reducers/peers' |
import { fetchPeers } from 'reducers/peers' |
||||
|
|
||||
|
import { fetchDescribeNetwork } from 'reducers/network' |
||||
|
|
||||
|
import { |
||||
|
openFriendsForm, |
||||
|
closeFriendsForm, |
||||
|
updateFriendFormSearchQuery, |
||||
|
friendFormSelectors |
||||
|
} from 'reducers/friendsform' |
||||
|
|
||||
import Friends from '../components/Friends' |
import Friends from '../components/Friends' |
||||
|
|
||||
const mapDispatchToProps = { |
const mapDispatchToProps = { |
||||
|
openFriendsForm, |
||||
|
closeFriendsForm, |
||||
|
updateFriendFormSearchQuery, |
||||
|
openChannel, |
||||
|
|
||||
fetchChannels, |
fetchChannels, |
||||
fetchPeers |
fetchPeers, |
||||
|
fetchDescribeNetwork |
||||
} |
} |
||||
|
|
||||
const mapStateToProps = state => ({ |
const mapStateToProps = state => ({ |
||||
channels: state.channels, |
channels: state.channels, |
||||
peers: state.peers, |
peers: state.peers, |
||||
|
network: state.network, |
||||
|
friendsform: state.friendsform, |
||||
|
|
||||
|
currentChannels: currentChannels(state), |
||||
activeChannels: channelsSelectors.activeChannels(state), |
activeChannels: channelsSelectors.activeChannels(state), |
||||
|
activeChannelPubkeys: channelsSelectors.activeChannelPubkeys(state), |
||||
nonActiveChannels: channelsSelectors.nonActiveChannels(state), |
nonActiveChannels: channelsSelectors.nonActiveChannels(state), |
||||
pendingOpenChannels: channelsSelectors.pendingOpenChannels(state) |
nonActiveChannelPubkeys: channelsSelectors.nonActiveChannelPubkeys(state), |
||||
|
pendingOpenChannels: channelsSelectors.pendingOpenChannels(state), |
||||
|
pendingOpenChannelPubkeys: channelsSelectors.pendingOpenChannelPubkeys(state), |
||||
|
closingPendingChannels: channelsSelectors.closingPendingChannels(state), |
||||
|
|
||||
|
filteredNetworkNodes: friendFormSelectors.filteredNetworkNodes(state) |
||||
}) |
}) |
||||
|
|
||||
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Friends)) |
const mergeProps = (stateProps, dispatchProps, ownProps) => { |
||||
|
const friendsFormProps = { |
||||
|
closeFriendsForm: dispatchProps.closeFriendsForm, |
||||
|
updateFriendFormSearchQuery: dispatchProps.updateFriendFormSearchQuery, |
||||
|
openChannel: dispatchProps.openChannel, |
||||
|
|
||||
|
friendsform: stateProps.friendsform, |
||||
|
filteredNetworkNodes: stateProps.filteredNetworkNodes, |
||||
|
|
||||
|
activeChannelPubkeys: stateProps.activeChannelPubkeys, |
||||
|
nonActiveChannelPubkeys: stateProps.nonActiveChannelPubkeys, |
||||
|
pendingOpenChannelPubkeys: stateProps.pendingOpenChannelPubkeys |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
...stateProps, |
||||
|
...dispatchProps, |
||||
|
...ownProps, |
||||
|
|
||||
|
friendsFormProps |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default withRouter(connect(mapStateToProps, mapDispatchToProps, mergeProps)(Friends)) |
||||
|
Loading…
Reference in new issue