Chore desktop cleanup #6896
15 changed files with 464 additions and 448 deletions
|
@ -19,7 +19,7 @@ THUMBNAIL_CDN_URL=https://image-processor.vanwanet.com/optimize/
|
||||||
WELCOME_VERSION=1.0
|
WELCOME_VERSION=1.0
|
||||||
|
|
||||||
# STRIPE
|
# STRIPE
|
||||||
STRIPE_PUBLIC_KEY='pk_test_NoL1JWL7i1ipfhVId5KfDZgo'
|
# STRIPE_PUBLIC_KEY='pk_test_NoL1JWL7i1ipfhVId5KfDZgo'
|
||||||
|
|
||||||
# Analytics
|
# Analytics
|
||||||
MATOMO_URL=https://analytics.lbry.com/
|
MATOMO_URL=https://analytics.lbry.com/
|
||||||
|
|
|
@ -2090,5 +2090,8 @@
|
||||||
"Expand Comments": "Expand Comments",
|
"Expand Comments": "Expand Comments",
|
||||||
"Expand": "Expand",
|
"Expand": "Expand",
|
||||||
"Load More": "Load More",
|
"Load More": "Load More",
|
||||||
|
"Collection": "Collection",
|
||||||
|
"%channelName% isn't live right now, but the chat is! Check back later to watch the stream.": "%channelName% isn't live right now, but the chat is! Check back later to watch the stream.",
|
||||||
|
"Review": "Review",
|
||||||
"--end--": "--end--"
|
"--end--": "--end--"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { ElementRef } from 'react';
|
import type { ElementRef } from 'react';
|
||||||
import { SIMPLE_SITE, STRIPE_PUBLIC_KEY } from 'config';
|
import { SIMPLE_SITE } from 'config';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -21,12 +21,8 @@ import Empty from 'component/common/empty';
|
||||||
import { getChannelIdFromClaim } from 'util/claim';
|
import { getChannelIdFromClaim } from 'util/claim';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
|
|
||||||
let stripeEnvironment = 'test';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
// if the key contains pk_live it's a live key
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
// 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 TAB_FIAT = 'TabFiat';
|
const TAB_FIAT = 'TabFiat';
|
||||||
const TAB_LBC = 'TabLBC';
|
const TAB_LBC = 'TabLBC';
|
||||||
|
@ -245,10 +241,13 @@ export function CommentCreate(props: Props) {
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
doToast({
|
doToast({
|
||||||
message: __("You sent %tipAmount% LBRY Credits as a tip to %tipChannelName%, I'm sure they appreciate it!", {
|
message: __(
|
||||||
tipAmount: tipAmount, // force show decimal places
|
"You sent %tipAmount% LBRY Credits as a tip to %tipChannelName%, I'm sure they appreciate it!",
|
||||||
tipChannelName,
|
{
|
||||||
}),
|
tipAmount: tipAmount, // force show decimal places
|
||||||
|
tipChannelName,
|
||||||
|
}
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
setSuccessTip({ txid, tipAmount });
|
setSuccessTip({ txid, tipAmount });
|
||||||
|
@ -265,7 +264,8 @@ export function CommentCreate(props: Props) {
|
||||||
Lbryio.call(
|
Lbryio.call(
|
||||||
'customer',
|
'customer',
|
||||||
'tip',
|
'tip',
|
||||||
{ // round to deal with floating point precision
|
{
|
||||||
|
// round to deal with floating point precision
|
||||||
amount: Math.round(100 * roundedAmount), // convert from dollars to cents
|
amount: Math.round(100 * roundedAmount), // convert from dollars to cents
|
||||||
creator_channel_name: tipChannelName, // creator_channel_name
|
creator_channel_name: tipChannelName, // creator_channel_name
|
||||||
creator_channel_claim_id: channelClaimId,
|
creator_channel_claim_id: channelClaimId,
|
||||||
|
@ -387,12 +387,7 @@ export function CommentCreate(props: Props) {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField type="textarea" name={'comment_signup_prompt'} placeholder={__('Say something about this...')} />
|
||||||
type="textarea"
|
|
||||||
name={'comment_signup_prompt'}
|
|
||||||
placeholder={__('Say something about this...')}
|
|
||||||
label={isFetchingChannels ? __('Comment') : undefined}
|
|
||||||
/>
|
|
||||||
<div className="section__actions--no-margin">
|
<div className="section__actions--no-margin">
|
||||||
<Button disabled button="primary" label={__('Post --[button to submit something]--')} requiresAuth={IS_WEB} />
|
<Button disabled button="primary" label={__('Post --[button to submit something]--')} requiresAuth={IS_WEB} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -534,7 +529,8 @@ export function CommentCreate(props: Props) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!claimIsMine && (
|
{/* @if TARGET='web' */}
|
||||||
|
{!claimIsMine && stripeEnvironment && (
|
||||||
<Button
|
<Button
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
button="alt"
|
button="alt"
|
||||||
|
@ -546,6 +542,7 @@ export function CommentCreate(props: Props) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{/* @endif */}
|
||||||
{isReply && !minTip && (
|
{isReply && !minTip && (
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
|
|
|
@ -4,14 +4,8 @@ import Button from 'component/button';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { STRIPE_PUBLIC_KEY } from 'config';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
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';
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
accountDetails: any,
|
accountDetails: any,
|
||||||
|
@ -41,12 +35,15 @@ const WalletBalance = (props: Props) => {
|
||||||
|
|
||||||
// TODO: this is actually incorrect, last4 should be populated based on the transaction not the current customer details
|
// TODO: this is actually incorrect, last4 should be populated based on the transaction not the current customer details
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
(async function() {
|
(async function () {
|
||||||
const customerStatusResponse = await getCustomerStatus();
|
const customerStatusResponse = await getCustomerStatus();
|
||||||
|
|
||||||
const lastFour = customerStatusResponse.PaymentMethods && customerStatusResponse.PaymentMethods.length && customerStatusResponse.PaymentMethods[0].card.last4;
|
const lastFour =
|
||||||
|
customerStatusResponse.PaymentMethods &&
|
||||||
|
customerStatusResponse.PaymentMethods.length &&
|
||||||
|
customerStatusResponse.PaymentMethods[0].card.last4;
|
||||||
|
|
||||||
setLastFour(lastFour);
|
setLastFour(lastFour);
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -59,53 +56,57 @@ const WalletBalance = (props: Props) => {
|
||||||
<div className="table__wrapper">
|
<div className="table__wrapper">
|
||||||
<table className="table table--transactions">
|
<table className="table table--transactions">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="date-header">{__('Date')}</th>
|
<th className="date-header">{__('Date')}</th>
|
||||||
<th>{<>{__('Receiving Channel Name')}</>}</th>
|
<th>{<>{__('Receiving Channel Name')}</>}</th>
|
||||||
<th>{__('Tip Location')}</th>
|
<th>{__('Tip Location')}</th>
|
||||||
<th>{__('Amount (USD)')} </th>
|
<th>{__('Amount (USD)')} </th>
|
||||||
<th>{__('Card Last 4')}</th>
|
<th>{__('Card Last 4')}</th>
|
||||||
<th>{__('Anonymous')}</th>
|
<th>{__('Anonymous')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{accountTransactions &&
|
{accountTransactions &&
|
||||||
accountTransactions.map((transaction) => (
|
accountTransactions.map((transaction) => (
|
||||||
<tr key={transaction.name + transaction.created_at}>
|
<tr key={transaction.name + transaction.created_at}>
|
||||||
<td>{moment(transaction.created_at).format('LLL')}</td>
|
<td>{moment(transaction.created_at).format('LLL')}</td>
|
||||||
<td>
|
<td>
|
||||||
<Button
|
<Button
|
||||||
className=""
|
className=""
|
||||||
navigate={'/' + transaction.channel_name + ':' + transaction.channel_claim_id}
|
navigate={'/' + transaction.channel_name + ':' + transaction.channel_claim_id}
|
||||||
label={transaction.channel_name}
|
label={transaction.channel_name}
|
||||||
button="link"
|
button="link"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Button
|
<Button
|
||||||
className=""
|
className=""
|
||||||
navigate={'/' + transaction.channel_name + ':' + transaction.source_claim_id}
|
navigate={'/' + transaction.channel_name + ':' + transaction.source_claim_id}
|
||||||
label={
|
label={
|
||||||
transaction.channel_claim_id === transaction.source_claim_id
|
transaction.channel_claim_id === transaction.source_claim_id
|
||||||
? 'Channel Page'
|
? 'Channel Page'
|
||||||
: 'Content Page'
|
: 'Content Page'
|
||||||
}
|
}
|
||||||
button="link"
|
button="link"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>${transaction.tipped_amount / 100}</td>
|
<td>${transaction.tipped_amount / 100}</td>
|
||||||
<td>{lastFour}</td>
|
<td>{lastFour}</td>
|
||||||
<td>{transaction.private_tip ? 'Yes' : 'No'}</td>
|
<td>{transaction.private_tip ? 'Yes' : 'No'}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{(!accountTransactions || accountTransactions.length === 0) && <p style={{textAlign: 'center', marginTop: '20px', fontSize: '13px', color: 'rgb(171, 171, 171)'}}>No Transactions</p>}
|
{(!accountTransactions || accountTransactions.length === 0) && (
|
||||||
|
<p style={{ textAlign: 'center', marginTop: '20px', fontSize: '13px', color: 'rgb(171, 171, 171)' }}>
|
||||||
|
No Transactions
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,8 @@ import LbcSymbol from 'component/common/lbc-symbol';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
|
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
|
||||||
import { STRIPE_PUBLIC_KEY } from 'config';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
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 DEFAULT_TIP_AMOUNTS = [1, 5, 25, 100];
|
||||||
const MINIMUM_FIAT_TIP = 1;
|
const MINIMUM_FIAT_TIP = 1;
|
||||||
|
@ -100,7 +94,7 @@ function WalletSendTip(props: Props) {
|
||||||
|
|
||||||
// check if creator has a payment method saved
|
// check if creator has a payment method saved
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (channelClaimId && isAuthenticated) {
|
if (channelClaimId && isAuthenticated && stripeEnvironment) {
|
||||||
Lbryio.call(
|
Lbryio.call(
|
||||||
'customer',
|
'customer',
|
||||||
'status',
|
'status',
|
||||||
|
@ -118,16 +112,18 @@ function WalletSendTip(props: Props) {
|
||||||
setHasSavedCard(Boolean(defaultPaymentMethodId));
|
setHasSavedCard(Boolean(defaultPaymentMethodId));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [channelClaimId, isAuthenticated]);
|
}, [channelClaimId, isAuthenticated, stripeEnvironment]);
|
||||||
|
|
||||||
// check if creator has an account saved
|
// check if creator has an account saved
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const tipInputElement = document.getElementById('tip-input');
|
const tipInputElement = document.getElementById('tip-input');
|
||||||
if (tipInputElement) { tipInputElement.focus() }
|
if (tipInputElement) {
|
||||||
|
tipInputElement.focus();
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (channelClaimId) {
|
if (channelClaimId && stripeEnvironment) {
|
||||||
Lbryio.call(
|
Lbryio.call(
|
||||||
'account',
|
'account',
|
||||||
'check',
|
'check',
|
||||||
|
@ -149,14 +145,14 @@ function WalletSendTip(props: Props) {
|
||||||
// console.log(error);
|
// console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [channelClaimId]);
|
}, [channelClaimId, stripeEnvironment]);
|
||||||
|
|
||||||
const noBalance = balance === 0;
|
const noBalance = balance === 0;
|
||||||
const tipAmount = useCustomTip ? customTipAmount : presetTipAmount;
|
const tipAmount = useCustomTip ? customTipAmount : presetTipAmount;
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = React.useState(claimIsMine ? TAB_BOOST : TAB_LBC);
|
const [activeTab, setActiveTab] = React.useState(claimIsMine ? TAB_BOOST : TAB_LBC);
|
||||||
|
|
||||||
function setClaimTypeText() {
|
function getClaimTypeText() {
|
||||||
if (claim.value_type === 'stream') {
|
if (claim.value_type === 'stream') {
|
||||||
return __('Content');
|
return __('Content');
|
||||||
} else if (claim.value_type === 'channel') {
|
} else if (claim.value_type === 'channel') {
|
||||||
|
@ -169,22 +165,24 @@ function WalletSendTip(props: Props) {
|
||||||
return __('Claim');
|
return __('Claim');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const claimTypeText = setClaimTypeText();
|
const claimTypeText = getClaimTypeText();
|
||||||
|
|
||||||
let iconToUse;
|
let iconToUse;
|
||||||
let explainerText = '';
|
let explainerText = '';
|
||||||
if (activeTab === TAB_BOOST) {
|
if (activeTab === TAB_BOOST) {
|
||||||
iconToUse = ICONS.LBC;
|
iconToUse = ICONS.LBC;
|
||||||
explainerText = __('This refundable boost will improve the discoverability of this %claimTypeText% while active.', {claimTypeText});
|
explainerText = __('This refundable boost will improve the discoverability of this %claimTypeText% while active.', {
|
||||||
|
claimTypeText,
|
||||||
|
});
|
||||||
} else if (activeTab === TAB_FIAT) {
|
} else if (activeTab === TAB_FIAT) {
|
||||||
iconToUse = ICONS.FINANCE;
|
iconToUse = ICONS.FINANCE;
|
||||||
explainerText = __('Show this channel your appreciation by sending a donation in USD. ');
|
explainerText = __('Show this channel your appreciation by sending a donation in USD.');
|
||||||
// if (!hasCardSaved) {
|
// if (!hasCardSaved) {
|
||||||
// explainerText += __('You must add a card to use this functionality.');
|
// explainerText += __('You must add a card to use this functionality.');
|
||||||
// }
|
// }
|
||||||
} else if (activeTab === TAB_LBC) {
|
} else if (activeTab === TAB_LBC) {
|
||||||
iconToUse = ICONS.LBC;
|
iconToUse = ICONS.LBC;
|
||||||
explainerText = __('Show this channel your appreciation by sending a donation of Credits. ');
|
explainerText = __('Show this channel your appreciation by sending a donation of Credits.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSupport = claimIsMine || activeTab === TAB_BOOST;
|
const isSupport = claimIsMine || activeTab === TAB_BOOST;
|
||||||
|
@ -216,7 +214,7 @@ function WalletSendTip(props: Props) {
|
||||||
} else if (tipAmount < MINIMUM_PUBLISH_BID) {
|
} else if (tipAmount < MINIMUM_PUBLISH_BID) {
|
||||||
tipError = __('Amount must be higher');
|
tipError = __('Amount must be higher');
|
||||||
}
|
}
|
||||||
// if tip fiat tab
|
// if tip fiat tab
|
||||||
} else {
|
} else {
|
||||||
regexp = RegExp(/^(\d*([.]\d{0,2})?)$/);
|
regexp = RegExp(/^(\d*([.]\d{0,2})?)$/);
|
||||||
const validTipInput = regexp.test(String(tipAmount));
|
const validTipInput = regexp.test(String(tipAmount));
|
||||||
|
@ -276,7 +274,8 @@ function WalletSendTip(props: Props) {
|
||||||
Lbryio.call(
|
Lbryio.call(
|
||||||
'customer',
|
'customer',
|
||||||
'tip',
|
'tip',
|
||||||
{ // round to fix issues with floating point numbers
|
{
|
||||||
|
// round to fix issues with floating point numbers
|
||||||
amount: Math.round(100 * tipAmount), // convert from dollars to cents
|
amount: Math.round(100 * tipAmount), // convert from dollars to cents
|
||||||
creator_channel_name: tipChannelName, // creator_channel_name
|
creator_channel_name: tipChannelName, // creator_channel_name
|
||||||
creator_channel_claim_id: channelClaimId,
|
creator_channel_claim_id: channelClaimId,
|
||||||
|
@ -297,7 +296,7 @@ function WalletSendTip(props: Props) {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function (error) {
|
||||||
let displayError = 'Sorry, there was an error in processing your payment!';
|
let displayError = 'Sorry, there was an error in processing your payment!';
|
||||||
|
|
||||||
if (error.message !== 'payment intent failed to confirm') {
|
if (error.message !== 'payment intent failed to confirm') {
|
||||||
|
@ -316,10 +315,10 @@ function WalletSendTip(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const countDecimals = function(value) {
|
const countDecimals = function (value) {
|
||||||
const text = value.toString();
|
const text = value.toString();
|
||||||
const index = text.indexOf('.');
|
const index = text.indexOf('.');
|
||||||
return (text.length - index - 1);
|
return text.length - index - 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleCustomPriceChange(event: SyntheticInputEvent<*>) {
|
function handleCustomPriceChange(event: SyntheticInputEvent<*>) {
|
||||||
|
@ -387,7 +386,9 @@ function WalletSendTip(props: Props) {
|
||||||
const displayAmount = !isNan(tipAmount) ? amountToShow : '';
|
const displayAmount = !isNan(tipAmount) ? amountToShow : '';
|
||||||
|
|
||||||
if (activeTab === TAB_BOOST) {
|
if (activeTab === TAB_BOOST) {
|
||||||
return (claimIsMine ? __('Boost Your %claimTypeText%', {claimTypeText}) : __('Boost This %claimTypeText%', {claimTypeText}));
|
return claimIsMine
|
||||||
|
? __('Boost Your %claimTypeText%', { claimTypeText })
|
||||||
|
: __('Boost This %claimTypeText%', { claimTypeText });
|
||||||
} else if (activeTab === TAB_FIAT) {
|
} else if (activeTab === TAB_FIAT) {
|
||||||
return __('Send a $%displayAmount% Tip', { displayAmount });
|
return __('Send a $%displayAmount% Tip', { displayAmount });
|
||||||
} else if (activeTab === TAB_LBC) {
|
} else if (activeTab === TAB_LBC) {
|
||||||
|
@ -416,7 +417,16 @@ function WalletSendTip(props: Props) {
|
||||||
{/* if there is no LBC balance, show user frontend to get credits */}
|
{/* if there is no LBC balance, show user frontend to get credits */}
|
||||||
{/* if there is lbc, the main tip/boost gui with the 3 tabs at the top */}
|
{/* if there is lbc, the main tip/boost gui with the 3 tabs at the top */}
|
||||||
<Card
|
<Card
|
||||||
title={<LbcSymbol postfix={claimIsMine ? __('Boost Your %claimTypeText%', {claimTypeText}) : __('Support This %claimTypeText%', {claimTypeText})} size={22} />}
|
title={
|
||||||
|
<LbcSymbol
|
||||||
|
postfix={
|
||||||
|
claimIsMine
|
||||||
|
? __('Boost Your %claimTypeText%', { claimTypeText })
|
||||||
|
: __('Support This %claimTypeText%', { claimTypeText })
|
||||||
|
}
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
}
|
||||||
subtitle={
|
subtitle={
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{!claimIsMine && (
|
{!claimIsMine && (
|
||||||
|
@ -429,7 +439,9 @@ function WalletSendTip(props: Props) {
|
||||||
button="alt"
|
button="alt"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const tipInputElement = document.getElementById('tip-input');
|
const tipInputElement = document.getElementById('tip-input');
|
||||||
if (tipInputElement) { tipInputElement.focus() }
|
if (tipInputElement) {
|
||||||
|
tipInputElement.focus();
|
||||||
|
}
|
||||||
if (!isConfirming) {
|
if (!isConfirming) {
|
||||||
setActiveTab(TAB_LBC);
|
setActiveTab(TAB_LBC);
|
||||||
}
|
}
|
||||||
|
@ -438,20 +450,24 @@ function WalletSendTip(props: Props) {
|
||||||
/>
|
/>
|
||||||
{/* tip fiat tab button */}
|
{/* tip fiat tab button */}
|
||||||
{/* @if TARGET='web' */}
|
{/* @if TARGET='web' */}
|
||||||
<Button
|
{stripeEnvironment && (
|
||||||
key="tip-fiat"
|
<Button
|
||||||
icon={ICONS.FINANCE}
|
key="tip-fiat"
|
||||||
label={__('Tip')}
|
icon={ICONS.FINANCE}
|
||||||
button="alt"
|
label={__('Tip')}
|
||||||
onClick={() => {
|
button="alt"
|
||||||
const tipInputElement = document.getElementById('tip-input');
|
onClick={() => {
|
||||||
if (tipInputElement) { tipInputElement.focus() }
|
const tipInputElement = document.getElementById('tip-input');
|
||||||
if (!isConfirming) {
|
if (tipInputElement) {
|
||||||
setActiveTab(TAB_FIAT);
|
tipInputElement.focus();
|
||||||
}
|
}
|
||||||
}}
|
if (!isConfirming) {
|
||||||
className={classnames('button-toggle', { 'button-toggle--active': activeTab === TAB_FIAT })}
|
setActiveTab(TAB_FIAT);
|
||||||
/>
|
}
|
||||||
|
}}
|
||||||
|
className={classnames('button-toggle', { 'button-toggle--active': activeTab === TAB_FIAT })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{/* @endif */}
|
{/* @endif */}
|
||||||
{/* tip LBC tab button */}
|
{/* tip LBC tab button */}
|
||||||
<Button
|
<Button
|
||||||
|
@ -461,7 +477,9 @@ function WalletSendTip(props: Props) {
|
||||||
button="alt"
|
button="alt"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const tipInputElement = document.getElementById('tip-input');
|
const tipInputElement = document.getElementById('tip-input');
|
||||||
if (tipInputElement) { tipInputElement.focus() }
|
if (tipInputElement) {
|
||||||
|
tipInputElement.focus();
|
||||||
|
}
|
||||||
if (!isConfirming) {
|
if (!isConfirming) {
|
||||||
setActiveTab(TAB_BOOST);
|
setActiveTab(TAB_BOOST);
|
||||||
}
|
}
|
||||||
|
@ -493,33 +511,29 @@ function WalletSendTip(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
<div className="confirm__label">{setConfirmLabel()}</div>
|
<div className="confirm__label">{setConfirmLabel()}</div>
|
||||||
<div className="confirm__value">
|
<div className="confirm__value">
|
||||||
{activeTab === TAB_FIAT ? <p>$ {(Math.round(tipAmount * 100) / 100).toFixed(2)}</p> : <LbcSymbol postfix={tipAmount} size={22} />}
|
{activeTab === TAB_FIAT ? (
|
||||||
|
<p>$ {(Math.round(tipAmount * 100) / 100).toFixed(2)}</p>
|
||||||
|
) : (
|
||||||
|
<LbcSymbol postfix={tipAmount} size={22} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
<Button
|
<Button autoFocus onClick={handleSubmit} button="primary" disabled={isPending} label={__('Confirm')} />
|
||||||
autoFocus
|
|
||||||
onClick={handleSubmit}
|
|
||||||
button="primary"
|
|
||||||
disabled={isPending}
|
|
||||||
label={__('Confirm')}
|
|
||||||
/>
|
|
||||||
<Button button="link" label={__('Cancel')} onClick={() => setIsConfirming(false)} />
|
<Button button="link" label={__('Cancel')} onClick={() => setIsConfirming(false)} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
// only show the prompt to earn more if its lbc or boost tab and no balance
|
) : !((activeTab === TAB_LBC || activeTab === TAB_BOOST) && noBalance) ? (
|
||||||
// otherwise you can show the full prompt
|
<>
|
||||||
) : (!((activeTab === TAB_LBC || activeTab === TAB_BOOST) && noBalance)
|
|
||||||
? <>
|
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<ChannelSelector />
|
<ChannelSelector />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{activeTab === TAB_FIAT && !hasCardSaved && (
|
{activeTab === TAB_FIAT && !hasCardSaved && (
|
||||||
<h3 className="add-card-prompt">
|
<h3 className="add-card-prompt">
|
||||||
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card')} button="link" />
|
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card')} button="link" />{' '}
|
||||||
{' '}{__('To Tip Creators')}
|
{__('To Tip Creators')}
|
||||||
</h3>
|
</h3>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -625,28 +639,36 @@ function WalletSendTip(props: Props) {
|
||||||
<div className="help">{__('The payment will be made from your saved card')}</div>
|
<div className="help">{__('The payment will be made from your saved card')}</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
// if it's LBC and there is no balance, you can prompt to purchase LBC
|
) : (
|
||||||
: <Card
|
// if it's LBC and there is no balance, you can prompt to purchase LBC
|
||||||
title={<I18nMessage tokens={{ lbc: <LbcSymbol size={22} /> }}>Supporting content requires %lbc%</I18nMessage>}
|
<Card
|
||||||
subtitle={
|
title={
|
||||||
<I18nMessage tokens={{ lbc: <LbcSymbol /> }}>
|
<I18nMessage tokens={{ lbc: <LbcSymbol size={22} /> }}>Supporting content requires %lbc%</I18nMessage>
|
||||||
With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to
|
}
|
||||||
see.
|
subtitle={
|
||||||
</I18nMessage>
|
<I18nMessage tokens={{ lbc: <LbcSymbol /> }}>
|
||||||
}
|
With %lbc%, you can send tips to your favorite creators, or help boost their content for more people
|
||||||
actions={
|
to see.
|
||||||
<div className="section__actions">
|
</I18nMessage>
|
||||||
<Button
|
}
|
||||||
icon={ICONS.REWARDS}
|
actions={
|
||||||
button="primary"
|
<div className="section__actions">
|
||||||
label={__('Earn Rewards')}
|
<Button
|
||||||
navigate={`/$/${PAGES.REWARDS}`}
|
icon={ICONS.REWARDS}
|
||||||
/>
|
button="primary"
|
||||||
<Button icon={ICONS.BUY} button="secondary" label={__('Buy/Swap Credits')} navigate={`/$/${PAGES.BUY}`} />
|
label={__('Earn Rewards')}
|
||||||
<Button button="link" label={__('Nevermind')} onClick={closeModal} />
|
navigate={`/$/${PAGES.REWARDS}`}
|
||||||
</div>
|
/>
|
||||||
}
|
<Button
|
||||||
/>
|
icon={ICONS.BUY}
|
||||||
|
button="secondary"
|
||||||
|
label={__('Buy/Swap Credits')}
|
||||||
|
navigate={`/$/${PAGES.BUY}`}
|
||||||
|
/>
|
||||||
|
<Button button="link" label={__('Nevermind')} onClick={closeModal} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -11,14 +11,8 @@ import classnames from 'classnames';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
|
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { STRIPE_PUBLIC_KEY } from 'config';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
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 DEFAULT_TIP_AMOUNTS = [1, 5, 25, 100];
|
||||||
|
|
||||||
|
@ -76,45 +70,49 @@ function WalletTipAmountSelector(props: Props) {
|
||||||
|
|
||||||
// check if creator has a payment method saved
|
// check if creator has a payment method saved
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
Lbryio.call(
|
if (stripeEnvironment) {
|
||||||
'customer',
|
Lbryio.call(
|
||||||
'status',
|
'customer',
|
||||||
{
|
'status',
|
||||||
environment: stripeEnvironment,
|
{
|
||||||
},
|
environment: stripeEnvironment,
|
||||||
'post'
|
},
|
||||||
).then((customerStatusResponse) => {
|
'post'
|
||||||
const defaultPaymentMethodId =
|
).then((customerStatusResponse) => {
|
||||||
customerStatusResponse.Customer &&
|
const defaultPaymentMethodId =
|
||||||
customerStatusResponse.Customer.invoice_settings &&
|
customerStatusResponse.Customer &&
|
||||||
customerStatusResponse.Customer.invoice_settings.default_payment_method &&
|
customerStatusResponse.Customer.invoice_settings &&
|
||||||
customerStatusResponse.Customer.invoice_settings.default_payment_method.id;
|
customerStatusResponse.Customer.invoice_settings.default_payment_method &&
|
||||||
|
customerStatusResponse.Customer.invoice_settings.default_payment_method.id;
|
||||||
|
|
||||||
setHasSavedCard(Boolean(defaultPaymentMethodId));
|
setHasSavedCard(Boolean(defaultPaymentMethodId));
|
||||||
});
|
});
|
||||||
}, []);
|
}
|
||||||
|
}, [stripeEnvironment]);
|
||||||
|
|
||||||
//
|
//
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
Lbryio.call(
|
if (stripeEnvironment) {
|
||||||
'account',
|
Lbryio.call(
|
||||||
'check',
|
'account',
|
||||||
{
|
'check',
|
||||||
channel_claim_id: channelClaimId,
|
{
|
||||||
channel_name: tipChannelName,
|
channel_claim_id: channelClaimId,
|
||||||
environment: stripeEnvironment,
|
channel_name: tipChannelName,
|
||||||
},
|
environment: stripeEnvironment,
|
||||||
'post'
|
},
|
||||||
)
|
'post'
|
||||||
.then((accountCheckResponse) => {
|
)
|
||||||
if (accountCheckResponse === true && canReceiveFiatTip !== true) {
|
.then((accountCheckResponse) => {
|
||||||
setCanReceiveFiatTip(true);
|
if (accountCheckResponse === true && canReceiveFiatTip !== true) {
|
||||||
}
|
setCanReceiveFiatTip(true);
|
||||||
})
|
}
|
||||||
.catch(function (error) {
|
})
|
||||||
// console.log(error);
|
.catch(function (error) {
|
||||||
});
|
// console.log(error);
|
||||||
}, []);
|
});
|
||||||
|
}
|
||||||
|
}, [stripeEnvironment]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// setHasSavedCard(false);
|
// setHasSavedCard(false);
|
||||||
|
@ -214,7 +212,7 @@ function WalletTipAmountSelector(props: Props) {
|
||||||
<div className="help">
|
<div className="help">
|
||||||
<span className="help--spendable">
|
<span className="help--spendable">
|
||||||
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card ')} button="link" /> To{' '}
|
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card ')} button="link" /> To{' '}
|
||||||
{__(' Tip Creators')}
|
{__('Tip Creators')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -282,7 +280,7 @@ function WalletTipAmountSelector(props: Props) {
|
||||||
<div className="help">
|
<div className="help">
|
||||||
<span className="help--spendable">
|
<span className="help--spendable">
|
||||||
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card ')} button="link" /> To{' '}
|
<Button navigate={`/$/${PAGES.SETTINGS_STRIPE_CARD}`} label={__('Add a Card ')} button="link" /> To{' '}
|
||||||
{__(' Tip Creators')}
|
{__('Tip Creators')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
2
ui/constants/stripe.js
Normal file
2
ui/constants/stripe.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const TEST = 'test';
|
||||||
|
export const LIVE = 'live';
|
|
@ -5,43 +5,19 @@ import Card from 'component/common/card';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { STRIPE_PUBLIC_KEY } from 'config';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
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';
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
closeModal: () => void,
|
closeModal: () => void,
|
||||||
abandonTxo: (Txo, () => void) => void,
|
|
||||||
abandonClaim: (string, number, ?() => void) => void,
|
|
||||||
tx: Txo,
|
|
||||||
claim: GenericClaim,
|
|
||||||
cb: () => void,
|
|
||||||
doResolveUri: (string) => void,
|
|
||||||
uri: string,
|
|
||||||
paymentMethodId: string,
|
paymentMethodId: string,
|
||||||
setAsConfirmingCard: () => void,
|
setAsConfirmingCard: () => void, // ?
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ModalRevokeClaim(props: Props) {
|
export default function ModalRemoveCard(props: Props) {
|
||||||
var that = this;
|
const { closeModal, paymentMethodId } = props;
|
||||||
console.log(that);
|
|
||||||
|
|
||||||
console.log(props);
|
|
||||||
|
|
||||||
const { closeModal, uri, paymentMethodId, setAsConfirmingCard } = props;
|
|
||||||
|
|
||||||
console.log(uri);
|
|
||||||
|
|
||||||
console.log(setAsConfirmingCard);
|
|
||||||
|
|
||||||
function removeCard() {
|
function removeCard() {
|
||||||
console.log(paymentMethodId);
|
|
||||||
|
|
||||||
Lbryio.call(
|
Lbryio.call(
|
||||||
'customer',
|
'customer',
|
||||||
'detach',
|
'detach',
|
||||||
|
@ -51,11 +27,9 @@ export default function ModalRevokeClaim(props: Props) {
|
||||||
},
|
},
|
||||||
'post'
|
'post'
|
||||||
).then((removeCardResponse) => {
|
).then((removeCardResponse) => {
|
||||||
console.log(removeCardResponse);
|
|
||||||
|
|
||||||
// TODO: add toast here
|
// TODO: add toast here
|
||||||
// closeModal();
|
// closeModal();
|
||||||
|
// Is there a better way to handle this? Why reload?
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -63,15 +37,14 @@ export default function ModalRevokeClaim(props: Props) {
|
||||||
return (
|
return (
|
||||||
<Modal ariaHideApp={false} isOpen contentLabel={'hello'} type="card" onAborted={closeModal}>
|
<Modal ariaHideApp={false} isOpen contentLabel={'hello'} type="card" onAborted={closeModal}>
|
||||||
<Card
|
<Card
|
||||||
title={'Confirm Remove Card'}
|
title={__('Confirm Remove Card')}
|
||||||
// body={getMsgBody(type, isSupport, name)}
|
|
||||||
actions={
|
actions={
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
<Button
|
<Button
|
||||||
className="stripe__confirm-remove-card"
|
className="stripe__confirm-remove-card"
|
||||||
button="secondary"
|
button="secondary"
|
||||||
icon={ICONS.DELETE}
|
icon={ICONS.DELETE}
|
||||||
label={'Remove Card'}
|
label={__('Remove Card')}
|
||||||
onClick={removeCard}
|
onClick={removeCard}
|
||||||
/>
|
/>
|
||||||
<Button button="link" label={__('Cancel')} onClick={closeModal} />
|
<Button button="link" label={__('Cancel')} onClick={closeModal} />
|
||||||
|
|
|
@ -12,7 +12,6 @@ import FileRenderDownload from 'component/fileRenderDownload';
|
||||||
import RecommendedContent from 'component/recommendedContent';
|
import RecommendedContent from 'component/recommendedContent';
|
||||||
import CollectionContent from 'component/collectionContentSidebar';
|
import CollectionContent from 'component/collectionContentSidebar';
|
||||||
import CommentsList from 'component/commentsList';
|
import CommentsList from 'component/commentsList';
|
||||||
import { Redirect } from 'react-router';
|
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
import Empty from 'component/common/empty';
|
import Empty from 'component/common/empty';
|
||||||
|
@ -145,10 +144,6 @@ function FilePage(props: Props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!claimIsMine && isLivestream) {
|
|
||||||
return <Redirect to={`/$/${PAGES.LIVESTREAM}`} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obscureNsfw && isMature) {
|
if (obscureNsfw && isMature) {
|
||||||
return (
|
return (
|
||||||
<Page className="file-page" filePage isMarkdown={isMarkdown}>
|
<Page className="file-page" filePage isMarkdown={isMarkdown}>
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { SIMPLE_SITE } from 'config';
|
||||||
import homepages from 'homepages';
|
import homepages from 'homepages';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import Yrbl from 'component/yrbl';
|
import Yrbl from 'component/yrbl';
|
||||||
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
|
||||||
type Price = {
|
type Price = {
|
||||||
currency: string,
|
currency: string,
|
||||||
|
@ -451,7 +452,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
{/* @endif */}
|
{/* @endif */}
|
||||||
|
|
||||||
{/* @if TARGET='web' */}
|
{/* @if TARGET='web' */}
|
||||||
{user && (
|
{user && getStripeEnvironment() && (
|
||||||
<Card
|
<Card
|
||||||
title={__('Bank Accounts')}
|
title={__('Bank Accounts')}
|
||||||
subtitle={__('Connect a bank account to receive tips and compensation in your local currency')}
|
subtitle={__('Connect a bank account to receive tips and compensation in your local currency')}
|
||||||
|
@ -470,7 +471,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
{/* @endif */}
|
{/* @endif */}
|
||||||
|
|
||||||
{/* @if TARGET='web' */}
|
{/* @if TARGET='web' */}
|
||||||
{isAuthenticated && (
|
{isAuthenticated && getStripeEnvironment() && (
|
||||||
<Card
|
<Card
|
||||||
title={__('Payment Methods')}
|
title={__('Payment Methods')}
|
||||||
subtitle={__('Add a credit card to tip creators in their local currency')}
|
subtitle={__('Add a credit card to tip creators in their local currency')}
|
||||||
|
|
|
@ -7,17 +7,12 @@ import Card from 'component/common/card';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
|
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { URL, WEBPACK_WEB_PORT, STRIPE_PUBLIC_KEY } from 'config';
|
import { URL, WEBPACK_WEB_PORT } from 'config';
|
||||||
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
|
||||||
const isDev = process.env.NODE_ENV !== 'production';
|
const isDev = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
let stripeEnvironment = 'test';
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
// 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';
|
|
||||||
}
|
|
||||||
|
|
||||||
let successStripeRedirectUrl, failureStripeRedirectUrl;
|
let successStripeRedirectUrl, failureStripeRedirectUrl;
|
||||||
let successEndpoint = '/$/settings/tip_account';
|
let successEndpoint = '/$/settings/tip_account';
|
||||||
let failureEndpoint = '/$/settings/tip_account';
|
let failureEndpoint = '/$/settings/tip_account';
|
||||||
|
@ -46,7 +41,7 @@ type State = {
|
||||||
unpaidBalance: number,
|
unpaidBalance: number,
|
||||||
pageTitle: string,
|
pageTitle: string,
|
||||||
stillRequiringVerification: boolean,
|
stillRequiringVerification: boolean,
|
||||||
accountTransactions: any
|
accountTransactions: any,
|
||||||
};
|
};
|
||||||
|
|
||||||
class StripeAccountConnection extends React.Component<Props, State> {
|
class StripeAccountConnection extends React.Component<Props, State> {
|
||||||
|
@ -144,7 +139,10 @@ class StripeAccountConnection extends React.Component<Props, State> {
|
||||||
stillRequiringVerification: false,
|
stillRequiringVerification: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((eventuallyDueInformation && eventuallyDueInformation.length) || (currentlyDueInformation && currentlyDueInformation.length)) {
|
if (
|
||||||
|
(eventuallyDueInformation && eventuallyDueInformation.length) ||
|
||||||
|
(currentlyDueInformation && currentlyDueInformation.length)
|
||||||
|
) {
|
||||||
objectToUpdateState.stillRequiringVerification = true;
|
objectToUpdateState.stillRequiringVerification = true;
|
||||||
getAndSetAccountLink(false);
|
getAndSetAccountLink(false);
|
||||||
}
|
}
|
||||||
|
@ -233,8 +231,17 @@ class StripeAccountConnection extends React.Component<Props, State> {
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<h3>{__('Congratulations! Your account has been connected with Odysee.')}</h3>
|
<h3>{__('Congratulations! Your account has been connected with Odysee.')}</h3>
|
||||||
{stillRequiringVerification && <><h3 style={{marginTop: '10px'}}>Although your account is connected it still requires verification to begin receiving tips.</h3>
|
{stillRequiringVerification && (
|
||||||
<h3 style={{marginTop: '10px'}}>Please use the button below to complete your verification process and enable tipping for your account.</h3></> }
|
<>
|
||||||
|
<h3 style={{ marginTop: '10px' }}>
|
||||||
|
Although your account is connected it still requires verification to begin receiving tips.
|
||||||
|
</h3>
|
||||||
|
<h3 style={{ marginTop: '10px' }}>
|
||||||
|
Please use the button below to complete your verification process and enable tipping for
|
||||||
|
your account.
|
||||||
|
</h3>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -254,9 +261,7 @@ class StripeAccountConnection extends React.Component<Props, State> {
|
||||||
<br />
|
<br />
|
||||||
<div>
|
<div>
|
||||||
<h3>
|
<h3>
|
||||||
{__(
|
{__('Connect your bank account to be able to cash your pending balance out to your account.')}
|
||||||
'Connect your bank account to be able to cash your pending balance out to your account.'
|
|
||||||
)}
|
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
|
@ -271,19 +276,23 @@ class StripeAccountConnection extends React.Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
actions={
|
actions={
|
||||||
<>{ stillRequiringVerification && <Button
|
<>
|
||||||
button="primary"
|
{stillRequiringVerification && (
|
||||||
label={__('Complete Verification')}
|
<Button
|
||||||
icon={ICONS.SETTINGS}
|
button="primary"
|
||||||
navigate={stripeConnectionUrl}
|
label={__('Complete Verification')}
|
||||||
className="stripe__complete-verification-button"
|
icon={ICONS.SETTINGS}
|
||||||
/> }
|
navigate={stripeConnectionUrl}
|
||||||
<Button
|
className="stripe__complete-verification-button"
|
||||||
button="secondary"
|
/>
|
||||||
label={__('View Transactions')}
|
)}
|
||||||
icon={ICONS.SETTINGS}
|
<Button
|
||||||
navigate={`/$/${PAGES.WALLET}?tab=fiat-payment-history`}
|
button="secondary"
|
||||||
/></>
|
label={__('View Transactions')}
|
||||||
|
icon={ICONS.SETTINGS}
|
||||||
|
navigate={`/$/${PAGES.WALLET}?tab=fiat-payment-history`}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -5,19 +5,14 @@ import React from 'react';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { STRIPE_PUBLIC_KEY } from 'config';
|
|
||||||
import Plastic from 'react-plastic';
|
import Plastic from 'react-plastic';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
|
import { STRIPE_PUBLIC_KEY } from 'config';
|
||||||
let stripeEnvironment = 'test';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
// if the key contains pk_live it's a live key
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
// 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 APIS_DOWN_ERROR_RESPONSE = __('There was an error from the server, please try again later');
|
const APIS_DOWN_ERROR_RESPONSE = __('There was an error from the server, please try again later');
|
||||||
const CARD_SETUP_ERROR_RESPONSE = __('There was an error getting your card setup, please try again later');
|
const CARD_SETUP_ERROR_RESPONSE = __('There was an error getting your card setup, please try again later');
|
||||||
|
@ -79,114 +74,116 @@ class SettingsStripeCard extends React.Component<Props, State> {
|
||||||
// TODO: fix this, should be a cleaner way
|
// TODO: fix this, should be a cleaner way
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
// check if customer has card setup already
|
// check if customer has card setup already
|
||||||
Lbryio.call(
|
if (stripeEnvironment) {
|
||||||
'customer',
|
Lbryio.call(
|
||||||
'status',
|
'customer',
|
||||||
{
|
'status',
|
||||||
environment: stripeEnvironment,
|
{
|
||||||
},
|
environment: stripeEnvironment,
|
||||||
'post'
|
},
|
||||||
)
|
'post'
|
||||||
.then((customerStatusResponse) => {
|
)
|
||||||
// user has a card saved if their defaultPaymentMethod has an id
|
.then((customerStatusResponse) => {
|
||||||
const defaultPaymentMethod = customerStatusResponse.Customer.invoice_settings.default_payment_method;
|
// user has a card saved if their defaultPaymentMethod has an id
|
||||||
let userHasAlreadySetupPayment = Boolean(defaultPaymentMethod && defaultPaymentMethod.id);
|
const defaultPaymentMethod = customerStatusResponse.Customer.invoice_settings.default_payment_method;
|
||||||
|
let userHasAlreadySetupPayment = Boolean(defaultPaymentMethod && defaultPaymentMethod.id);
|
||||||
|
|
||||||
// show different frontend if user already has card
|
// show different frontend if user already has card
|
||||||
if (userHasAlreadySetupPayment) {
|
if (userHasAlreadySetupPayment) {
|
||||||
let card = customerStatusResponse.PaymentMethods[0].card;
|
let card = customerStatusResponse.PaymentMethods[0].card;
|
||||||
|
|
||||||
let customer = customerStatusResponse.Customer;
|
let customer = customerStatusResponse.Customer;
|
||||||
|
|
||||||
let topOfDisplay = customer.email.split('@')[0];
|
let topOfDisplay = customer.email.split('@')[0];
|
||||||
let bottomOfDisplay = '@' + customer.email.split('@')[1];
|
let bottomOfDisplay = '@' + customer.email.split('@')[1];
|
||||||
|
|
||||||
let cardDetails = {
|
let cardDetails = {
|
||||||
brand: card.brand,
|
brand: card.brand,
|
||||||
expiryYear: card.exp_year,
|
expiryYear: card.exp_year,
|
||||||
expiryMonth: card.exp_month,
|
expiryMonth: card.exp_month,
|
||||||
lastFour: card.last4,
|
lastFour: card.last4,
|
||||||
topOfDisplay: topOfDisplay,
|
topOfDisplay: topOfDisplay,
|
||||||
bottomOfDisplay: bottomOfDisplay,
|
bottomOfDisplay: bottomOfDisplay,
|
||||||
};
|
};
|
||||||
|
|
||||||
that.setState({
|
that.setState({
|
||||||
currentFlowStage: 'cardConfirmed',
|
currentFlowStage: 'cardConfirmed',
|
||||||
pageTitle: 'Tip History',
|
pageTitle: 'Tip History',
|
||||||
userCardDetails: cardDetails,
|
userCardDetails: cardDetails,
|
||||||
paymentMethodId: customerStatusResponse.PaymentMethods[0].id,
|
paymentMethodId: customerStatusResponse.PaymentMethods[0].id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// otherwise, prompt them to save a card
|
// otherwise, prompt them to save a card
|
||||||
} else {
|
} else {
|
||||||
that.setState({
|
that.setState({
|
||||||
currentFlowStage: 'confirmingCard',
|
currentFlowStage: 'confirmingCard',
|
||||||
});
|
});
|
||||||
|
|
||||||
// get a payment method secret for frontend
|
// get a payment method secret for frontend
|
||||||
|
Lbryio.call(
|
||||||
|
'customer',
|
||||||
|
'setup',
|
||||||
|
{
|
||||||
|
environment: stripeEnvironment,
|
||||||
|
},
|
||||||
|
'post'
|
||||||
|
).then((customerSetupResponse) => {
|
||||||
|
clientSecret = customerSetupResponse.client_secret;
|
||||||
|
|
||||||
|
// instantiate stripe elements
|
||||||
|
setupStripe();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// get customer transactions
|
||||||
Lbryio.call(
|
Lbryio.call(
|
||||||
'customer',
|
'customer',
|
||||||
'setup',
|
'list',
|
||||||
{
|
{
|
||||||
environment: stripeEnvironment,
|
environment: stripeEnvironment,
|
||||||
},
|
},
|
||||||
'post'
|
'post'
|
||||||
).then((customerSetupResponse) => {
|
).then((customerTransactionsResponse) => {
|
||||||
clientSecret = customerSetupResponse.client_secret;
|
that.setState({
|
||||||
|
customerTransactions: customerTransactionsResponse,
|
||||||
// instantiate stripe elements
|
});
|
||||||
setupStripe();
|
|
||||||
});
|
});
|
||||||
}
|
// if the status call fails, either an actual error or need to run setup first
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
// errorString passed from the API (with a 403 error)
|
||||||
|
const errorString = 'user as customer is not setup yet';
|
||||||
|
|
||||||
// get customer transactions
|
// if it's beamer's error indicating the account is not linked yet
|
||||||
Lbryio.call(
|
if (error.message && error.message.indexOf(errorString) > -1) {
|
||||||
'customer',
|
// send them to save a card
|
||||||
'list',
|
that.setState({
|
||||||
{
|
currentFlowStage: 'confirmingCard',
|
||||||
environment: stripeEnvironment,
|
});
|
||||||
},
|
|
||||||
'post'
|
// get a payment method secret for frontend
|
||||||
).then((customerTransactionsResponse) => {
|
Lbryio.call(
|
||||||
that.setState({
|
'customer',
|
||||||
customerTransactions: customerTransactionsResponse,
|
'setup',
|
||||||
});
|
{
|
||||||
|
environment: stripeEnvironment,
|
||||||
|
},
|
||||||
|
'post'
|
||||||
|
).then((customerSetupResponse) => {
|
||||||
|
clientSecret = customerSetupResponse.client_secret;
|
||||||
|
|
||||||
|
// instantiate stripe elements
|
||||||
|
setupStripe();
|
||||||
|
});
|
||||||
|
// 500 error from the backend being down
|
||||||
|
} else if (error === 'internal_apis_down') {
|
||||||
|
doToast({ message: APIS_DOWN_ERROR_RESPONSE, isError: true });
|
||||||
|
} else {
|
||||||
|
// probably an error from stripe
|
||||||
|
doToast({ message: CARD_SETUP_ERROR_RESPONSE, isError: true });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// if the status call fails, either an actual error or need to run setup first
|
}
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
// errorString passed from the API (with a 403 error)
|
|
||||||
const errorString = 'user as customer is not setup yet';
|
|
||||||
|
|
||||||
// if it's beamer's error indicating the account is not linked yet
|
|
||||||
if (error.message && error.message.indexOf(errorString) > -1) {
|
|
||||||
// send them to save a card
|
|
||||||
that.setState({
|
|
||||||
currentFlowStage: 'confirmingCard',
|
|
||||||
});
|
|
||||||
|
|
||||||
// get a payment method secret for frontend
|
|
||||||
Lbryio.call(
|
|
||||||
'customer',
|
|
||||||
'setup',
|
|
||||||
{
|
|
||||||
environment: stripeEnvironment,
|
|
||||||
},
|
|
||||||
'post'
|
|
||||||
).then((customerSetupResponse) => {
|
|
||||||
clientSecret = customerSetupResponse.client_secret;
|
|
||||||
|
|
||||||
// instantiate stripe elements
|
|
||||||
setupStripe();
|
|
||||||
});
|
|
||||||
// 500 error from the backend being down
|
|
||||||
} else if (error === 'internal_apis_down') {
|
|
||||||
doToast({ message: APIS_DOWN_ERROR_RESPONSE, isError: true });
|
|
||||||
} else {
|
|
||||||
// probably an error from stripe
|
|
||||||
doToast({ message: CARD_SETUP_ERROR_RESPONSE, isError: true });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 250);
|
}, 250);
|
||||||
|
|
||||||
function setupStripe() {
|
function setupStripe() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { DOMAIN } from 'config';
|
import { DOMAIN, ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { lazyImport } from 'util/lazyImport';
|
import { lazyImport } from 'util/lazyImport';
|
||||||
|
@ -199,7 +199,7 @@ function ShowPage(props: Props) {
|
||||||
/>
|
/>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
} else if (isLivestream) {
|
} else if (isLivestream && ENABLE_NO_SOURCE_CLAIMS) {
|
||||||
innerContent = <LivestreamPage uri={uri} />;
|
innerContent = <LivestreamPage uri={uri} />;
|
||||||
} else {
|
} else {
|
||||||
innerContent = <FilePage uri={uri} location={location} />;
|
innerContent = <FilePage uri={uri} location={location} />;
|
||||||
|
|
|
@ -12,8 +12,8 @@ import * as PAGES from 'constants/pages';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import YrblWalletEmpty from 'component/yrblWalletEmpty';
|
import YrblWalletEmpty from 'component/yrblWalletEmpty';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { STRIPE_PUBLIC_KEY } from 'config';
|
|
||||||
import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'component/common/tabs';
|
import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'component/common/tabs';
|
||||||
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
|
|
||||||
const TAB_QUERY = 'tab';
|
const TAB_QUERY = 'tab';
|
||||||
|
|
||||||
|
@ -23,12 +23,7 @@ const TABS = {
|
||||||
PAYMENT_HISTORY: 'fiat-payment-history',
|
PAYMENT_HISTORY: 'fiat-payment-history',
|
||||||
};
|
};
|
||||||
|
|
||||||
let stripeEnvironment = 'test';
|
let stripeEnvironment = getStripeEnvironment();
|
||||||
// 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';
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
history: { action: string, push: (string) => void, replace: (string) => void },
|
history: { action: string, push: (string) => void, replace: (string) => void },
|
||||||
|
@ -117,8 +112,11 @@ const WalletPage = (props: Props) => {
|
||||||
|
|
||||||
// calculate account transactions section
|
// calculate account transactions section
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
(async function() {
|
(async function () {
|
||||||
try {
|
try {
|
||||||
|
if (!stripeEnvironment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const response = await getAccountStatus();
|
const response = await getAccountStatus();
|
||||||
|
|
||||||
setAccountStatusResponse(response);
|
setAccountStatusResponse(response);
|
||||||
|
@ -131,23 +129,27 @@ const WalletPage = (props: Props) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, [stripeEnvironment]);
|
||||||
|
|
||||||
// populate customer payment data
|
// populate customer payment data
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
(async function() {
|
(async function () {
|
||||||
try {
|
try {
|
||||||
// get card payments customer has made
|
// get card payments customer has made
|
||||||
|
if (!stripeEnvironment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let customerTransactionResponse = await getPaymentHistory();
|
let customerTransactionResponse = await getPaymentHistory();
|
||||||
|
if (customerTransactionResponse && customerTransactionResponse.length) {
|
||||||
customerTransactionResponse.reverse();
|
customerTransactionResponse.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
setCustomerTransactions(customerTransactionResponse);
|
setCustomerTransactions(customerTransactionResponse);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, [stripeEnvironment]);
|
||||||
|
|
||||||
// @endif
|
// @endif
|
||||||
|
|
||||||
|
@ -157,77 +159,80 @@ const WalletPage = (props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* @if TARGET='web' */}
|
{stripeEnvironment && (
|
||||||
<Page>
|
<Page>
|
||||||
<Tabs onChange={onTabChange} index={tabIndex}>
|
<Tabs onChange={onTabChange} index={tabIndex}>
|
||||||
<TabList className="tabs__list--collection-edit-page">
|
<TabList className="tabs__list--collection-edit-page">
|
||||||
<Tab>{__('LBRY Credits')}</Tab>
|
<Tab>{__('LBRY Credits')}</Tab>
|
||||||
<Tab>{__('Account History')}</Tab>
|
<Tab>{__('Account History')}</Tab>
|
||||||
<Tab>{__('Payment History')}</Tab>
|
<Tab>{__('Payment History')}</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanels>
|
<TabPanels>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<div className="section card-stack">
|
<div className="section card-stack">
|
||||||
<div className="lbc-transactions">
|
<div className="lbc-transactions">
|
||||||
{/* if the transactions are loading */}
|
{/* if the transactions are loading */}
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="main--empty">
|
<div className="main--empty">
|
||||||
<Spinner delayed />
|
<Spinner delayed />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* when the transactions are finished loading */}
|
{/* when the transactions are finished loading */}
|
||||||
{!loading && (
|
{!loading && (
|
||||||
<>
|
<>
|
||||||
{showIntro ? (
|
{showIntro ? (
|
||||||
<YrblWalletEmpty includeWalletLink />
|
<YrblWalletEmpty includeWalletLink />
|
||||||
) : (
|
) : (
|
||||||
<div className="card-stack">
|
<div className="card-stack">
|
||||||
<WalletBalance />
|
<WalletBalance />
|
||||||
<TxoList search={search} />
|
<TxoList search={search} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</TabPanel>
|
||||||
</TabPanel>
|
<TabPanel>
|
||||||
<TabPanel>
|
<div className="section card-stack">
|
||||||
<div className="section card-stack">
|
<WalletFiatBalance accountDetails={accountStatusResponse} />
|
||||||
<WalletFiatBalance accountDetails={accountStatusResponse} />
|
<WalletFiatAccountHistory transactions={accountTransactionResponse} />
|
||||||
<WalletFiatAccountHistory transactions={accountTransactionResponse} />
|
</div>
|
||||||
</div>
|
</TabPanel>
|
||||||
</TabPanel>
|
<TabPanel>
|
||||||
<TabPanel>
|
<div className="section card-stack">
|
||||||
<div className="section card-stack">
|
<WalletFiatPaymentBalance
|
||||||
<WalletFiatPaymentBalance transactions={customerTransactions} accountDetails={accountStatusResponse} />
|
transactions={customerTransactions}
|
||||||
<WalletFiatPaymentHistory transactions={customerTransactions} />
|
accountDetails={accountStatusResponse}
|
||||||
</div>
|
/>
|
||||||
</TabPanel>
|
<WalletFiatPaymentHistory transactions={customerTransactions} />
|
||||||
</TabPanels>
|
</div>
|
||||||
</Tabs>
|
</TabPanel>
|
||||||
</Page>
|
</TabPanels>
|
||||||
{/* @endif */}
|
</Tabs>
|
||||||
{/* @if TARGET='app' */}
|
</Page>
|
||||||
<Page>
|
)}
|
||||||
{loading && (
|
{!stripeEnvironment && (
|
||||||
<div className="main--empty">
|
<Page>
|
||||||
<Spinner delayed />
|
{loading && (
|
||||||
</div>
|
<div className="main--empty">
|
||||||
)}
|
<Spinner delayed />
|
||||||
{!loading && (
|
</div>
|
||||||
<>
|
)}
|
||||||
{showIntro ? (
|
{!loading && (
|
||||||
<YrblWalletEmpty includeWalletLink />
|
<>
|
||||||
) : (
|
{showIntro ? (
|
||||||
<div className="card-stack">
|
<YrblWalletEmpty includeWalletLink />
|
||||||
<WalletBalance />
|
) : (
|
||||||
<TxoList search={search} />
|
<div className="card-stack">
|
||||||
</div>
|
<WalletBalance />
|
||||||
)}
|
<TxoList search={search} />
|
||||||
</>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Page>
|
</>
|
||||||
{/* @endif */}
|
)}
|
||||||
|
</Page>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
13
ui/util/stripe.js
Normal file
13
ui/util/stripe.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// @flow
|
||||||
|
import { STRIPE_PUBLIC_KEY } from 'config';
|
||||||
|
import * as STRIPE_CONSTS from 'constants/stripe';
|
||||||
|
export function getStripeEnvironment() {
|
||||||
|
if (STRIPE_PUBLIC_KEY) {
|
||||||
|
if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) {
|
||||||
|
return STRIPE_CONSTS.LIVE;
|
||||||
|
} else {
|
||||||
|
return STRIPE_CONSTS.TEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
Loading…
Reference in a new issue