| @@ -1,15 +1,18 @@ | ||
| 1 | 1 | import React from 'react'; |
| 2 | -import { useEffect, useState } from 'react'; | |
| 2 | +import { useEffect, useRef, useState } from 'react'; | |
| 3 | 3 | import { __ } from '@wordpress/i18n'; |
| 4 | 4 | import { fetchAccessToken } from '../api/wordpressApiClient'; |
| 5 | 5 | import { getOrCreateBackgroundApp } from './backgroundAppUtils'; |
| 6 | 6 | import { isRefreshTokenAvailable } from './isRefreshTokenAvailable'; |
| 7 | +import { reportEmbedderUnavailable, whenEmbedderReady } from './embedderReady'; | |
| 7 | 8 | import ErrorHandler from '../shared/Common/ErrorHandler'; |
| 8 | 9 | |
| 9 | 10 | export function useGetEmbedder() { |
| 10 | 11 | const [embedder, setEmbedder] = useState<any>(null); |
| 11 | 12 | const [errorStatus, setErrorStatus] = useState<number | null>(null); |
| 13 | + const cancelWaitRef = useRef<(() => void) | null>(null); | |
| 14 | + const mountedRef = useRef(true); | |
| 12 | 15 | |
| 13 | 16 | const loadEmbedder = () => { |
| 14 | 17 | fetchAccessToken() |
| 15 | 18 | .then( |
| @@ -19,12 +22,43 @@ | ||
| 19 | 22 | }: { |
| 20 | 23 | accessToken: string; |
| 21 | 24 | expiresIn: number; |
| 22 | 25 | }) => { |
| 23 | - setEmbedder(getOrCreateBackgroundApp(accessToken, expiresIn)); | |
| 26 | + if (!mountedRef.current) return; | |
| 27 | + | |
| 28 | + const startedAt = Date.now(); | |
| 29 | + const { promise, cancel } = whenEmbedderReady(); | |
| 30 | + | |
| 31 | + cancelWaitRef.current = cancel; | |
| 32 | + | |
| 33 | + return promise.then(isReady => { | |
| 34 | + cancelWaitRef.current = null; | |
| 35 | + | |
| 36 | + if (!mountedRef.current) return; | |
| 37 | + | |
| 38 | + const app = isReady | |
| 39 | + ? getOrCreateBackgroundApp(accessToken, expiresIn) | |
| 40 | + : null; | |
| 41 | + | |
| 42 | + if (app) { | |
| 43 | + console.info('HubSpot plugin - embedder ready, rendering widget'); | |
| 44 | + setEmbedder(app); | |
| 45 | + } else { | |
| 46 | + reportEmbedderUnavailable(Date.now() - startedAt); | |
| 47 | + setErrorStatus(500); | |
| 48 | + } | |
| 49 | + }); | |
| 24 | 50 | } |
| 25 | 51 | ) |
| 26 | - .catch((err: any) => setErrorStatus((err && err.status) || 500)); | |
| 52 | + .catch((err: any) => { | |
| 53 | + if (!mountedRef.current) return; | |
| 54 | + | |
| 55 | + console.error( | |
| 56 | + 'HubSpot plugin - access token request failed', | |
| 57 | + (err && err.status) || 'no status' | |
| 58 | + ); | |
| 59 | + setErrorStatus((err && err.status) || 500); | |
| 60 | + }); | |
| 27 | 61 | }; |
| 28 | 62 | |
| 29 | 63 | useEffect(() => { |
| 30 | 64 | if (isRefreshTokenAvailable()) { |
| @@ -29,8 +63,16 @@ | ||
| 29 | 63 | useEffect(() => { |
| 30 | 64 | if (isRefreshTokenAvailable()) { |
| 31 | 65 | loadEmbedder(); |
| 32 | 66 | } |
| 67 | + | |
| 68 | + return () => { | |
| 69 | + mountedRef.current = false; | |
| 70 | + if (cancelWaitRef.current) { | |
| 71 | + cancelWaitRef.current(); | |
| 72 | + cancelWaitRef.current = null; | |
| 73 | + } | |
| 74 | + }; | |
| 33 | 75 | }, []); |
| 34 | 76 | |
| 35 | 77 | const errorElement = |
| 36 | 78 | errorStatus !== null |