Browse Source

fix(styles): clean up and standardize buttons

Implement Button component throughout the app.

Fix #830
renovate/lint-staged-8.x
Tom Kirkpatrick 6 years ago
committed by Tom Kirkpatrick
parent
commit
06b1d27e64
No known key found for this signature in database GPG Key ID: 72203A8EC5967EA8
  1. 11
      app/components/Activity/Activity.js
  2. 19
      app/components/Activity/Activity.scss
  3. 6
      app/components/App/App.js
  4. 7
      app/components/Contacts/AddChannel/AddChannel.js
  5. 13
      app/components/Contacts/AddChannel/AddChannel.scss
  6. 8
      app/components/Contacts/ConnectManually/ConnectManually.js
  7. 22
      app/components/Contacts/ConnectManually/ConnectManually.scss
  8. 8
      app/components/Contacts/SubmitChannelForm/SubmitChannelForm.js
  9. 21
      app/components/Contacts/SubmitChannelForm/SubmitChannelForm.scss
  10. 8
      app/components/Form/Pay/Pay.js
  11. 22
      app/components/Form/Pay/Pay.scss
  12. 8
      app/components/Form/Request/Request.js
  13. 22
      app/components/Form/Request/Request.scss
  14. 16
      app/components/Onboarding/FormContainer/FormContainer.js
  15. 28
      app/components/Onboarding/FormContainer/FormContainer.scss
  16. 29
      app/components/Onboarding/Login/Login.js
  17. 70
      app/components/Onboarding/Login/Login.scss
  18. 3
      app/components/Onboarding/Login/messages.js
  19. 35
      app/components/Settings/Theme/Theme.js
  20. 9
      app/components/Wallet/Wallet.js
  21. 22
      app/components/Wallet/Wallet.scss
  22. 12
      app/containers/Activity.js
  23. 2
      app/containers/App.js
  24. 72
      app/containers/Root.js
  25. 5
      app/index.js
  26. 4
      app/lib/lnd/subscribe/channelgraph.js
  27. 3
      app/reducers/index.js
  28. 23
      app/reducers/settings.js
  29. 67
      app/reducers/theme.js
  30. 90
      app/styles/app.global.scss
  31. 5
      app/translations/en.json
  32. 10
      test/unit/components/Form/Pay.spec.js
  33. 4
      test/unit/reducers/__snapshots__/settings.spec.js.snap

11
app/components/Activity/Activity.js

@ -6,7 +6,8 @@ import xIcon from 'icons/x.svg'
import FaRepeat from 'react-icons/lib/fa/repeat'
import { FormattedMessage, injectIntl } from 'react-intl'
import { Flex } from 'rebass'
import Button from 'components/UI/Button'
import Wallet from 'components/Wallet'
import Invoice from './Invoice'
import Payment from './Payment'
@ -217,15 +218,15 @@ class Activity extends Component {
))}
{showExpiredToggle &&
currentActivity.length > 0 && (
<li>
<div className={styles.toggleExpired} onClick={toggleExpiredRequests}>
<Flex justifyContent="center">
<Button onClick={toggleExpiredRequests} mx="auto">
{showExpiredRequests ? (
<FormattedMessage {...messages.hide_expired} />
) : (
<FormattedMessage {...messages.show_expired} />
)}
</div>
</li>
</Button>
</Flex>
)}
</ul>
</div>

19
app/components/Activity/Activity.scss

@ -140,25 +140,6 @@
}
}
.toggleExpired {
margin: 0 auto;
font-size: 14px;
font-weight: bold;
color: var(--primaryText);
background: var(--lightBackground);
padding: 10px 7.5px;
width: 200px;
text-align: center;
border-radius: 5px;
cursor: pointer;
opacity: 1;
transition: all 0.25s;
&:hover {
opacity: 0.5;
}
}
.activity {
position: relative;
padding: 0 60px;

6
app/components/App/App.js

@ -26,6 +26,7 @@ class App extends Component {
render() {
const {
currentTheme,
currentTicker,
form,
@ -41,8 +42,6 @@ class App extends Component {
activityModalProps,
channelFormProps,
settings,
children
} = this.props
@ -51,7 +50,7 @@ class App extends Component {
}
return (
<div className={`${settings.theme}`}>
<div className={`${currentTheme}`}>
<div className={styles.titleBar} />
<GlobalError error={error} clearError={clearError} />
@ -79,6 +78,7 @@ App.propTypes = {
formProps: PropTypes.object.isRequired,
closeForm: PropTypes.func.isRequired,
error: PropTypes.object.isRequired,
currentTheme: PropTypes.string.isRequired,
currentTicker: PropTypes.object,
contactsFormProps: PropTypes.object,
networkTabProps: PropTypes.object,

7
app/components/Contacts/AddChannel/AddChannel.js

@ -5,8 +5,8 @@ import Isvg from 'react-inlinesvg'
import x from 'icons/x.svg'
import { FormattedMessage } from 'react-intl'
import Button from 'components/UI/Button'
import messages from './messages'
import styles from './AddChannel.scss'
const AddChannel = ({
@ -145,9 +145,10 @@ const AddChannel = ({
<p>
<FormattedMessage {...messages.manual_description} />
</p>
<div className={styles.manualConnectButton} onClick={openManualForm}>
<Button onClick={openManualForm} variant="primary" width={1}>
<FormattedMessage {...messages.manual_button} />
</div>
</Button>
</section>
)}
</div>

13
app/components/Contacts/AddChannel/AddChannel.scss

@ -125,17 +125,4 @@
font-size: 14px;
margin: 20px 0;
}
div {
background: var(--lightningOrange);
font-size: 16px;
padding: 10px;
cursor: pointer;
transition: all 0.25s;
border-radius: 5px;
&:hover {
opacity: 0.75;
}
}
}

8
app/components/Contacts/ConnectManually/ConnectManually.js

@ -2,6 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import Button from 'components/UI/Button'
import messages from './messages'
import styles from './ConnectManually.scss'
@ -81,12 +82,9 @@ class ConnectManually extends React.Component {
</section>
<section className={styles.submit}>
<div
className={`${styles.button} ${manualFormIsValid.isValid ? styles.active : undefined}`}
onClick={formSubmitted}
>
<Button disabled={!manualFormIsValid.isValid} onClick={formSubmitted} size="large">
<FormattedMessage {...messages.submit} />
</div>
</Button>
</section>
</div>
)

22
app/components/Contacts/ConnectManually/ConnectManually.scss

@ -100,26 +100,4 @@
.submit {
margin-top: 50px;
text-align: center;
.button {
width: 235px;
margin: 0 auto;
padding: 20px 10px;
background: #31343f;
opacity: 0.5;
cursor: pointer;
transition: 0.25s all;
&.active {
background: var(--lightningOrange);
color: var(--white);
font-weight: bold;
opacity: 1;
transition: all 0.25s;
&:hover {
opacity: 0.75;
}
}
}
}

8
app/components/Contacts/SubmitChannelForm/SubmitChannelForm.js

@ -5,6 +5,7 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import FaExclamationCircle from 'react-icons/lib/fa/exclamation-circle'
import AmountInput from 'components/AmountInput'
import Button from 'components/UI/Button'
import { FormattedNumber, FormattedMessage } from 'react-intl'
import messages from './messages'
@ -155,12 +156,9 @@ class SubmitChannelForm extends React.Component {
</section>
<section className={styles.submit}>
<div
className={`${styles.button} ${contactCapacity > 0 ? styles.active : undefined}`}
onClick={formSubmitted}
>
<Button disabled={!(contactCapacity > 0)} onClick={formSubmitted} size="large">
<FormattedMessage {...messages.submit} />
</div>
</Button>
</section>
</div>
)

21
app/components/Contacts/SubmitChannelForm/SubmitChannelForm.scss

@ -145,25 +145,4 @@
.submit {
margin-top: 50px;
text-align: center;
.button {
width: 235px;
margin: 0 auto;
padding: 20px 10px;
background: var(--lightBackground);
opacity: 0.5;
cursor: pointer;
transition: 0.25s all;
&.active {
background: var(--lightningOrange);
color: var(--white);
font-weight: bold;
opacity: 1;
&:hover {
opacity: 0.5;
}
}
}
}

8
app/components/Form/Pay/Pay.js

@ -8,6 +8,7 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import { btc } from 'lib/utils'
import AmountInput from 'components/AmountInput'
import Button from 'components/UI/Button'
import { FormattedNumber, FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
@ -203,12 +204,9 @@ class Pay extends Component {
</section>
<section className={styles.submit}>
<div
className={`${styles.button} ${isValid ? styles.active : undefined}`}
onClick={onPaySubmit}
>
<Button disabled={!isValid} onClick={onPaySubmit} size="large" width={200}>
<FormattedMessage {...messages.pay} />
</div>
</Button>
</section>
</div>
</div>

22
app/components/Form/Pay/Pay.scss

@ -155,28 +155,6 @@
.submit {
margin-top: 20px;
text-align: center;
.button {
width: 200px;
margin: 0 auto;
padding: 15px 7.5px;
background: var(--lightBackground);
border-radius: 5px;
opacity: 0.5;
cursor: pointer;
transition: 0.25s all;
&.active {
background: var(--lightningOrange);
color: var(--white);
font-weight: bold;
opacity: 1;
&:hover {
// background: darken(var(--lightningOrange), 5%);
}
}
}
}
}

8
app/components/Form/Request/Request.js

@ -7,6 +7,7 @@ import FaAngleDown from 'react-icons/lib/fa/angle-down'
import { btc } from 'lib/utils'
import AmountInput from 'components/AmountInput'
import Button from 'components/UI/Button'
import { FormattedNumber, FormattedMessage, injectIntl } from 'react-intl'
import messages from './messages'
@ -109,12 +110,9 @@ const Request = ({
</section>
<section className={styles.submit}>
<div
className={`${styles.button} ${amount > 0 ? styles.active : undefined}`}
onClick={onRequestSubmit}
>
<Button disabled={!(amount > 0)} onClick={onRequestSubmit} size="large" width={200}>
<FormattedMessage {...messages.request} />
</div>
</Button>
</section>
</div>
</div>

22
app/components/Form/Request/Request.scss

@ -134,27 +134,5 @@
.submit {
margin-top: 50px;
text-align: center;
.button {
width: 200px;
margin: 0 auto;
padding: 15px 7.5px;
background: var(--lightBackground);
border-radius: 5px;
opacity: 0.5;
cursor: pointer;
transition: 0.25s all;
&.active {
background: var(--lightningOrange);
color: var(--white);
font-weight: bold;
opacity: 1;
&:hover {
opacity: 0.75;
}
}
}
}
}

16
app/components/Onboarding/FormContainer/FormContainer.js

@ -5,7 +5,7 @@ import Isvg from 'react-inlinesvg'
import FaAngleLeft from 'react-icons/lib/fa/angle-left'
import FaAngleRight from 'react-icons/lib/fa/angle-right'
import Button from 'components/UI/Button'
import zapLogo from 'icons/zap-logo.svg'
import { FormattedMessage } from 'react-intl'
import zapLogoBlack from 'icons/zap-logo-black.svg'
@ -42,18 +42,18 @@ const FormContainer = ({ title, description, back, next, children, theme }) => (
<div className={styles.buttonsContainer}>
<section>
{back && (
<div onClick={back} className={styles.backButton}>
<FaAngleLeft style={{ verticalAlign: 'top' }} />{' '}
<Button variant="secondary" onClick={back} px={0}>
<FaAngleLeft />
<FormattedMessage {...messages.back} />
</div>
</Button>
)}
</section>
<section>
{next && (
<div onClick={next} className={styles.nextButton}>
<FormattedMessage {...messages.next} />{' '}
<FaAngleRight style={{ verticalAlign: 'top' }} />
</div>
<Button onClick={next}>
<FormattedMessage {...messages.next} />
<FaAngleRight />
</Button>
)}
</section>
</div>

28
app/components/Onboarding/FormContainer/FormContainer.scss

@ -3,7 +3,7 @@
.container {
position: relative;
height: 100vh;
background: var(--darkestBackground);
background: var(--lightBackground);
}
.titleBar {
@ -51,7 +51,7 @@
.content {
position: relative;
background: var(--lightBackground);
background: var(--darkestBackground);
height: 100vh;
padding: 40px 40px;
}
@ -67,29 +67,5 @@
display: flex;
flex-direction: row;
justify-content: space-between;
.nextButton {
cursor: pointer;
transition: all 0.25s;
background: var(--lightningOrange);
padding: 8px 20px 8px 30px;
text-align: center;
border-radius: 5px;
&:hover {
opacity: 0.5;
}
}
.backButton {
cursor: pointer;
transition: all 0.25s;
padding: 8px 20px 8px 0;
text-align: center;
&:hover {
opacity: 0.5;
}
}
}
}

29
app/components/Onboarding/Login/Login.js

@ -1,11 +1,13 @@
import React from 'react'
import PropTypes from 'prop-types'
import { FormattedMessage, injectIntl } from 'react-intl'
import Button from 'components/UI/Button'
import messages from './messages'
import styles from './Login.scss'
const Login = ({
password,
passwordIsValid,
updatePassword,
unlockingWallet,
unlockWallet,
@ -31,26 +33,25 @@ const Login = ({
</p>
<section className={styles.buttons}>
<div>
<span className={styles.button}>
<span
className={`${!unlockingWallet ? styles.active : undefined} ${styles.button}`}
onClick={() => unlockWallet(password)}
>
{unlockingWallet ? (
<i className={styles.spinner} />
) : (
<FormattedMessage {...messages.unlock} />
)}
</span>
</span>
</div>
<Button
disabled={!passwordIsValid || unlockingWallet}
onClick={() => unlockWallet(password)}
processing={unlockingWallet}
size="large"
>
{unlockingWallet ? (
<FormattedMessage {...messages.unlocking} />
) : (
<FormattedMessage {...messages.unlock} />
)}
</Button>
</section>
</div>
)
Login.propTypes = {
password: PropTypes.string.isRequired,
passwordIsValid: PropTypes.bool.isRequired,
updatePassword: PropTypes.func.isRequired,
unlockingWallet: PropTypes.bool.isRequired,
unlockWallet: PropTypes.func.isRequired,

70
app/components/Onboarding/Login/Login.scss

@ -27,6 +27,7 @@
.error {
margin-top: 20px;
height: 20px;
color: $red;
visibility: hidden;
font-size: 12px;
@ -40,73 +41,4 @@
.buttons {
margin-top: 15%;
text-align: center;
div {
color: var(--primaryText);
text-align: center;
margin-bottom: 40px;
.button {
padding: 15px 35px;
background: var(--lightningOrange);
font-size: 14px;
transition: all 0.25s;
border-radius: 5px;
&.button {
position: relative;
}
&.active {
opacity: 1;
cursor: pointer;
&:hover {
opacity: 0.5;
}
}
}
}
}
.spinner {
height: 20px;
width: 20px;
border: 1px solid rgba(235, 184, 100, 0.1);
border-left-color: rgba(235, 184, 100, 0.4);
-webkit-border-radius: 999px;
-moz-border-radius: 999px;
border-radius: 999px;
-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;
display: inline-block;
position: absolute;
top: calc(50% - 10px);
left: calc(50% - 10px);
}
@-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);
}
}

3
app/components/Onboarding/Login/messages.js

@ -3,5 +3,6 @@ import { defineMessages } from 'react-intl'
/* eslint-disable max-len */
export default defineMessages({
password_placeholder: 'Password',
unlock: 'Unlock'
unlock: 'Unlock',
unlocking: 'Unlocking'
})

35
app/components/Settings/Theme/Theme.js

@ -9,7 +9,7 @@ import messages from './messages'
import styles from './Theme.scss'
const Fiat = ({ theme, disableSubMenu, setTheme }) => (
const Theme = ({ currentTheme, disableSubMenu, setTheme, themes }) => (
<div>
<header className={styles.submenuHeader} onClick={disableSubMenu}>
<FaAngleLeft />
@ -18,26 +18,27 @@ const Fiat = ({ theme, disableSubMenu, setTheme }) => (
</span>
</header>
<ul className={styles.themes}>
<li className={theme === 'dark' ? styles.active : ''} onClick={() => setTheme('dark')}>
<span>
<FormattedMessage {...messages.dark} />
</span>
{theme === 'dark' && <Isvg src={checkIcon} />}
</li>
<li className={theme === 'light' ? styles.active : ''} onClick={() => setTheme('light')}>
<span>
<FormattedMessage {...messages.light} />
</span>
{theme === 'light' && <Isvg src={checkIcon} />}
</li>
{Object.keys(themes).map(theme => {
return (
<li
key={theme}
className={currentTheme === theme ? styles.active : ''}
onClick={() => setTheme(theme)}
>
<FormattedMessage {...messages[theme]} />
{currentTheme === theme && <Isvg src={checkIcon} />}
</li>
)
})}
</ul>
</div>
)
Fiat.propTypes = {
theme: PropTypes.string.isRequired,
Theme.propTypes = {
currentTheme: PropTypes.string.isRequired,
disableSubMenu: PropTypes.func.isRequired,
setTheme: PropTypes.func
setTheme: PropTypes.func,
themes: PropTypes.object.isRequired
}
export default Fiat
export default Theme

9
app/components/Wallet/Wallet.js

@ -8,6 +8,7 @@ import { btc, blockExplorer } from 'lib/utils'
import Value from 'components/Value'
import AnimatedCheckmark from 'components/AnimatedCheckmark'
import Settings from 'components/Settings'
import Button from 'components/UI/Button'
import zapLogo from 'icons/zap-logo.svg'
import zapLogoBlack from 'icons/zap-logo-black.svg'
@ -115,12 +116,12 @@ const Wallet = ({
</div>
<div className={styles.right}>
<div className={styles.rightContent}>
<div className={styles.pay} onClick={openPayForm}>
<Button onClick={openPayForm} variant="primary" my={10} mx={7.5} width={100}>
<FormattedMessage {...messages.pay} />
</div>
<div className={styles.request} onClick={openRequestForm}>
</Button>
<Button onClick={openRequestForm} variant="primary" my={10} mx={7.5} width={100}>
<FormattedMessage {...messages.request} />
</div>
</Button>
</div>
<div className={styles.notificationBox}>
{showPayLoadingScreen && (

22
app/components/Wallet/Wallet.scss

@ -173,28 +173,6 @@
flex-direction: row;
justify-content: flex-end;
align-items: right;
.pay,
.request {
font-size: 13px;
font-weight: bold;
color: var(--white);
background: var(--lightningOrange);
padding: 10px 7.5px;
width: 80px;
text-align: center;
border-radius: 5px;
cursor: pointer;
transition: all 0.25s;
&:hover {
opacity: 0.75;
}
&:nth-child(1) {
margin-right: 20px;
}
}
}
.notificationBox {

12
app/containers/Activity.js

@ -23,7 +23,9 @@ import { payFormSelectors } from 'reducers/payform'
import { setWalletCurrencyFilters } from 'reducers/info'
import { setSettingsOpen, setActiveSubMenu, disableSubMenu, setTheme } from 'reducers/settings'
import { setSettingsOpen, setActiveSubMenu, disableSubMenu } from 'reducers/settings'
import { setTheme, themeSelectors } from 'reducers/theme'
import Activity from 'components/Activity'
@ -77,6 +79,9 @@ const mapStateToProps = state => ({
currentLocale: state.intl.locale,
locales: state.locale,
currentTheme: themeSelectors.currentTheme(state),
themes: themeSelectors.themes(state),
paymentModalOpen: paymentSelectors.paymentModalOpen(state),
invoiceModalOpen: invoiceSelectors.invoiceModalOpen(state),
@ -110,7 +115,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => ({
currencyName: stateProps.currencyName,
network: stateProps.info.network,
paymentTimeout: stateProps.payment.paymentTimeout,
theme: stateProps.settings.theme,
theme: stateProps.currentTheme,
setCurrency: dispatchProps.setCurrency,
setWalletCurrencyFilters: dispatchProps.setWalletCurrencyFilters,
@ -148,7 +153,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => ({
},
themeProps: {
theme: stateProps.settings.theme,
themes: stateProps.themes,
currentTheme: stateProps.currentTheme,
setTheme: dispatchProps.setTheme,
disableSubMenu: dispatchProps.disableSubMenu
}

2
app/containers/App.js

@ -4,6 +4,7 @@ import get from 'lodash.get'
import { btc } from 'lib/utils'
import { themeSelectors } from 'reducers/theme'
import { setCurrency, tickerSelectors } from 'reducers/ticker'
import { closeWalletModal } from 'reducers/address'
@ -165,6 +166,7 @@ const mapStateToProps = state => ({
activityModalItem: activitySelectors.activityModalItem(state),
currentTheme: themeSelectors.currentTheme(state),
currentTicker: tickerSelectors.currentTicker(state),
currentCurrencyFilters: tickerSelectors.currentCurrencyFilters(state),
currencyName: tickerSelectors.currencyName(state),

72
app/containers/Root.js

@ -3,8 +3,8 @@ import { connect } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import { Switch, Route } from 'react-router'
import PropTypes from 'prop-types'
import { ThemeProvider } from 'styled-components'
import GlobalError from 'components/GlobalError'
import { clearError } from 'reducers/error'
import {
@ -32,6 +32,7 @@ import {
setReEnterSeedIndexes
} from 'reducers/onboarding'
import { fetchTicker, tickerSelectors } from 'reducers/ticker'
import { themeSelectors } from 'reducers/theme'
import { lndSelectors } from 'reducers/lnd'
import { walletAddress } from 'reducers/address'
import LoadingBolt from 'components/LoadingBolt'
@ -73,8 +74,9 @@ const mapStateToProps = state => ({
onboarding: state.onboarding,
address: state.address,
info: state.info,
theme: state.settings.theme,
balance: state.balance,
currentTheme: themeSelectors.currentTheme(state),
currentThemeSettings: themeSelectors.currentThemeSettings(state),
currentTicker: tickerSelectors.currentTicker(state),
error: state.error,
syncPercentage: lndSelectors.syncPercentage(state),
@ -97,7 +99,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
hasSynced: stateProps.info.hasSynced,
syncPercentage: stateProps.syncPercentage,
address: stateProps.address.address,
theme: stateProps.theme
theme: stateProps.currentTheme
}
const connectionTypeProps = {
@ -188,7 +190,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
const onboardingProps = {
onboarding: stateProps.onboarding,
theme: stateProps.theme,
theme: stateProps.currentTheme,
changeStep: dispatchProps.changeStep,
startLnd: dispatchProps.startLnd,
submitNewWallet: dispatchProps.submitNewWallet,
@ -225,6 +227,7 @@ class Root extends Component {
const {
balance,
clearError,
currentThemeSettings,
currentTicker,
error: { error },
history,
@ -235,15 +238,17 @@ class Root extends Component {
if (!onboardingProps.onboarding.onboarded) {
return (
<div>
<LoadingBolt
theme={onboardingProps.theme}
visible={!onboardingProps.onboarding.onboarding}
/>
<GlobalError error={error} clearError={clearError} />
<Onboarding {...onboardingProps} />
<Syncing {...syncingProps} />
</div>
<ThemeProvider theme={currentThemeSettings}>
<div>
<LoadingBolt
theme={onboardingProps.theme}
visible={!onboardingProps.onboarding.onboarding}
/>
<GlobalError error={error} clearError={clearError} />
<Onboarding {...onboardingProps} />
<Syncing {...syncingProps} />
</div>
</ThemeProvider>
)
}
@ -253,27 +258,33 @@ class Root extends Component {
onboardingProps.onboarding.connectionType === 'local' &&
lnd.syncStatus !== 'complete'
) {
return <Syncing {...syncingProps} />
return (
<ThemeProvider theme={currentThemeSettings}>
<Syncing {...syncingProps} />
</ThemeProvider>
)
}
return (
<ConnectedRouter history={history}>
<div>
<LoadingBolt
theme={onboardingProps.theme}
visible={
(!lnd.lightningGrpcActive && !lnd.walletUnlockerGrpcActive) ||
!currentTicker ||
balance.channelBalance === null ||
balance.walletBalance === null
}
/>
<App>
<Switch>
<Route path="/" component={Activity} />
</Switch>
</App>
</div>
<ThemeProvider theme={currentThemeSettings}>
<div>
<LoadingBolt
theme={onboardingProps.theme}
visible={
(!lnd.lightningGrpcActive && !lnd.walletUnlockerGrpcActive) ||
!currentTicker ||
balance.channelBalance === null ||
balance.walletBalance === null
}
/>
<App>
<Switch>
<Route path="/" component={Activity} />
</Switch>
</App>
</div>
</ThemeProvider>
</ConnectedRouter>
)
}
@ -284,6 +295,7 @@ Root.propTypes = {
clearError: PropTypes.func.isRequired,
error: PropTypes.object.isRequired,
fetchTicker: PropTypes.func.isRequired,
currentThemeSettings: PropTypes.object.isRequired,
currentTicker: PropTypes.object,
history: PropTypes.object.isRequired,
lnd: PropTypes.object.isRequired,

5
app/index.js

@ -2,12 +2,9 @@ import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-intl-redux'
import jstz from 'jstimezonedetect'
import Root from './containers/Root'
import { configureStore, history } from './store/configureStore'
import { getLocale } from './lib/i18n'
// Load global styles.
import Root from './containers/Root'
import './styles/app.global.scss'
// Register supported locales.

4
app/lib/lnd/subscribe/channelgraph.js

@ -5,7 +5,7 @@ export default function subscribeToChannelGraph() {
const call = this.service.subscribeChannelGraph({})
call.on('data', channelGraphData => {
mainLog.info('CHANNELGRAPH:', channelGraphData)
mainLog.debug('CHANNELGRAPH:', channelGraphData)
if (this.mainWindow) {
this.mainWindow.send('channelGraphData', { channelGraphData })
}
@ -13,7 +13,7 @@ export default function subscribeToChannelGraph() {
call.on('end', () => mainLog.info('end'))
call.on('error', error => error.code !== status.CANCELLED && mainLog.error(error))
call.on('status', channelGraphStatus => {
mainLog.info('CHANNELGRAPHSTATUS:', channelGraphStatus)
mainLog.debug('CHANNELGRAPHSTATUS:', channelGraphStatus)
if (this.mainWindow) {
this.mainWindow.send('channelGraphStatus', { channelGraphStatus })
}

3
app/reducers/index.js

@ -2,6 +2,7 @@ import { combineReducers } from 'redux'
import { routerReducer as router } from 'react-router-redux'
import { intlReducer as intl } from 'react-intl-redux'
import locale from './locale'
import theme from './theme'
import onboarding from './onboarding'
import lnd from './lnd'
import ticker from './ticker'
@ -29,6 +30,8 @@ const rootReducer = combineReducers({
router,
intl,
locale,
theme,
onboarding,
lnd,
ticker,

23
app/reducers/settings.js

@ -1,7 +1,3 @@
import Store from 'electron-store'
// Settings store
const store = new Store({ name: 'settings' })
// ------------------------------------
// Constants
// ------------------------------------
@ -9,8 +5,6 @@ export const SET_SETTINGS_OPEN = 'SET_SETTINGS_OPEN'
export const SET_ACTIVE_SUBMENU = 'SET_ACTIVE_SUBMENU'
export const DISABLE_SUBMENU = 'DISABLE_SUBMENU'
export const SET_THEME = 'SET_THEME'
// ------------------------------------
// Actions
// ------------------------------------
@ -34,25 +28,13 @@ export function disableSubMenu() {
}
}
export function setTheme(theme) {
// Persist the new fiatTicker in our ticker store
store.set('theme', theme)
return {
type: SET_THEME,
theme
}
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[SET_SETTINGS_OPEN]: (state, { settingsOpen }) => ({ ...state, settingsOpen }),
[SET_ACTIVE_SUBMENU]: (state, { activeSubMenu }) => ({ ...state, activeSubMenu }),
[DISABLE_SUBMENU]: state => ({ ...state, activeSubMenu: null }),
[SET_THEME]: (state, { theme }) => ({ ...state, theme })
[DISABLE_SUBMENU]: state => ({ ...state, activeSubMenu: null })
}
// ------------------------------------
@ -60,8 +42,7 @@ const ACTION_HANDLERS = {
// ------------------------------------
const initialState = {
settingsOpen: false,
activeSubMenu: null,
theme: store.get('theme', 'dark')
activeSubMenu: null
}
export default function settingsReducer(state = initialState, action) {

67
app/reducers/theme.js

@ -0,0 +1,67 @@
import { createSelector } from 'reselect'
import Store from 'electron-store'
import { dark, light } from 'themes'
// Settings store
const store = new Store({ name: 'settings' })
// ------------------------------------
// Constants
// ------------------------------------
export const SET_THEME = 'SET_THEME'
const DEFAULT_THEME = 'dark'
// ------------------------------------
// Actions
// ------------------------------------
export function setTheme(currentTheme) {
// Persist the new fiatTicker in our ticker store
store.set('theme', currentTheme)
return {
type: SET_THEME,
currentTheme
}
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[SET_THEME]: (state, { currentTheme }) => ({ ...state, currentTheme })
}
// ------------------------------------
// Selectors
// ------------------------------------
const themeSelectors = {}
const currentThemeSelector = state => state.theme.currentTheme
const themesSelector = state => state.theme.themes
themeSelectors.themes = createSelector(themesSelector, themes => themes)
themeSelectors.currentTheme = createSelector(currentThemeSelector, currentTheme => currentTheme)
themeSelectors.currentThemeSettings = createSelector(
themesSelector,
currentThemeSelector,
(themes, currentTheme) => themes[currentTheme]
)
export { themeSelectors }
// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
currentTheme: store.get('theme', DEFAULT_THEME),
themes: { dark, light }
}
export default function themeReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}

90
app/styles/app.global.scss

@ -74,96 +74,6 @@ input[type=number] {
}
}
// buttons
.buttonPrimary,
.buttonSecondary {
-webkit-user-select: none;
cursor: pointer;
display: block;
padding: 18px 30px 15px;
border-radius: 2px;
text-align: center;
font-size: 16px;
letter-spacing: 1.5px;
transition: none;
position: relative;
color: $white;
}
.buttonPrimary {
background-color: $main;
box-shadow: 0 3px 0 0 darken($main, 10%);
&:active {
box-shadow: inset 0 1px 1px 1px darken($main, 10%);
}
}
.buttonPrimary.inactive {
opacity: 0.5;
cursor: auto;
}
.buttonPrimary.inactive:active {
box-shadow: 0 3px 0 0 darken($main, 10%);
transform: none;
}
.buttonSecondary {
background-color: $secondary;
box-shadow: 0 3px 0 0 darken($secondary, 10%);
&:active {
box-shadow: inset 0 1px 1px 1px darken($secondary, 10%);
}
}
.buttonPrimary:active,
.buttonSecondary:active {
transform: translate(0, 3px);
outline: 0;
}
.buttonContainer.circleContainer {
display: inline-block;
width: auto;
min-width: 0;
background: none;
border: none;
box-shadow: none;
}
.buttonContainer .circle {
display: inline-block;
border-radius: 50px;
}
.buttonContainer .circle.small {
width: 50px;
padding: 10px 0;
}
.buttonContainer.small {
min-width: auto;
padding: 0;
border: none;
margin: 0 auto;
width: 80%;
}
.buttonContainer .small.active {
box-shadow: inset 0 1px 1px 1px #1f4b2e;
transform: translate(0, 3px);
outline: 0;
background: #002280;
}
.buttonContainer.small .buttonPrimary {
padding: 10px 5px;
font-size: 15px;
}
// network
@keyframes dash {

5
app/translations/en.json

@ -99,6 +99,7 @@
"components.Onboarding.FormContainer.next": "Next",
"components.Onboarding.Login.password_placeholder": "Password",
"components.Onboarding.Login.unlock": "Unlock",
"components.Onboarding.Login.unlocking": "Unlocking",
"components.Onboarding.NewWalletPassword.password_confirm_placeholder": "Confirm Password",
"components.Onboarding.NewWalletPassword.password_error_length": "Password must be at least {passwordMinLength} characters long",
"components.Onboarding.NewWalletPassword.password_error_match": "Passwords do not match",
@ -145,6 +146,10 @@
"components.Settings.Locale.title": "Language",
"components.Settings.Menu.fiat": "Fiat Currency",
"components.Settings.Menu.locale": "Language",
"components.Settings.Menu.theme": "Theme",
"components.Settings.Theme.dark": "Dark",
"components.Settings.Theme.light": "Light",
"components.Settings.Theme.title": "Theme",
"components.Wallet.ReceiveModal.bitcoin_address": "Bitcoin Address",
"components.Wallet.ReceiveModal.copy_address": "Copy address",
"components.Wallet.ReceiveModal.copy_pubkey": "Copy Pubkey",

10
test/unit/components/Form/Pay.spec.js

@ -1,9 +1,9 @@
import React from 'react'
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import 'jest-styled-components'
import Pay from 'components/Form/Pay'
import { dark as theme } from 'themes'
import { mountWithIntl } from '../../__helpers__/intl-enzyme-test-helper'
configure({ adapter: new Adapter() })
@ -48,7 +48,7 @@ const defaultProps = {
describe('Form', () => {
describe('should show the form without an input', () => {
const el = mountWithIntl(<Pay {...defaultProps} />)
const el = mountWithIntl(<Pay {...defaultProps} theme={theme} />)
it('should contain Pay', () => {
expect(el.find('input#paymentRequest').props.value).toBe(undefined)
@ -57,7 +57,7 @@ describe('Form', () => {
describe('should show lightning with a lightning input', () => {
const props = { ...defaultProps, isLn: true }
const el = mountWithIntl(<Pay {...props} />)
const el = mountWithIntl(<Pay {...props} theme={theme} />)
it('should contain Pay', () => {
expect(el.find('input#paymentRequest').props.value).toBe(undefined)
@ -66,7 +66,7 @@ describe('Form', () => {
describe('should show on-chain with an on-chain input', () => {
const props = { ...defaultProps, isOnchain: true }
const el = mountWithIntl(<Pay {...props} />)
const el = mountWithIntl(<Pay {...props} theme={theme} />)
it('should contain Pay', () => {
expect(el.find('input#paymentRequest').props.value).toBe(undefined)

4
test/unit/reducers/__snapshots__/settings.spec.js.snap

@ -4,7 +4,6 @@ exports[`reducers settingsReducer should correctly disableSubmenu 1`] = `
Object {
"activeSubMenu": null,
"settingsOpen": false,
"theme": "dark",
}
`;
@ -12,7 +11,6 @@ exports[`reducers settingsReducer should correctly setActiveSubmenu 1`] = `
Object {
"activeSubMenu": true,
"settingsOpen": false,
"theme": "dark",
}
`;
@ -20,7 +18,6 @@ exports[`reducers settingsReducer should correctly setSettingsOpen 1`] = `
Object {
"activeSubMenu": null,
"settingsOpen": true,
"theme": "dark",
}
`;
@ -28,6 +25,5 @@ exports[`reducers settingsReducer should handle initial state 1`] = `
Object {
"activeSubMenu": null,
"settingsOpen": false,
"theme": "dark",
}
`;

Loading…
Cancel
Save