// @flow import * as ICONS from 'constants/icons'; import * as PAGES from 'constants/pages'; import React from 'react'; import Button from 'component/button'; import { FormField } from 'component/common/form'; import { MINIMUM_PUBLISH_BID } from 'constants/claim'; import CreditAmount from 'component/common/credit-amount'; import I18nMessage from 'component/i18nMessage'; import classnames from 'classnames'; import usePersistedState from 'effects/use-persisted-state'; import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp'; import { Lbryio } from 'lbryinc'; import { STRIPE_PUBLIC_KEY } from 'config'; let stripeEnvironment = 'test'; // if the key contains pk_live it's a live key // update the environment for the calls to the backend to indicate which environment to hit if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { stripeEnvironment = 'live'; } const DEFAULT_TIP_AMOUNTS = [1, 5, 25, 100]; const TAB_FIAT = 'TabFiat'; const TAB_LBC = 'TabLBC'; type Props = { balance: number, amount: number, onChange: (number) => void, isAuthenticated: boolean, claim: StreamClaim, uri: string, onTipErrorChange: (string) => void, activeTab: string, shouldDisableReviewButton: (boolean) => void }; function WalletTipAmountSelector(props: Props) { const { balance, amount, onChange, activeTab, claim, onTipErrorChange, shouldDisableReviewButton } = props; const [useCustomTip, setUseCustomTip] = usePersistedState('comment-support:useCustomTip', false); const [tipError, setTipError] = React.useState(); const [canReceiveFiatTip, setCanReceiveFiatTip] = React.useState(); // dont persist because it needs to be calc'd per creator const [hasCardSaved, setHasSavedCard] = usePersistedState('comment-support:hasCardSaved', false); // if it's fiat but there's no card saved OR the creator can't receive fiat tips const shouldDisableFiatSelectors = (activeTab === TAB_FIAT && (!hasCardSaved || !canReceiveFiatTip)); /** * whether tip amount selection/review functionality should be disabled * @param [amount] LBC amount (optional) * @returns {boolean} */ function shouldDisableAmountSelector(amount) { // if it's LBC but the balance isn't enough, or fiat conditions met // $FlowFixMe return (amount > balance && activeTab !== TAB_FIAT) || shouldDisableFiatSelectors; } shouldDisableReviewButton(shouldDisableFiatSelectors); // setup variables for tip API let channelClaimId, tipChannelName; // if there is a signing channel it's on a file if (claim.signing_channel) { channelClaimId = claim.signing_channel.claim_id; tipChannelName = claim.signing_channel.name; // otherwise it's on the channel page } else { channelClaimId = claim.claim_id; tipChannelName = claim.name; } // check if creator has a payment method saved React.useEffect(() => { Lbryio.call( 'customer', 'status', { environment: stripeEnvironment, }, 'post' ).then((customerStatusResponse) => { const defaultPaymentMethodId = customerStatusResponse.Customer && customerStatusResponse.Customer.invoice_settings && customerStatusResponse.Customer.invoice_settings.default_payment_method && customerStatusResponse.Customer.invoice_settings.default_payment_method.id; setHasSavedCard(Boolean(defaultPaymentMethodId)); }); }, []); // React.useEffect(() => { Lbryio.call( 'account', 'check', { channel_claim_id: channelClaimId, channel_name: tipChannelName, environment: stripeEnvironment, }, 'post' ) .then((accountCheckResponse) => { if (accountCheckResponse === true && canReceiveFiatTip !== true) { setCanReceiveFiatTip(true); } }) .catch(function (error) { // console.log(error); }); }, []); React.useEffect(() => { // setHasSavedCard(false); // setCanReceiveFiatTip(true); const regexp = RegExp(/^(\d*([.]\d{0,8})?)$/); const validTipInput = regexp.test(String(amount)); let tipError = ''; if (amount === 0) { tipError = __('Amount must be a positive number'); } else if (!amount || typeof amount !== 'number') { tipError = __('Amount must be a number'); } // if it's not fiat, aka it's boost or lbc tip else if (activeTab !== TAB_FIAT) { if (!validTipInput) { tipError = __('Amount must have no more than 8 decimal places'); } else if (amount === balance) { tipError = __('Please decrease the amount to account for transaction fees'); } else if (amount > balance) { tipError = __('Not enough Credits'); } else if (amount < MINIMUM_PUBLISH_BID) { tipError = __('Amount must be higher'); } // if tip fiat tab } else { if (amount < 1) { tipError = __('Amount must be at least one dollar'); } else if (amount > 1000) { tipError = __('Amount cannot be over 1000 dollars'); } } setTipError(tipError); onTipErrorChange(tipError); }, [amount, balance, setTipError, activeTab]); function handleCustomPriceChange(amount: number) { const tipAmount = parseFloat(amount); onChange(tipAmount); } return ( <>
{DEFAULT_TIP_AMOUNTS.map((defaultAmount) => (
{useCustomTip && activeTab === TAB_FIAT && !hasCardSaved && ( <>
)} {/* has card saved but cant creator cant receive tips */} {useCustomTip && activeTab === TAB_FIAT && hasCardSaved && !canReceiveFiatTip && ( <>
Only select creators can receive tips at this time
)} {/* has card saved but cant creator cant receive tips */} {useCustomTip && activeTab === TAB_FIAT && hasCardSaved && canReceiveFiatTip && ( <>
Send a tip directly from your attached card
)} {useCustomTip && (
{__('Custom support amount')}{' '} }}> (%lbc_balance% available) ) : ( <> ) // <> //
// Send a tip directly from your attached card //
// } className="form-field--price-amount" error={tipError} min="0" step="any" type="number" placeholder="1.23" value={amount} onChange={(event) => handleCustomPriceChange(event.target.value)} />
)} {/* lbc tab */} {activeTab === TAB_LBC && } {/* fiat button but no card saved */} {!useCustomTip && activeTab === TAB_FIAT && !hasCardSaved && ( <>
)} {/* has card saved but cant creator cant receive tips */} {!useCustomTip && activeTab === TAB_FIAT && hasCardSaved && !canReceiveFiatTip && ( <>
Only select creators can receive tips at this time
)} {/* has card saved but cant creator cant receive tips */} {!useCustomTip && activeTab === TAB_FIAT && hasCardSaved && canReceiveFiatTip && ( <>
Send a tip directly from your attached card
)} ); } export default WalletTipAmountSelector;