Browse Source

feature(autopilot-onboarding): allow user to turn autopilot on/off before starting their node

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
2d1030a1f7
  1. 42
      app/components/Onboarding/Autopilot.js
  2. 53
      app/components/Onboarding/Autopilot.scss
  3. 7
      app/components/Onboarding/FormContainer.js
  4. 2
      app/components/Onboarding/FormContainer.scss
  5. 21
      app/components/Onboarding/Onboarding.js
  6. 12
      app/containers/Root.js
  7. 36
      app/main.dev.js
  8. 20
      app/reducers/onboarding.js

42
app/components/Onboarding/Autopilot.js

@ -0,0 +1,42 @@
import React from 'react'
import PropTypes from 'prop-types'
import { FaCircle, FaCircleThin } from 'react-icons/lib/fa'
import styles from './Autopilot.scss'
const Autopilot = ({ autopilot, setAutopilot }) => (
<div className={styles.container}>
<section className={`${styles.enable} ${autopilot && styles.active}`}>
<div onClick={() => setAutopilot(true)}>
{
autopilot ?
<FaCircle />
:
<FaCircleThin />
}
<span className={styles.label}>
Enable Autopilot
</span>
</div>
</section>
<section className={`${styles.disable} ${(!autopilot && autopilot !== null) && styles.active}`}>
<div onClick={() => setAutopilot(false)}>
{
!autopilot && autopilot !== null ?
<FaCircle />
:
<FaCircleThin />
}
<span className={styles.label}>
Disable Autopilot
</span>
</div>
</section>
</div>
)
Autopilot.propTypes = {
autopilot: PropTypes.bool,
setAutopilot: PropTypes.func.isRequired
}
export default Autopilot

53
app/components/Onboarding/Autopilot.scss

@ -0,0 +1,53 @@
@import '../../variables.scss';
.container {
color: $white;
section {
margin: 20px 0;
&.enable {
&.active {
div {
color: $green;
border-color: $green;
}
}
div:hover {
color: $green;
border-color: $green;
}
}
&.disable {
&.active {
div {
color: $red;
border-color: $red;
}
}
div:hover {
color: $red;
border-color: $red;
}
}
div {
width: 150px;
text-align: center;
display: inline-block;
padding: 20px;
border: 1px solid $white;
border-radius: 5px;
font-weight: 200;
cursor: pointer;
transition: all 0.25s;
}
.label {
margin-left: 15px;
}
}
}

7
app/components/Onboarding/FormContainer.js

@ -1,6 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import { FaAngleLeft, FaAngleRight } from 'react-icons/lib/fa'
import zapLogo from 'icons/zap_logo.svg' import zapLogo from 'icons/zap_logo.svg'
import styles from './FormContainer.scss' import styles from './FormContainer.scss'
@ -28,12 +31,12 @@ const FormContainer = ({ title, description, back, next, children }) => (
<div className={styles.buttonsContainer}> <div className={styles.buttonsContainer}>
<section> <section>
{ {
back && <div onClick={back}>Back</div> back && <div onClick={back}><FaAngleLeft style={{ verticalAlign: 'top' }} /> Back</div>
} }
</section> </section>
<section> <section>
{ {
next && <div onClick={next}>Next</div> next && <div onClick={next}>Next <FaAngleRight style={{ verticalAlign: 'top' }} /></div>
} }
</section> </section>
</div> </div>

2
app/components/Onboarding/FormContainer.scss

@ -32,6 +32,8 @@
p { p {
font-size: 12px; font-size: 12px;
line-height: 1.5;
width: 70%;
} }
} }

21
app/components/Onboarding/Onboarding.js

@ -5,15 +5,19 @@ import LoadingBolt from 'components/LoadingBolt'
import FormContainer from './FormContainer' import FormContainer from './FormContainer'
import Alias from './Alias' import Alias from './Alias'
import Autopilot from './Autopilot'
import styles from './Onboarding.scss' import styles from './Onboarding.scss'
const Onboarding = ({ const Onboarding = ({
onboarding: { onboarding: {
step, step,
alias alias,
autopilot
}, },
changeStep,
submit, submit,
aliasProps aliasProps,
autopilotProps
}) => { }) => {
const renderStep = () => { const renderStep = () => {
switch (step) { switch (step) {
@ -23,11 +27,22 @@ const Onboarding = ({
title={'1. What should we call you?'} title={'1. What should we call you?'}
description={'Set your nickname to help others connect with you on the Lightning Network'} description={'Set your nickname to help others connect with you on the Lightning Network'}
back={null} back={null}
next={() => submit(alias)} next={() => changeStep(2)}
> >
<Alias {...aliasProps} /> <Alias {...aliasProps} />
</FormContainer> </FormContainer>
) )
case 2:
return (
<FormContainer
title={'2. Autopilot'}
description={'Autopilot is an automatic network manager. Instead of manually adding people to build your network to make payments, enable autopilot to automatically connect you to the Lightning Network using 60% of your balance.'}
back={() => changeStep(1)}
next={() => submit(alias, autopilot)}
>
<Autopilot {...autopilotProps} />
</FormContainer>
)
default: default:
return <LoadingBolt /> return <LoadingBolt />
} }

12
app/containers/Root.js

@ -7,12 +7,13 @@ import PropTypes from 'prop-types'
import LoadingBolt from '../components/LoadingBolt' import LoadingBolt from '../components/LoadingBolt'
import Onboarding from '../components/Onboarding' import Onboarding from '../components/Onboarding'
import Syncing from '../components/Onboarding/Syncing' import Syncing from '../components/Onboarding/Syncing'
import { updateAlias, changeStep, submit } from '../reducers/onboarding' import { updateAlias, setAutopilot, changeStep, submit } from '../reducers/onboarding'
import { fetchBlockHeight, lndSelectors } from '../reducers/lnd' import { fetchBlockHeight, lndSelectors } from '../reducers/lnd'
import Routes from '../routes' import Routes from '../routes'
const mapDispatchToProps = { const mapDispatchToProps = {
updateAlias, updateAlias,
setAutopilot,
changeStep, changeStep,
submit, submit,
@ -37,10 +38,17 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
alias: stateProps.onboarding.alias alias: stateProps.onboarding.alias
} }
const autopilotProps = {
autopilot: stateProps.onboarding.autopilot,
setAutopilot: dispatchProps.setAutopilot
}
const onboardingProps = { const onboardingProps = {
onboarding: stateProps.onboarding, onboarding: stateProps.onboarding,
changeStep: dispatchProps.changeStep,
submit: dispatchProps.submit, submit: dispatchProps.submit,
aliasProps aliasProps,
autopilotProps
} }
return { return {

36
app/main.dev.js

@ -139,7 +139,7 @@ const sendLndSynced = () => {
} }
// Starts the LND node // Starts the LND node
const startLnd = (alias) => { const startLnd = (alias, autopilot) => {
let lndPath let lndPath
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
@ -148,21 +148,21 @@ const startLnd = (alias) => {
lndPath = path.join(__dirname, '..', 'bin', plat === 'win32' ? 'lnd.exe' : 'lnd') lndPath = path.join(__dirname, '..', 'bin', plat === 'win32' ? 'lnd.exe' : 'lnd')
} }
const neutrino = spawn(lndPath, const neutrinoArgs = [
[ '--bitcoin.active',
'--bitcoin.active', '--bitcoin.testnet',
'--bitcoin.testnet', '--bitcoin.node=neutrino',
'--bitcoin.node=neutrino', '--neutrino.connect=btcd.jackmallers.com:18333',
'--neutrino.connect=btcd.jackmallers.com:18333', '--neutrino.addpeer=188.166.148.62:18333',
'--neutrino.addpeer=188.166.148.62:18333', '--neutrino.addpeer=159.65.48.139:18333',
'--neutrino.addpeer=159.65.48.139:18333', '--neutrino.connect=127.0.0.1:18333',
'--neutrino.connect=127.0.0.1:18333', '--debuglevel=debug',
'--autopilot.active', '--noencryptwallet',
'--debuglevel=debug', `${ autopilot ? '--autopilot.active' : ''}`,
'--noencryptwallet', `${alias ? `--alias=${alias}` : ''}`
`--alias=${alias}` ]
]
) const neutrino = spawn(lndPath, neutrinoArgs)
.on('error', error => console.log(`lnd error: ${error}`)) .on('error', error => console.log(`lnd error: ${error}`))
.on('close', code => console.log(`lnd shutting down ${code}`)) .on('close', code => console.log(`lnd shutting down ${code}`))
@ -284,9 +284,9 @@ app.on('ready', async () => {
// Start LND // Start LND
// startLnd() // startLnd()
// once the onboarding has finished we wanna let the application we have started syncing and start LND // once the onboarding has finished we wanna let the application we have started syncing and start LND
ipcMain.on('onboardingFinished', (event, { alias }) => { ipcMain.on('onboardingFinished', (event, { alias, autopilot }) => {
sendLndSyncing() sendLndSyncing()
startLnd(alias) startLnd(alias, autopilot)
}) })
} else { } else {
// An LND process was found, no need to start our own // An LND process was found, no need to start our own

20
app/reducers/onboarding.js

@ -7,6 +7,8 @@ export const UPDATE_ALIAS = 'UPDATE_ALIAS'
export const CHANGE_STEP = 'CHANGE_STEP' export const CHANGE_STEP = 'CHANGE_STEP'
export const SET_AUTOPILOT = 'SET_AUTOPILOT'
export const ONBOARDING_STARTED = 'ONBOARDING_STARTED' export const ONBOARDING_STARTED = 'ONBOARDING_STARTED'
export const ONBOARDING_FINISHED = 'ONBOARDING_FINISHED' export const ONBOARDING_FINISHED = 'ONBOARDING_FINISHED'
@ -20,6 +22,13 @@ export function updateAlias(alias) {
} }
} }
export function setAutopilot(autopilot) {
return {
type: SET_AUTOPILOT,
autopilot
}
}
export function changeStep(step) { export function changeStep(step) {
return { return {
type: CHANGE_STEP, type: CHANGE_STEP,
@ -27,9 +36,10 @@ export function changeStep(step) {
} }
} }
export function submit(alias) { export function submit(alias, autopilot) {
// alert the app we're done onboarding and it's cool to start LND // alert the app we're done onboarding and it's cool to start LND
ipcRenderer.send('onboardingFinished', { alias }) // send the alias they set along with whether they want autopilot on or not
ipcRenderer.send('onboardingFinished', { alias, autopilot })
return { return {
type: ONBOARDING_FINISHED type: ONBOARDING_FINISHED
@ -45,6 +55,7 @@ export const startOnboarding = () => (dispatch) => {
// ------------------------------------ // ------------------------------------
const ACTION_HANDLERS = { const ACTION_HANDLERS = {
[UPDATE_ALIAS]: (state, { alias }) => ({ ...state, alias }), [UPDATE_ALIAS]: (state, { alias }) => ({ ...state, alias }),
[SET_AUTOPILOT]: (state, { autopilot }) => ({ ...state, autopilot }),
[CHANGE_STEP]: (state, { step }) => ({ ...state, step }), [CHANGE_STEP]: (state, { step }) => ({ ...state, step }),
[ONBOARDING_STARTED]: state => ({ ...state, onboarded: false }), [ONBOARDING_STARTED]: state => ({ ...state, onboarded: false }),
[ONBOARDING_FINISHED]: state => ({ ...state, onboarded: true }) [ONBOARDING_FINISHED]: state => ({ ...state, onboarded: true })
@ -56,13 +67,14 @@ const ACTION_HANDLERS = {
const initialState = { const initialState = {
onboarded: true, onboarded: true,
step: 1, step: 1,
alias: '' alias: '',
autopilot: null
} }
// ------------------------------------ // ------------------------------------
// Reducer // Reducer
// ------------------------------------ // ------------------------------------
export default function lndReducer(state = initialState, action) { export default function onboardingReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type] const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state return handler ? handler(state, action) : state

Loading…
Cancel
Save