Browse Source

Merge pull request #211 from LN-Zap/feature/help-route

Feature/help route
renovate/lint-staged-8.x
JimmyMow 7 years ago
committed by GitHub
parent
commit
d2c622843e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      app/components/LndSyncing/LndSyncing.js
  2. 2
      app/components/LndSyncing/LndSyncing.scss
  3. 7
      app/components/Nav/Nav.js
  4. 6
      app/containers/Root.js
  5. 1
      app/icons/help.svg
  6. 9
      app/main.dev.js
  7. 8
      app/reducers/lnd.js
  8. 2
      app/routes.js
  9. 88
      app/routes/help/components/Help.js
  10. 90
      app/routes/help/components/Help.scss
  11. 10
      app/routes/help/containers/HelpContainer.js
  12. 3
      app/routes/help/index.js
  13. 7
      package.json

45
app/components/LndSyncing/LndSyncing.js

@ -1,5 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import copy from 'copy-to-clipboard'
import { showNotification } from 'notifications'
import { FaCopy } from 'react-icons/lib/fa'
import styles from './LndSyncing.scss'
@ -31,25 +33,37 @@ class LndSyncing extends Component {
}
componentWillMount() {
const { fetchBlockHeight, newAddress } = this.props
this.props.fetchBlockHeight()
}
componentDidUpdate(prevProps) {
const { grpcStarted, newAddress } = this.props
fetchBlockHeight()
newAddress('np2wkh')
if (!prevProps.grpcStarted && grpcStarted) {
newAddress('np2wkh')
}
}
render() {
const { syncPercentage, address: { address } } = this.props
const { syncPercentage, address: { addressLoading, address } } = this.props
const { facts, currentFact } = this.state
const renderCurrentFact = facts[currentFact]
const copyOnClick = () => {
if (!address) { return }
copy(address)
showNotification('Noice', 'Successfully copied to clipboard')
}
return (
<div className={styles.container}>
<header>
<section>
<h3>zap</h3>
</section>
<section className={styles.loading}>
<h4>{syncPercentage}%</h4>
<section className={`${styles.loading} hint--left`} data-hint='Syncing your Lightning Network node to the blockchain'>
<h4>{syncPercentage.toString().length > 0 && `${syncPercentage}%`}</h4>
<div className={styles.spinner} />
</section>
</header>
@ -79,8 +93,15 @@ class LndSyncing extends Component {
</section>
<section>
<div className={styles.address}>
<span>{address}</span>
<span className='hint--left' data-hint='Copy Address'>
<span>
{
addressLoading ?
'Loading...'
:
address
}
</span>
<span className='hint--left' data-hint='Copy Address' onClick={copyOnClick}>
<FaCopy />
</span>
</div>
@ -94,8 +115,12 @@ class LndSyncing extends Component {
LndSyncing.propTypes = {
newAddress: PropTypes.func.isRequired,
fetchBlockHeight: PropTypes.func.isRequired,
syncPercentage: PropTypes.number.isRequired,
address: PropTypes.object.isRequired
syncPercentage: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
]).isRequired,
address: PropTypes.object.isRequired,
grpcStarted: PropTypes.bool.isRequired
}
export default LndSyncing

2
app/components/LndSyncing/LndSyncing.scss

@ -183,7 +183,7 @@
span:nth-child(1) {
flex: 9;
overflow-x: scroll;
font-size: 18px;
font-size: 14px;
}
span:nth-child(2) {

7
app/components/Nav/Nav.js

@ -6,6 +6,7 @@ import Isvg from 'react-inlinesvg'
import walletIcon from 'icons/wallet.svg'
import peersIcon from 'icons/peers.svg'
import networkIcon from 'icons/globe.svg'
import helpIcon from 'icons/help.svg'
import styles from './Nav.scss'
@ -34,6 +35,12 @@ const Nav = ({ openPayForm, openRequestForm }) => (
<span>Network</span>
</li>
</NavLink>
<NavLink exact to='/help' activeClassName={styles.active} className={styles.link}>
<li>
<Isvg styles={{ verticalAlign: 'middle' }} src={helpIcon} />
<span>Help</span>
</li>
</NavLink>
</ul>
<div className={styles.buttons}>
<div className={`buttonPrimary ${styles.button}`} onClick={openPayForm}>

6
app/containers/Root.js

@ -39,6 +39,7 @@ const Root = ({
fetchBlockHeight={fetchBlockHeight}
syncPercentage={syncPercentage}
address={address}
grpcStarted={lnd.grpcStarted}
/>
)
}
@ -61,7 +62,10 @@ Root.propTypes = {
lnd: PropTypes.object.isRequired,
fetchBlockHeight: PropTypes.func.isRequired,
newAddress: PropTypes.func.isRequired,
syncPercentage: PropTypes.number.isRequired,
syncPercentage: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
]).isRequired,
address: PropTypes.object.isRequired
}

1
app/icons/help.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-life-buoy"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4"></circle><line x1="4.93" y1="4.93" x2="9.17" y2="9.17"></line><line x1="14.83" y1="14.83" x2="19.07" y2="19.07"></line><line x1="14.83" y1="9.17" x2="19.07" y2="4.93"></line><line x1="14.83" y1="9.17" x2="18.36" y2="5.64"></line><line x1="4.93" y1="19.07" x2="9.17" y2="14.83"></line></svg>

After

Width:  |  Height:  |  Size: 575 B

9
app/main.dev.js

@ -127,13 +127,18 @@ const sendLndSynced = () => {
// Starts the LND node
const startLnd = () => {
const lndPath = path.join(__dirname, '..', 'resources', 'bin', plat, plat === 'win32' ? 'lnd.exe' : 'lnd')
let lndPath
if (process.env.NODE_ENV === 'development') {
lndPath = path.join(__dirname, '..', 'resources', 'bin', plat, plat === 'win32' ? 'lnd.exe' : 'lnd')
} else {
lndPath = path.join(__dirname, '..', 'bin', plat === 'win32' ? 'lnd.exe' : 'lnd')
}
const neutrino = spawn(lndPath,
[
'--bitcoin.active',
'--bitcoin.testnet',
'--neutrino.active',
'--bitcoin.node=neutrino',
'--neutrino.connect=btcd0.lightning.computer:18333',
'--autopilot.active',
'--debuglevel=debug',

8
app/reducers/lnd.js

@ -122,7 +122,13 @@ const lndBlockHeightSelector = state => state.lnd.lndBlockHeight
lndSelectors.syncPercentage = createSelector(
blockHeightSelector,
lndBlockHeightSelector,
(blockHeight, lndBlockHeight) => (Math.floor((lndBlockHeight / blockHeight) * 100))
(blockHeight, lndBlockHeight) => {
const percentage = Math.floor((lndBlockHeight / blockHeight) * 100)
if (percentage === Infinity) { return '' }
return percentage
}
)
export { lndSelectors }

2
app/routes.js

@ -5,12 +5,14 @@ import App from './routes/app'
import Activity from './routes/activity'
import Contacts from './routes/contacts'
import Network from './routes/network'
import Help from './routes/help'
const routes = () => (
<App>
<Switch>
<Route path='/contacts' component={Contacts} />
<Route path='/network' component={Network} />
<Route path='/help' component={Help} />
<Route path='/' component={Activity} />
</Switch>
</App>

88
app/routes/help/components/Help.js

@ -0,0 +1,88 @@
import { shell } from 'electron'
import React, { Component } from 'react'
import { MdSearch } from 'react-icons/lib/md'
import styles from './Help.scss'
class Help extends Component {
constructor(props) {
super(props)
this.state = {
videos: [
{
id: '8kZq6eec49A',
title: 'Syncing and Depositing - Zap Lightning Network Wallet Tutorial (Video 1)'
},
{
id: 'xSiTH63fOQM',
title: 'Adding a contact - Zap Lightning Network Wallet Tutorial (Video 2)'
},
{
id: 'c0SLmywYDHU',
title: 'Making a Lightning Network payment - Zap Lightning Network Wallet Tutorial (Video 3)'
},
{
id: 'Xrx2TiiF90Q',
title: 'Receive Lightning Network payment - Zap Lightning Network Wallet Tutorial (Video 4)'
},
{
id: 'YfxukBHnwUM',
title: 'Network Map - Zap Lightning Network Wallet Tutorial (Video 5)'
},
{
id: 'NORklrrYzOg',
title: 'Using an explorer to add Zap contacts - Zap Lightning Network Wallet Tutorial (Video 6)'
}
],
searchQuery: ''
}
}
render() {
const { videos, searchQuery } = this.state
const filteredVideos = videos.filter(video => video.title.includes(searchQuery))
return (
<div className={styles.helpContainer}>
<header className={styles.header}>
<h1>Video tutorials</h1>
</header>
<div className={styles.search}>
<label className={`${styles.label} ${styles.input}`} htmlFor='helpSearch'>
<MdSearch />
</label>
<input
value={searchQuery}
onChange={event => this.setState({ searchQuery: event.target.value })}
className={`${styles.text} ${styles.input}`}
placeholder='Search the video library...'
type='text'
id='helpSearch'
/>
</div>
<ul className={styles.videos}>
{
filteredVideos.map((video, index) => (
<li key={index}>
<iframe
src={`https://www.youtube.com/embed/${video.id}`}
frameBorder='0'
title={video.id}
/>
<section className={styles.info} onClick={() => shell.openExternal(`https://www.youtube.com/watch?v=${video.id}`)}>
<h2>{video.title}</h2>
</section>
</li>
))
}
</ul>
</div>
)
}
}
export default Help

90
app/routes/help/components/Help.scss

@ -0,0 +1,90 @@
@import '../../../variables.scss';
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
background: $lightgrey;
padding: 20px 40px;
h1 {
text-transform: uppercase;
font-size: 26px;
margin-right: 5px;
}
}
.search {
height: 55px;
padding: 2px 25px;
border-top: 1px solid $darkgrey;
border-bottom: 1px solid $darkgrey;
background: $white;
.input {
display: inline-block;
vertical-align: top;
height: 100%;
}
.label {
width: 5%;
line-height: 50px;
font-size: 20px;
text-align: center;
cursor: pointer;
}
.text {
width: 95%;
outline: 0;
padding: 0;
border: 0;
border-radius: 0;
height: 50px;
font-size: 16px;
}
}
.videos {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
padding: 20px 40px;
li {
position: relative;
width: 50%;
text-align: center;
margin: 20px 0;
width: 400px;
height: 400px;
transition: all 0.25s;
&:hover {
opacity: 0.5;
.info {
padding: 50px 15px;
}
}
iframe {
width: 100%;
height: 100%;
}
.info {
position: absolute;
bottom: 0;
width: calc(100% - 30px);
padding: 15px;
background: $darkgrey;
cursor: pointer;
transition: all 0.25s;
text-align: left;
line-height: 1.5;
}
}
}

10
app/routes/help/containers/HelpContainer.js

@ -0,0 +1,10 @@
import { withRouter } from 'react-router'
import { connect } from 'react-redux'
import Help from '../components/Help'
const mapDispatchToProps = {}
const mapStateToProps = () => ({})
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Help))

3
app/routes/help/index.js

@ -0,0 +1,3 @@
import HelpContainer from './containers/HelpContainer'
export default HelpContainer

7
package.json

@ -1,7 +1,7 @@
{
"name": "zap-desktop",
"productName": "ZapDesktop",
"version": "0.0.1",
"version": "0.1.0",
"description": "desktop application for the lightning network",
"scripts": {
"build": "concurrently \"npm run build-main\" \"npm run build-renderer\"",
@ -80,7 +80,10 @@
"output": "release"
},
"extraResources": [
"**/resources/bin/darwin/lnd"
{
"from": "./resources/bin/darwin/lnd",
"to": "./bin/lnd"
}
]
},
"repository": {

Loading…
Cancel
Save