Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.

Commit 450f1b0

Browse files
authored
Merge pull request #430 from lightninglabs/loader-syncing
Implement loader - syncing chain screen
2 parents c7c1679 + edd570d commit 450f1b0

File tree

8 files changed

+200
-21
lines changed

8 files changed

+200
-21
lines changed

src/component/spinner.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,10 @@ export const SmallSpinner = ({ ...props }) => (
3434
// Load Network Spinner
3535
//
3636

37-
const sizeM = 80;
38-
const progressWidthM = 3;
37+
const size = 80;
38+
const progressWidth = 3;
3939

4040
const loadNetworkStyles = StyleSheet.create({
41-
spinner: {
42-
margin: 20,
43-
},
4441
bolt: {
4542
height: 126 / 4.5,
4643
width: 64 / 4.5,
@@ -53,12 +50,12 @@ const loadNetworkStyles = StyleSheet.create({
5350
},
5451
});
5552

56-
export const LoadNetworkSpinner = ({ percentage, msg }) => (
57-
<View style={loadNetworkStyles.spinner}>
53+
export const LoadNetworkSpinner = ({ percentage, msg, style }) => (
54+
<View style={style}>
5855
<ResizeableSpinner
5956
percentage={percentage}
60-
size={sizeM}
61-
progressWidth={progressWidthM}
57+
size={size}
58+
progressWidth={progressWidth}
6259
gradient="loadNetworkGrad"
6360
icon="lightning-bolt"
6461
iconStyles={loadNetworkStyles.bolt}
@@ -70,6 +67,7 @@ export const LoadNetworkSpinner = ({ percentage, msg }) => (
7067
LoadNetworkSpinner.propTypes = {
7168
percentage: PropTypes.number.isRequired,
7269
msg: PropTypes.string.isRequired,
70+
style: ViewPropTypes.style,
7371
};
7472

7573
//
@@ -88,7 +86,7 @@ const resizeableStyles = StyleSheet.create({
8886
},
8987
});
9088

91-
const ResizeableSpinner = ({
89+
export const ResizeableSpinner = ({
9290
percentage,
9391
size,
9492
gradient,
@@ -140,7 +138,7 @@ const Gradients = () => (
140138
<Stop offset="100%" stopColor={color.purple} />
141139
</LinearGradient>
142140
<LinearGradient id="openChannelsGrad" x1="0" y1="0" x2="1" y2="1">
143-
<Stop offset="0%" stopColor={color.openChansLightPurple} />
141+
<Stop offset="0%" stopColor={color.lightPurple} />
144142
<Stop offset="50%" stopColor={color.openChansDarkPurple} />
145143
</LinearGradient>
146144
</Defs>
@@ -187,11 +185,11 @@ SpinnerFill.propTypes = {
187185

188186
const generateArc = (percentage, radius) => {
189187
if (percentage === 0) {
190-
percentage = 1;
191-
} else if (percentage === 100) {
192-
percentage = 99.999;
188+
percentage = 0.001;
189+
} else if (percentage === 1) {
190+
percentage = 0.999;
193191
}
194-
const a = percentage * 2 * Math.PI / 100; // angle (in radian) depends on percentage
192+
const a = percentage * 2 * Math.PI; // angle (in radian) depends on percentage
195193
const r = radius; // radius of the circle
196194
var rx = r,
197195
ry = r,
@@ -200,7 +198,7 @@ const generateArc = (percentage, radius) => {
200198
sweepFlag = 1,
201199
x = r + r * Math.sin(a),
202200
y = r - r * Math.cos(a);
203-
if (percentage <= 50) {
201+
if (percentage <= 0.5) {
204202
largeArcFlag = 0;
205203
} else {
206204
largeArcFlag = 1;

src/component/style.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export const color = {
1414
loadNetworkLightPurple: '#A95BDC',
1515
loadNetworkMedPurple: '#651399',
1616
loadNetworkMedDarkPurple: '#610F96',
17-
openChansLightPurple: '#A540CD',
1817
openChansDarkPurple: '#6B249C',
1918
orange: '#F66B1C',
2019
blackDark: '#252F4A',

src/computed/loader-msg.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { computed, extendObservable } from 'mobx';
2+
3+
const ComputedLoaderMsg = store => {
4+
extendObservable(store, {
5+
loadingMsg: computed(() => {
6+
const { percentSynced: percent } = store;
7+
return getLoadingMsg(percent);
8+
}),
9+
});
10+
};
11+
12+
export const LOADING_COPY_START = 'Loading network...';
13+
export const LOADING_COPY_MID = 'Almost done...';
14+
export const LOADING_COPY_END = 'Just a few seconds...';
15+
export const LOADING_PERCENT_MID = 0.5;
16+
export const LOADING_PERCENT_END = 0.95;
17+
18+
/**
19+
* Retrieve the loading message corresponding to the percent
20+
* @param {number} percent The percentage the network is synced.
21+
* @return {string} The message corresponding to the percent.
22+
*/
23+
const getLoadingMsg = percent => {
24+
percent = Number(percent);
25+
if (isNaN(percent)) {
26+
percent = 0;
27+
} else if (percent < 0) {
28+
percent = 0;
29+
} else if (percent > 1) {
30+
percent = 1;
31+
}
32+
if (percent < LOADING_PERCENT_MID) {
33+
return LOADING_COPY_START;
34+
} else if (percent < LOADING_PERCENT_END) {
35+
return LOADING_COPY_MID;
36+
} else {
37+
return LOADING_COPY_END;
38+
}
39+
};
40+
41+
export default ComputedLoaderMsg;

src/store.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { extendObservable } from 'mobx';
2+
import ComputedLoaderMsg from './computed/loader-msg';
23
import ComputedWallet from './computed/wallet';
34
import ComputedTransaction from './computed/transaction';
45
import ComputedChannel from './computed/channel';
@@ -17,6 +18,7 @@ export class Store {
1718
walletUnlocked: false, // Is the wallet unlocked
1819
lndReady: false, // Is lnd process running
1920
syncedToChain: false, // Is lnd synced to blockchain
21+
percentSynced: 0, // Expects 0-1 range
2022
route: DEFAULT_ROUTE,
2123
blockHeight: null,
2224
balanceSatoshis: 0,
@@ -72,6 +74,7 @@ export class Store {
7274
}
7375

7476
init() {
77+
ComputedLoaderMsg(this);
7578
ComputedWallet(this);
7679
ComputedTransaction(this);
7780
ComputedChannel(this);

src/view/loader-syncing.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react';
2+
import { StyleSheet, View } from 'react-native';
3+
import PropTypes from 'prop-types';
4+
import Background from '../component/background';
5+
import { H1Text, CopyText } from '../component/text';
6+
import MainContent from '../component/main-content';
7+
import { LoadNetworkSpinner } from '../component/spinner';
8+
import { DownButton } from '../component/button';
9+
import { color } from '../component/style';
10+
11+
const styles = StyleSheet.create({
12+
spinner: {
13+
marginTop: 40,
14+
},
15+
downBtn: {
16+
margin: 25,
17+
},
18+
});
19+
20+
const LoaderSyncingView = ({ store }) => (
21+
<Background color={color.blackDark}>
22+
<MainContent>
23+
<LoadNetworkSpinner
24+
percentage={store.percentSynced}
25+
msg={store.loadingMsg}
26+
style={styles.spinner}
27+
/>
28+
<CopySection />
29+
<DownButton onPress={() => {}} style={styles.downBtn}>
30+
Learn More
31+
</DownButton>
32+
</MainContent>
33+
</Background>
34+
);
35+
36+
LoaderSyncingView.propTypes = {
37+
store: PropTypes.object.isRequired,
38+
};
39+
40+
//
41+
// Copy Section
42+
//
43+
44+
const copyStyles = StyleSheet.create({
45+
wrapper: {
46+
flex: 1,
47+
justifyContent: 'center',
48+
alignItems: 'center',
49+
},
50+
title: {
51+
textAlign: 'center',
52+
marginTop: 30,
53+
},
54+
copyTxt: {
55+
textAlign: 'center',
56+
marginTop: 10,
57+
maxWidth: 450,
58+
paddingBottom: 30,
59+
},
60+
});
61+
62+
const CopySection = () => (
63+
<View style={copyStyles.wrapper}>
64+
<H1Text style={copyStyles.title}>Almost there</H1Text>
65+
<CopyText style={copyStyles.copyTxt}>
66+
{
67+
"Why not learn more about what we're doing at Lightning Labs? Or grab a coffee. This could take about 30 minutes."
68+
}
69+
</CopyText>
70+
</View>
71+
);
72+
73+
export default LoaderSyncingView;

stories/component/spinner.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { storiesOf } from '@storybook/react';
33
import MainContent from '../../src/component/main-content';
4-
import { LoadNetworkSpinner, SmallSpinner } from '../../src/component/spinner';
4+
import { SmallSpinner, LoadNetworkSpinner } from '../../src/component/spinner';
55
import { color } from '../../src/component/style';
66
import Background from '../../src/component/background';
77

@@ -17,8 +17,20 @@ storiesOf('Spinner', module)
1717
))
1818
.add('Load Network Spinner', () => (
1919
<MainContent style={{ alignItems: 'flex-start', flexDirection: 'row' }}>
20-
<LoadNetworkSpinner percentage={30} msg="Loading network..." />
21-
<LoadNetworkSpinner percentage={50} msg="Almost done..." />
22-
<LoadNetworkSpinner percentage={100} msg="Just a few seconds..." />
20+
<LoadNetworkSpinner
21+
percentage={0.3}
22+
msg="Loading network..."
23+
style={{ margin: 20 }}
24+
/>
25+
<LoadNetworkSpinner
26+
percentage={0.5}
27+
msg="Almost done..."
28+
style={{ margin: 20 }}
29+
/>
30+
<LoadNetworkSpinner
31+
percentage={1}
32+
msg="Just a few seconds..."
33+
style={{ margin: 20 }}
34+
/>
2335
</MainContent>
2436
));

stories/screen.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import PayBitcoinConfirm from '../src/view/pay-bitcoin-confirm';
3838
import PayBitcoinDone from '../src/view/pay-bitcoin-done';
3939
import NoRoute from '../src/view/no-route';
4040
import Loader from '../src/view/loader';
41+
import LoaderSyncing from '../src/view/loader-syncing';
4142
import SeedSuccess from '../src/view/seed-success';
4243
import Seed from '../src/view/seed';
4344
import SeedVerify from '../src/view/seed-verify';
@@ -93,6 +94,7 @@ storiesOf('Screens', module)
9394
<NewAddress store={store} nav={nav} invoice={invoice} />
9495
))
9596
.add('Wait', () => <Wait />)
97+
.add('Loader - Syncing Chain', () => <LoaderSyncing store={store} />)
9698
.add('Home', () => (
9799
<Home
98100
store={store}
@@ -220,6 +222,7 @@ store.pendingChannels = [...Array(6)].map((x, i) => ({
220222
status: i % 2 === 0 ? 'pending-closing' : 'pending-open',
221223
}));
222224
store.selectedChannel = store.computedChannels && store.computedChannels[0];
225+
store.percentSynced = 0.3;
223226
store.seedMnemonic = [
224227
'empower',
225228
'neglect',
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { observable, useStrict } from 'mobx';
2+
import ComputedLoaderMsg from '../../../src/computed/loader-msg';
3+
import {
4+
LOADING_COPY_START,
5+
LOADING_COPY_MID,
6+
LOADING_COPY_END,
7+
LOADING_PERCENT_MID,
8+
LOADING_PERCENT_END,
9+
} from '../../../src/computed/loader-msg';
10+
11+
describe('Computed Loader Msg Unit Tests', () => {
12+
let store;
13+
14+
beforeEach(() => {
15+
useStrict(false);
16+
store = observable({
17+
percentSynced: 0,
18+
});
19+
});
20+
21+
// TODO: figure out how error handling will work on network error
22+
describe('ComputedLoaderMsg()', () => {
23+
it('should work with non-numerical values', () => {
24+
store.percentSynced = null;
25+
ComputedLoaderMsg(store);
26+
expect(store.loadingMsg, 'to equal', LOADING_COPY_START);
27+
});
28+
29+
it('should work for < 0 and > 1 percentages', () => {
30+
store.percentSynced = -1;
31+
ComputedLoaderMsg(store);
32+
expect(store.loadingMsg, 'to equal', LOADING_COPY_START);
33+
store.percentSynced = 1.01;
34+
ComputedLoaderMsg(store);
35+
expect(store.loadingMsg, 'to equal', LOADING_COPY_END);
36+
});
37+
38+
it('should work for each milestone percentage', () => {
39+
store.percentSynced = 0.1;
40+
ComputedLoaderMsg(store);
41+
expect(store.loadingMsg, 'to equal', LOADING_COPY_START);
42+
store.percentSynced = LOADING_PERCENT_MID;
43+
ComputedLoaderMsg(store);
44+
expect(store.loadingMsg, 'to equal', LOADING_COPY_MID);
45+
store.percentSynced = LOADING_PERCENT_END;
46+
ComputedLoaderMsg(store);
47+
expect(store.loadingMsg, 'to equal', LOADING_COPY_END);
48+
});
49+
});
50+
});

0 commit comments

Comments
 (0)