From 8dcb70cbb197b0c4a0f131d2d282328612d98803 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Tue, 27 Jun 2023 14:49:45 -0400 Subject: [PATCH] PKG -- [fcl] Fixed android polling (#1703) * PKG -- [fcl] Fixed android polling * DOC -- [fcl] add comments * DOC -- [fcl] add comments --- .../exec-service/strategies/http-post.js | 25 ++++++++++++++++--- .../exec-service/strategies/utils/poll.js | 9 ++++--- .../src/utils/react-native/render-browser.js | 6 ++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/fcl/src/current-user/exec-service/strategies/http-post.js b/packages/fcl/src/current-user/exec-service/strategies/http-post.js index e2f5ae96b..722cf1860 100644 --- a/packages/fcl/src/current-user/exec-service/strategies/http-post.js +++ b/packages/fcl/src/current-user/exec-service/strategies/http-post.js @@ -26,25 +26,44 @@ export const getExecHttpPost = (execLocal) => async({service, body, config, opts } else if (resp.status === "REDIRECT") { return resp } else if (resp.status === "PENDING") { + + // these two flags are required to run polling one more time before it stops var canContinue = true + var shouldContinue = true + const [_, unmount] = await execLocal( normalizeLocalView(resp.local), { serviceEndpoint, - onClose: () => (canContinue = false) + onClose: () => (shouldContinue = false) } ) const close = () => { try { unmount() - canContinue = false + shouldContinue = false } catch (error) { console.error("Frame Close Error", error) } } + /** + * this function is run once per poll call. + * Offsetting canContinue flag to make sure that + * the polling is performed one extra time after canContinue flag is set to false + * to prevent halting on Android when a browser calls window.close + * before FCL receives a successful result from polling + * + * @returns {boolean} + */ + const checkCanContinue = () => { + const offsetCanContinue = canContinue + canContinue = shouldContinue + + return offsetCanContinue + } - return poll(resp.updates, () => canContinue) + return poll(resp.updates, checkCanContinue) .then(serviceResponse => { close() return serviceResponse diff --git a/packages/fcl/src/current-user/exec-service/strategies/utils/poll.js b/packages/fcl/src/current-user/exec-service/strategies/utils/poll.js index a217aa10b..fed4a564c 100644 --- a/packages/fcl/src/current-user/exec-service/strategies/utils/poll.js +++ b/packages/fcl/src/current-user/exec-service/strategies/utils/poll.js @@ -24,9 +24,10 @@ const serviceBody = service => { return undefined } -export async function poll(service, canContinue = () => true) { +export async function poll(service, checkCanContinue = () => true) { invariant(service, "Missing Polling Service", {service}) - if (!canContinue()) throw new Error("Externally Halted") + const canContinue = checkCanContinue() + if (!canContinue) throw new Error("Externally Halted") let resp try { @@ -35,7 +36,7 @@ export async function poll(service, canContinue = () => true) { document.visibilityState === "hidden" ) { await new Promise(r => setTimeout(r, 500)) - return poll(service, canContinue) + return poll(service, checkCanContinue) } resp = await fetchService(service, { @@ -52,6 +53,6 @@ export async function poll(service, canContinue = () => true) { throw new Error(`Declined: ${resp.reason || "No reason supplied."}`) default: await new Promise(r => setTimeout(r, 500)) - return poll(resp.updates, canContinue) + return poll(resp.updates, checkCanContinue) } } diff --git a/packages/fcl/src/utils/react-native/render-browser.js b/packages/fcl/src/utils/react-native/render-browser.js index 6b0e867cf..ca5630be3 100644 --- a/packages/fcl/src/utils/react-native/render-browser.js +++ b/packages/fcl/src/utils/react-native/render-browser.js @@ -4,7 +4,11 @@ export function renderBrowser(src, opts = {}) { const webbrowser = WebBrowser.openAuthSessionAsync(src.toString()) const unmount = () => { - WebBrowser.dismissAuthSession() + try { + WebBrowser.dismissAuthSession() + } catch (error) { + console.log(error) + } } // Call onClose when the webbrowser is closed