From acfca37dec6c2dce065ccbad9e061616842789e4 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 10 Jun 2021 12:56:27 -0500 Subject: [PATCH] CryptoDonate: add CryptoDonateWidget to homepage --- app/soapbox/actions/soapbox.js | 3 + .../components/crypto_donate_panel.js | 65 +++++++++++++++++++ .../crypto_donate/components/site_wallet.js | 9 ++- app/soapbox/pages/home_page.js | 9 ++- app/styles/components/crypto-donate.scss | 32 +++++++++ app/styles/components/wtf-panel.scss | 19 ++++++ 6 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 app/soapbox/features/crypto_donate/components/crypto_donate_panel.js diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index e732b1f40..7e03a1e52 100644 --- a/app/soapbox/actions/soapbox.js +++ b/app/soapbox/actions/soapbox.js @@ -43,6 +43,9 @@ export const defaultConfig = ImmutableMap({ allowedEmoji: allowedEmoji, verifiedCanEditName: false, displayFqn: true, + cryptoDonatePanel: ImmutableMap({ + limit: 3, + }), }); export function getSoapboxConfig(state) { diff --git a/app/soapbox/features/crypto_donate/components/crypto_donate_panel.js b/app/soapbox/features/crypto_donate/components/crypto_donate_panel.js new file mode 100644 index 000000000..b63acdad1 --- /dev/null +++ b/app/soapbox/features/crypto_donate/components/crypto_donate_panel.js @@ -0,0 +1,65 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import { Link } from 'react-router-dom'; +import { FormattedMessage } from 'react-intl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import SiteWallet from './site_wallet'; +import { List as ImmutableList } from 'immutable'; +import classNames from 'classnames'; + +const mapStateToProps = state => { + const addresses = state.getIn(['soapbox', 'crypto_addresses'], ImmutableList()); + return { + total: addresses.size, + siteTitle: state.getIn(['instance', 'title']), + }; +}; + +export default @connect(mapStateToProps) +class CryptoDonatePanel extends ImmutablePureComponent { + + static propTypes = { + limit: PropTypes.number, + total: PropTypes.number, + } + + static defaultProps = { + limit: 3, + } + + render() { + const { limit, total, siteTitle } = this.props; + const more = total - limit; + const hasMore = more > 0; + + return ( +
+
+ + + + +
+
+
+ +
+ +
+ {hasMore && + + } +
+ ); + } + +}; diff --git a/app/soapbox/features/crypto_donate/components/site_wallet.js b/app/soapbox/features/crypto_donate/components/site_wallet.js index 3e5d30bc5..5e5e3fa69 100644 --- a/app/soapbox/features/crypto_donate/components/site_wallet.js +++ b/app/soapbox/features/crypto_donate/components/site_wallet.js @@ -1,14 +1,18 @@ import React from 'react'; import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import CryptoAddress from './crypto_address'; -const mapStateToProps = state => { +const mapStateToProps = (state, ownProps) => { // Address example: // {"ticker": "btc", "address": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n", "note": "This is our main address"} + const addresses = state.getIn(['soapbox', 'crypto_addresses']); + const { limit } = ownProps; + return { - coinList: state.getIn(['soapbox', 'crypto_addresses']), + coinList: typeof limit === 'number' ? addresses.take(limit) : addresses, }; }; @@ -17,6 +21,7 @@ class CoinList extends ImmutablePureComponent { static propTypes = { coinList: ImmutablePropTypes.list, + limit: PropTypes.number, } render() { diff --git a/app/soapbox/pages/home_page.js b/app/soapbox/pages/home_page.js index 50233bb70..435752196 100644 --- a/app/soapbox/pages/home_page.js +++ b/app/soapbox/pages/home_page.js @@ -8,6 +8,7 @@ import FeaturesPanel from '../features/ui/components/features_panel'; import PromoPanel from '../features/ui/components/promo_panel'; import UserPanel from '../features/ui/components/user_panel'; import FundingPanel from '../features/ui/components/funding_panel'; +import CryptoDonatePanel from 'soapbox/features/crypto_donate/components/crypto_donate_panel'; import ComposeFormContainer from '../features/compose/containers/compose_form_container'; import Avatar from '../components/avatar'; import { getFeatures } from 'soapbox/utils/features'; @@ -16,10 +17,13 @@ import { getSoapboxConfig } from 'soapbox/actions/soapbox'; const mapStateToProps = state => { const me = state.get('me'); + const soapbox = getSoapboxConfig(state); return { me, account: state.getIn(['accounts', me]), - hasPatron: getSoapboxConfig(state).getIn(['extensions', 'patron', 'enabled']), + hasPatron: soapbox.getIn(['extensions', 'patron', 'enabled']), + hasCrypto: typeof soapbox.getIn(['crypto_addresses', 0, 'ticker']) === 'string', + cryptoLimit: soapbox.getIn(['cryptoDonatePanel', 'limit']), features: getFeatures(state.get('instance')), }; }; @@ -33,7 +37,7 @@ class HomePage extends ImmutablePureComponent { } render() { - const { me, children, account, hasPatron, features } = this.props; + const { me, children, account, hasPatron, features, hasCrypto, cryptoLimit } = this.props; return (
@@ -44,6 +48,7 @@ class HomePage extends ImmutablePureComponent {
{hasPatron && } + {hasCrypto && }
diff --git a/app/styles/components/crypto-donate.scss b/app/styles/components/crypto-donate.scss index 10289e976..2fd6b7fd6 100644 --- a/app/styles/components/crypto-donate.scss +++ b/app/styles/components/crypto-donate.scss @@ -67,3 +67,35 @@ padding: 10px 0; } } + +.crypto-donate-panel { + &__message { + margin: 20px 0; + margin-top: -12px; + font-size: 14px; + } + + .site-wallet { + display: block; + padding-bottom: 10px; + } + + .crypto-address { + padding: 0; + margin: 20px 0; + + &:first-child { + margin-top: 0; + } + + &:last-child { + margin-bottom: 0; + } + } + + &--has-more { + .site-wallet { + padding-bottom: 0; + } + } +} diff --git a/app/styles/components/wtf-panel.scss b/app/styles/components/wtf-panel.scss index bad152f99..ce46a038a 100644 --- a/app/styles/components/wtf-panel.scss +++ b/app/styles/components/wtf-panel.scss @@ -129,4 +129,23 @@ } } } + + &__expand-btn { + display: block; + width: 100%; + height: 100%; + max-height: 46px; + position: relative; + border-top: 1px solid; + border-color: var(--brand-color--faint); + transition: max-height 150ms ease; + overflow: hidden; + opacity: 1; + text-align: center; + line-height: 46px; + font-size: 14px; + cursor: pointer; + color: var(--primary-text-color); + text-decoration: none; + } }