kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
CryptoDonate: add CryptoDonateWidget to homepage
rodzic
a3ee5789bc
commit
acfca37dec
|
@ -43,6 +43,9 @@ export const defaultConfig = ImmutableMap({
|
||||||
allowedEmoji: allowedEmoji,
|
allowedEmoji: allowedEmoji,
|
||||||
verifiedCanEditName: false,
|
verifiedCanEditName: false,
|
||||||
displayFqn: true,
|
displayFqn: true,
|
||||||
|
cryptoDonatePanel: ImmutableMap({
|
||||||
|
limit: 3,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export function getSoapboxConfig(state) {
|
export function getSoapboxConfig(state) {
|
||||||
|
|
|
@ -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 (
|
||||||
|
<div className={classNames('wtf-panel funding-panel crypto-donate-panel', { 'crypto-donate-panel--has-more': hasMore })}>
|
||||||
|
<div className='wtf-panel-header'>
|
||||||
|
<i role='img' alt='bitcoin' className='fa fa-bitcoin wtf-panel-header__icon' />
|
||||||
|
<span className='wtf-panel-header__label'>
|
||||||
|
<span><FormattedMessage id='crypto_donate_panel.heading' defaultMessage='Donate Cryptocurrency' /></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='wtf-panel__content'>
|
||||||
|
<div className='crypto-donate-panel__message'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='crypto_donate_panel.intro.message'
|
||||||
|
defaultMessage='{siteTitle} accepts cryptocurrency donations to fund the service. Thank you for your support!'
|
||||||
|
values={{ siteTitle }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<SiteWallet limit={limit} />
|
||||||
|
</div>
|
||||||
|
{hasMore && <Link className='wtf-panel__expand-btn' to='/donate/crypto'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='crypto_donate_panel.actions.more'
|
||||||
|
defaultMessage='Click to see {count} more {count, plural, one {wallet} other {wallets}}'
|
||||||
|
values={{ count: more }}
|
||||||
|
/>
|
||||||
|
</Link>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -1,14 +1,18 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import CryptoAddress from './crypto_address';
|
import CryptoAddress from './crypto_address';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
// Address example:
|
// Address example:
|
||||||
// {"ticker": "btc", "address": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n", "note": "This is our main address"}
|
// {"ticker": "btc", "address": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n", "note": "This is our main address"}
|
||||||
|
const addresses = state.getIn(['soapbox', 'crypto_addresses']);
|
||||||
|
const { limit } = ownProps;
|
||||||
|
|
||||||
return {
|
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 = {
|
static propTypes = {
|
||||||
coinList: ImmutablePropTypes.list,
|
coinList: ImmutablePropTypes.list,
|
||||||
|
limit: PropTypes.number,
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import FeaturesPanel from '../features/ui/components/features_panel';
|
||||||
import PromoPanel from '../features/ui/components/promo_panel';
|
import PromoPanel from '../features/ui/components/promo_panel';
|
||||||
import UserPanel from '../features/ui/components/user_panel';
|
import UserPanel from '../features/ui/components/user_panel';
|
||||||
import FundingPanel from '../features/ui/components/funding_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 ComposeFormContainer from '../features/compose/containers/compose_form_container';
|
||||||
import Avatar from '../components/avatar';
|
import Avatar from '../components/avatar';
|
||||||
import { getFeatures } from 'soapbox/utils/features';
|
import { getFeatures } from 'soapbox/utils/features';
|
||||||
|
@ -16,10 +17,13 @@ import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const me = state.get('me');
|
const me = state.get('me');
|
||||||
|
const soapbox = getSoapboxConfig(state);
|
||||||
return {
|
return {
|
||||||
me,
|
me,
|
||||||
account: state.getIn(['accounts', 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')),
|
features: getFeatures(state.get('instance')),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -33,7 +37,7 @@ class HomePage extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { me, children, account, hasPatron, features } = this.props;
|
const { me, children, account, hasPatron, features, hasCrypto, cryptoLimit } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='page'>
|
<div className='page'>
|
||||||
|
@ -44,6 +48,7 @@ class HomePage extends ImmutablePureComponent {
|
||||||
<div className='columns-area__panels__pane__inner'>
|
<div className='columns-area__panels__pane__inner'>
|
||||||
<UserPanel accountId={me} />
|
<UserPanel accountId={me} />
|
||||||
{hasPatron && <FundingPanel />}
|
{hasPatron && <FundingPanel />}
|
||||||
|
{hasCrypto && <CryptoDonatePanel limit={cryptoLimit} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -67,3 +67,35 @@
|
||||||
padding: 10px 0;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue