lbry-desktop/src/renderer/component/cardVerify/view.jsx

175 lines
4.1 KiB
React
Raw Normal View History

2018-10-04 07:59:47 +02:00
// @flow
2018-11-26 02:21:25 +01:00
import * as ICONS from 'constants/icons';
import React from 'react';
2018-03-26 23:32:43 +02:00
import Button from 'component/button';
2017-07-19 01:00:13 +02:00
let scriptLoading = false;
let scriptLoaded = false;
let scriptDidError = false;
2018-10-04 07:59:47 +02:00
type Props = {
disabled: boolean,
label: ?string,
// =====================================================
// Required by stripe
// see Stripe docs for more info:
// https://stripe.com/docs/checkout#integration-custom
// =====================================================
2018-10-04 07:59:47 +02:00
// Your publishable key (test or live).
// can't use "key" as a prop in react, so have to change the keyname
stripeKey: string,
// The callback to invoke when the Checkout process is complete.
// function(token)
// token is the token object created.
// token.id can be used to create a charge or customer.
// token.email contains the email address entered by the user.
token: string,
};
2017-07-19 01:00:13 +02:00
2019-01-19 19:54:06 +01:00
type State = {
open: boolean,
};
class CardVerify extends React.Component<Props, State> {
constructor(props: Props) {
2017-07-19 01:00:13 +02:00
super(props);
this.state = {
open: false,
};
}
componentDidMount() {
if (scriptLoaded) {
return;
}
if (scriptLoading) {
return;
}
scriptLoading = true;
const script = document.createElement('script');
script.src = 'https://checkout.stripe.com/checkout.js';
script.async = true;
2017-07-19 01:00:13 +02:00
this.loadPromise = (() => {
let canceled = false;
const promise = new Promise((resolve, reject) => {
script.onload = () => {
scriptLoaded = true;
scriptLoading = false;
resolve();
this.onScriptLoaded();
};
script.onerror = event => {
scriptDidError = true;
scriptLoading = false;
reject(event);
this.onScriptError(event);
2017-07-19 01:00:13 +02:00
};
});
const wrappedPromise = new Promise((accept, cancel) => {
promise.then(() => (canceled ? cancel({ isCanceled: true }) : accept()));
promise.catch(error => (canceled ? cancel({ isCanceled: true }) : cancel(error)));
2017-07-19 01:00:13 +02:00
});
return {
promise: wrappedPromise,
cancel() {
canceled = true;
},
};
})();
this.loadPromise.promise.then(this.onScriptLoaded).catch(this.onScriptError);
2017-07-19 01:00:13 +02:00
document.body.appendChild(script);
2017-07-19 01:00:13 +02:00
}
componentDidUpdate() {
if (!scriptLoading) {
this.updateStripeHandler();
}
}
componentWillUnmount() {
if (this.loadPromise) {
this.loadPromise.cancel();
}
if (CardVerify.stripeHandler && this.state.open) {
CardVerify.stripeHandler.close();
}
}
onScriptLoaded = () => {
if (!CardVerify.stripeHandler) {
CardVerify.stripeHandler = StripeCheckout.configure({
key: this.props.stripeKey,
});
if (this.hasPendingClick) {
this.showStripeDialog();
}
}
};
onScriptError = (...args) => {
throw new Error('Unable to load credit validation script.');
2017-07-19 01:00:13 +02:00
};
onClosed = () => {
this.setState({ open: false });
};
updateStripeHandler() {
if (!CardVerify.stripeHandler) {
CardVerify.stripeHandler = StripeCheckout.configure({
key: this.props.stripeKey,
});
}
}
showStripeDialog() {
this.setState({ open: true });
2017-07-25 20:59:47 +02:00
CardVerify.stripeHandler.open({
allowRememberMe: false,
closed: this.onClosed,
description: __('Confirm Identity'),
2017-07-25 20:59:47 +02:00
email: this.props.email,
locale: 'auto',
panelLabel: 'Verify',
2017-07-25 20:59:47 +02:00
token: this.props.token,
2017-07-27 20:42:43 +02:00
zipCode: true,
2017-07-25 20:59:47 +02:00
});
2017-07-19 01:00:13 +02:00
}
onClick = () => {
if (scriptDidError) {
try {
throw new Error('Tried to call onClick, but StripeCheckout failed to load');
} catch (x) {}
} else if (CardVerify.stripeHandler) {
this.showStripeDialog();
} else {
this.hasPendingClick = true;
}
};
2017-07-19 01:00:13 +02:00
render() {
return (
2018-03-26 23:32:43 +02:00
<Button
button="primary"
2017-07-19 01:00:13 +02:00
label={this.props.label}
2018-11-26 02:21:25 +01:00
icon={ICONS.LOCK}
disabled={this.props.disabled || this.state.open || this.hasPendingClick}
onClick={this.onClick.bind(this)}
2017-07-19 01:00:13 +02:00
/>
);
}
}
export default CardVerify;