diff --git a/app/components/Contacts/Contact.scss b/app/components/Contacts/Contact.scss
index d8c71d01..749dac7e 100644
--- a/app/components/Contacts/Contact.scss
+++ b/app/components/Contacts/Contact.scss
@@ -7,6 +7,12 @@
padding: 30px 0;
border-bottom: 1px solid $traditionalgrey;
+ &.loading {
+ .info {
+ opacity: 0.2;
+ }
+ }
+
.limits {
display: flex;
flex-direction: row;
@@ -100,3 +106,46 @@
}
}
}
+
+@-webkit-keyframes animation-rotate {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ }
+}
+
+@-moz-keyframes animation-rotate {
+ 100% {
+ -moz-transform: rotate(360deg);
+ }
+}
+
+@-o-keyframes animation-rotate {
+ 100% {
+ -o-transform: rotate(360deg);
+ }
+}
+
+@keyframes animation-rotate {
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.spinner {
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-left-color: rgba(0, 0, 0, 0.4);
+ -webkit-border-radius: 999px;
+ -moz-border-radius: 999px;
+ border-radius: 999px;
+}
+
+.spinner {
+ margin: 0 auto;
+ height: 50px;
+ width: 50px;
+ -webkit-animation: animation-rotate 1000ms linear infinite;
+ -moz-animation: animation-rotate 1000ms linear infinite;
+ -o-animation: animation-rotate 1000ms linear infinite;
+ animation: animation-rotate 1000ms linear infinite;
+}
+
diff --git a/app/components/Contacts/ContactsForm.js b/app/components/Contacts/ContactsForm.js
index 4e8cc34a..ec7bf54f 100644
--- a/app/components/Contacts/ContactsForm.js
+++ b/app/components/Contacts/ContactsForm.js
@@ -27,12 +27,24 @@ class ContactsForm extends React.Component {
nonActiveChannelPubkeys,
pendingOpenChannelPubkeys,
filteredNetworkNodes,
+ loadingChannelPubkeys,
showManualForm
} = this.props
const { editing, manualFormInput } = this.state
+
const renderRightSide = (node) => {
+ if (loadingChannelPubkeys.includes(node.pub_key)) {
+ return (
+
+
+
+ )
+ }
+
if (activeChannelPubkeys.includes(node.pub_key)) {
return (
diff --git a/app/components/Contacts/ContactsForm.scss b/app/components/Contacts/ContactsForm.scss
index 0e094442..1860c1cf 100644
--- a/app/components/Contacts/ContactsForm.scss
+++ b/app/components/Contacts/ContactsForm.scss
@@ -188,3 +188,46 @@
}
}
}
+
+@-webkit-keyframes animation-rotate {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ }
+}
+
+@-moz-keyframes animation-rotate {
+ 100% {
+ -moz-transform: rotate(360deg);
+ }
+}
+
+@-o-keyframes animation-rotate {
+ 100% {
+ -o-transform: rotate(360deg);
+ }
+}
+
+@keyframes animation-rotate {
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.spinner {
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-left-color: rgba(0, 0, 0, 0.4);
+ -webkit-border-radius: 999px;
+ -moz-border-radius: 999px;
+ border-radius: 999px;
+}
+
+.spinner {
+ margin: 0 auto;
+ height: 20px;
+ width: 20px;
+ -webkit-animation: animation-rotate 1000ms linear infinite;
+ -moz-animation: animation-rotate 1000ms linear infinite;
+ -o-animation: animation-rotate 1000ms linear infinite;
+ animation: animation-rotate 1000ms linear infinite;
+}
+
diff --git a/app/components/Contacts/LoadingContact.js b/app/components/Contacts/LoadingContact.js
new file mode 100644
index 00000000..2161c818
--- /dev/null
+++ b/app/components/Contacts/LoadingContact.js
@@ -0,0 +1,28 @@
+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 LoadingContact = ({ pubkey }) => (
+
+
+
+
+ Loading
+
+ {pubkey}
+
+
+
+)
+
+LoadingContact.propTypes = {
+
+}
+
+export default LoadingContact
diff --git a/app/lnd/methods/channelController.js b/app/lnd/methods/channelController.js
index 40a4fdaa..410b23d4 100644
--- a/app/lnd/methods/channelController.js
+++ b/app/lnd/methods/channelController.js
@@ -30,7 +30,11 @@ export function connectAndOpen(lnd, meta, event, payload) {
const peer = find(peers, { pub_key: pubkey })
if (peer) {
- console.log('we can open the channel')
+ console.log('already have the peer. can open the channel now')
+ const call = lnd.openChannel(channelPayload, meta)
+
+ call.on('data', data => event.sender.send('pushchannelupdated', { pubkey, data }))
+ call.on('error', error => event.sender.send('pushchannelerror', { pubkey, error: error.toString() }))
} else {
console.log('connect to the peer first')
connectPeer(lnd, meta, { pubkey, host })
@@ -41,9 +45,6 @@ export function connectAndOpen(lnd, meta, event, payload) {
call.on('data', data => event.sender.send('pushchannelupdated', { data }))
call.on('error', error => event.sender.send('pushchannelerror', { error: error.toString() }))
-
- call.on('end', () => event.sender.send('pushchannelend'))
- call.on('status', status => event.sender.send('pushchannelstatus', { status }))
})
.catch(err => {
console.log('connectPeer err: ', err)
diff --git a/app/reducers/channels.js b/app/reducers/channels.js
index 0a752df8..0c692b6e 100644
--- a/app/reducers/channels.js
+++ b/app/reducers/channels.js
@@ -29,6 +29,9 @@ export const SET_VIEW_TYPE = 'SET_VIEW_TYPE'
export const TOGGLE_CHANNEL_PULLDOWN = 'TOGGLE_CHANNEL_PULLDOWN'
export const CHANGE_CHANNEL_FILTER = 'CHANGE_CHANNEL_FILTER'
+export const ADD_LOADING_PUBKEY = 'ADD_LOADING_PUBKEY'
+export const REMOVE_LOADING_PUBKEY = 'REMOVE_LOADING_PUBKEY'
+
// ------------------------------------
// Actions
// ------------------------------------
@@ -91,6 +94,20 @@ export function setViewType(viewType) {
}
}
+export function addLoadingPubkey(pubkey) {
+ return {
+ type: ADD_LOADING_PUBKEY,
+ pubkey
+ }
+}
+
+export function removeLoadingPubkey(pubkey) {
+ return {
+ type: REMOVE_LOADING_PUBKEY,
+ pubkey
+ }
+}
+
// Send IPC event for peers
export const fetchChannels = () => async (dispatch) => {
dispatch(getChannels())
@@ -105,6 +122,7 @@ export const openChannel = ({ pubkey, host, local_amt, push_amt }) => (dispatch)
const localamt = btc.btcToSatoshis(local_amt)
dispatch(openingChannel())
+ dispatch(addLoadingPubkey(pubkey))
ipcRenderer.send('lnd', { msg: 'connectAndOpen', data: { pubkey, host, localamt } })
}
@@ -118,9 +136,10 @@ export const channelSuccessful = () => (dispatch) => {
}
// Receive IPC event for updated channel
-export const pushchannelupdated = (event, data) => (dispatch) => {
+export const pushchannelupdated = (event, { pubkey, data }) => (dispatch) => {
console.log('PUSH CHANNEL UPDATED: ', data)
dispatch(fetchChannels())
+ dispatch(removeLoadingPubkey(pubkey))
}
// Receive IPC event for channel end
@@ -130,10 +149,11 @@ export const pushchannelend = event => (dispatch) => { // eslint-disable-line
}
// Receive IPC event for channel error
-export const pushchannelerror = (event, { error }) => (dispatch) => {
+export const pushchannelerror = (event, { pubkey, error }) => (dispatch) => {
console.log('PUSH CHANNEL ERROR: ', error)
dispatch(openingFailure())
dispatch(setError(error))
+ dispatch(removeLoadingPubkey(pubkey))
}
// Receive IPC event for channel status
@@ -269,7 +289,10 @@ const ACTION_HANDLERS = {
[SET_VIEW_TYPE]: (state, { viewType }) => ({ ...state, viewType }),
[TOGGLE_CHANNEL_PULLDOWN]: state => ({ ...state, filterPulldown: !state.filterPulldown }),
- [CHANGE_CHANNEL_FILTER]: (state, { filter }) => ({ ...state, filterPulldown: false, filter })
+ [CHANGE_CHANNEL_FILTER]: (state, { filter }) => ({ ...state, filterPulldown: false, filter }),
+
+ [ADD_LOADING_PUBKEY]: (state, { pubkey }) => ({ ...state, loadingChannelPubkeys: [pubkey, ...state.loadingChannelPubkeys] }),
+ [REMOVE_LOADING_PUBKEY]: (state, { pubkey }) => ({ ...state, loadingChannelPubkeys: state.loadingChannelPubkeys.filter(loadingPubkey => loadingPubkey !== pubkey) })
}
const channelsSelectors = {}
@@ -427,7 +450,9 @@ const initialState = {
{ key: 'NON_ACTIVE_CHANNELS', name: 'Offline Contacts' },
{ key: 'OPEN_PENDING_CHANNELS', name: 'Pending Contacts' },
{ key: 'CLOSING_PENDING_CHANNELS', name: 'Closing Contacts' }
- ]
+ ],
+
+ loadingChannelPubkeys: []
}
export default function channelsReducer(state = initialState, action) {
diff --git a/app/routes/contacts/components/Contacts.js b/app/routes/contacts/components/Contacts.js
index 43da439b..3dd00d35 100644
--- a/app/routes/contacts/components/Contacts.js
+++ b/app/routes/contacts/components/Contacts.js
@@ -12,6 +12,7 @@ import OnlineContact from 'components/Contacts/OnlineContact'
import PendingContact from 'components/Contacts/PendingContact'
import ClosingContact from 'components/Contacts/ClosingContact'
import OfflineContact from 'components/Contacts/OfflineContact'
+import LoadingContact from 'components/Contacts/LoadingContact'
import plus from 'icons/plus.svg'
@@ -40,7 +41,8 @@ class Contacts extends Component {
searchQuery,
filterPulldown,
filter,
- viewType
+ viewType,
+ loadingChannelPubkeys
},
currentChannels,
activeChannels,
@@ -148,6 +150,16 @@ class Contacts extends Component {
+ {
+ loadingChannelPubkeys.map(pubkey => {
+ console.log('pubkey: ', pubkey)
+
+ return (
+
+ )
+ })
+ }
+
{
currentChannels.length > 0 && currentChannels.map((channel, index) => {
if (Object.prototype.hasOwnProperty.call(channel, 'blocks_till_open')) {
diff --git a/app/routes/contacts/containers/ContactsContainer.js b/app/routes/contacts/containers/ContactsContainer.js
index 568fa34c..e7a4bbf1 100644
--- a/app/routes/contacts/containers/ContactsContainer.js
+++ b/app/routes/contacts/containers/ContactsContainer.js
@@ -71,6 +71,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
contactsform: stateProps.contactsform,
filteredNetworkNodes: stateProps.filteredNetworkNodes,
+ loadingChannelPubkeys: stateProps.channels.loadingChannelPubkeys,
showManualForm: stateProps.showManualForm,
activeChannelPubkeys: stateProps.activeChannelPubkeys,