Implement polling and reconfirmation

This will poll the server every certain interval (15s) for the email address
and stop polling if the email is Authorized or the modal is closed or after a certain period of time (2 hours)

MAILPOET-4300
This commit is contained in:
Oluwaseun Olorunsola
2022-07-04 17:38:15 +01:00
committed by Veljko V
parent 183f64834c
commit ee70d2dd1e
3 changed files with 79 additions and 12 deletions

View File

@ -1,9 +1,14 @@
import { useEffect, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import ReactStringReplace from 'react-string-replace'; import ReactStringReplace from 'react-string-replace';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import moment from 'moment';
import { MailPoet } from 'mailpoet'; import { MailPoet } from 'mailpoet';
import { Modal } from 'common/modal/modal'; import { Modal } from 'common/modal/modal';
import { Loader } from 'common'; import { Button, Loader } from 'common';
const SET_INTERVAL_SECONDS = 15;
const STOP_POLLING_AFTER = 2; // hours
type ApiActionType = 'create' | 'confirm'; type ApiActionType = 'create' | 'confirm';
@ -31,22 +36,75 @@ type Props = {
}; };
function AuthorizeSenderEmailModal({ senderEmail, onRequestClose }: Props) { function AuthorizeSenderEmailModal({ senderEmail, onRequestClose }: Props) {
const [apiResponseType, setApiResponseType] = useState<boolean>(null); const [createEmailApiResponse, setCreateEmailApiResponse] =
useState<boolean>(null);
const [confirmEmailApiResponse, setConfirmEmailApiResponse] =
useState<boolean>(null);
const [showLoader, setShowLoader] = useState<boolean>(true);
const setIntervalId = useRef<NodeJS.Timeout>();
const setIntervalStopTime = useRef<number>();
const senderEmailAddress = String(senderEmail).toLowerCase(); const senderEmailAddress = String(senderEmail).toLowerCase();
useEffect(() => { useEffect(() => {
if (!senderEmailAddress) { if (!senderEmailAddress) {
return; return null;
} }
const clearCurrentInterval = (intervalID: NodeJS.Timeout) => {
clearInterval(intervalID);
};
const executeAction = () => {
const currentIntervalId = setIntervalId.current;
const currentIntervalStopTime = setIntervalStopTime.current;
if (currentIntervalStopTime && Date.now() >= currentIntervalStopTime) {
// stop polling after 2 hours
clearCurrentInterval(currentIntervalId);
return;
}
makeApiRequest(senderEmailAddress, 'confirm')
.then((res) => {
const response = Boolean(res?.data?.isAuthorized);
if (response) {
clearCurrentInterval(currentIntervalId);
setCreateEmailApiResponse(null);
setShowLoader(false);
setConfirmEmailApiResponse(true);
}
})
.catch(() => {
//
});
};
makeApiRequest(senderEmailAddress) makeApiRequest(senderEmailAddress)
.then((res) => { .then((res) => {
setApiResponseType(Boolean(res?.data)); const response = Boolean(res?.data);
setCreateEmailApiResponse(response);
setShowLoader(response);
if (response) {
// if pending or already authorized perform the check ahead
executeAction();
}
}) })
.catch(() => { .catch(() => {
setApiResponseType(false); setCreateEmailApiResponse(false);
setShowLoader(false);
}); });
clearCurrentInterval(setIntervalId.current);
setIntervalStopTime.current = moment()
.add(STOP_POLLING_AFTER, 'hours')
.valueOf();
const invervalID = setInterval(executeAction, 1000 * SET_INTERVAL_SECONDS);
setIntervalId.current = invervalID;
return () => clearCurrentInterval(invervalID);
}, [senderEmailAddress]); }, [senderEmailAddress]);
return ( return (
@ -58,7 +116,7 @@ function AuthorizeSenderEmailModal({ senderEmail, onRequestClose }: Props) {
onRequestClose={onRequestClose} onRequestClose={onRequestClose}
contentClassName="authorize-sender-email-modal" contentClassName="authorize-sender-email-modal"
> >
{apiResponseType && ( {createEmailApiResponse && (
<p> <p>
{ReactStringReplace( {ReactStringReplace(
MailPoet.I18n.t('authorizeSenderEmailModalDescription'), MailPoet.I18n.t('authorizeSenderEmailModalDescription'),
@ -69,12 +127,21 @@ function AuthorizeSenderEmailModal({ senderEmail, onRequestClose }: Props) {
)} )}
</p> </p>
)} )}
{createEmailApiResponse === false && (
{apiResponseType === false && (
<p>{MailPoet.I18n.t('authorizeSenderEmailMessageError')}</p> <p>{MailPoet.I18n.t('authorizeSenderEmailMessageError')}</p>
)} )}
<Loader size={64} /> {showLoader && <Loader size={64} />}
{confirmEmailApiResponse && (
<>
<p>{MailPoet.I18n.t('authorizeSenderEmailMessageSuccess')}</p>
<Button onClick={onRequestClose} className="button-on-top">
{' '}
{MailPoet.I18n.t('close')}{' '}
</Button>
</>
)}
</Modal> </Modal>
); );
} }

View File

@ -198,7 +198,7 @@ class Settings extends APIEndpoint {
} }
/** /**
* Makes POST request to Bridge endpoint to add email to user email authorization list * Create POST request to Bridge endpoint to add email to user email authorization list
*/ */
public function authorizeSenderEmailAddress($data = []) { public function authorizeSenderEmailAddress($data = []) {
$emailAddress = $data['email'] ?? null; $emailAddress = $data['email'] ?? null;

View File

@ -193,7 +193,7 @@ class API {
if (!$isSuccess) { if (!$isSuccess) {
$logData = [ $logData = [
'code' => $code, 'code' => $code,
'error' => is_wp_error($result) ? $result->get_error_message() : null, 'error' => is_wp_error($result) ? $result->get_error_message() : $this->wp->wpRemoteRetrieveBody($result),
]; ];
$this->loggerFactory->getLogger(LoggerFactory::TOPIC_BRIDGE)->error('CreateAuthorizedEmailAddress API call failed.', $logData); $this->loggerFactory->getLogger(LoggerFactory::TOPIC_BRIDGE)->error('CreateAuthorizedEmailAddress API call failed.', $logData);
} }