From 6d39f8bae0dbdd3c6ad2e486837b458cc2556827 Mon Sep 17 00:00:00 2001 From: Robert Long Date: Mon, 9 Aug 2021 18:03:06 -0700 Subject: [PATCH] Ensure that room UI state is reset when leaving due to inactivity --- src/ConferenceCallManagerHooks.js | 71 +++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/src/ConferenceCallManagerHooks.js b/src/ConferenceCallManagerHooks.js index 6aa5a0c8..d10b7bff 100644 --- a/src/ConferenceCallManagerHooks.js +++ b/src/ConferenceCallManagerHooks.js @@ -149,25 +149,6 @@ export function useVideoRoom(manager, roomId, timeout = 5000) { error: undefined, })); - function onBeforeUnload(event) { - if ( - event.type === "visibilitychange" && - document.visibilityState === "visible" - ) { - return; - } - - manager.leaveCall(); - } - - // iOS doesn't fire beforeunload event, so leave the call when you hide the page. - if (isIOS()) { - window.addEventListener("pagehide", onBeforeUnload); - document.addEventListener("visibilitychange", onBeforeUnload); - } - - window.addEventListener("beforeunload", onBeforeUnload); - const onParticipantsChanged = () => { setState((prevState) => ({ ...prevState, @@ -222,9 +203,6 @@ export function useVideoRoom(manager, roomId, timeout = 5000) { return () => { manager.client.removeListener("Room", roomCallback); manager.removeListener("participants_changed", onParticipantsChanged); - window.removeEventListener("pagehide", onBeforeUnload); - document.removeEventListener("visibilitychange", onBeforeUnload); - window.removeEventListener("beforeunload", onBeforeUnload); clearTimeout(timeoutId); manager.leaveCall(); }; @@ -270,6 +248,55 @@ export function useVideoRoom(manager, roomId, timeout = 5000) { })); }, [manager]); + useEffect(() => { + let pageVisibilityTimeout; + + function onBeforeUnload(event) { + if (event.type === "visibilitychange") { + if (document.visibilityState === "visible") { + clearTimeout(pageVisibilityTimeout); + } else { + // Wait 5 seconds before closing the page to avoid accidentally leaving + // TODO: Make this configurable? + pageVisibilityTimeout = setTimeout(() => { + manager.leaveCall(); + + setState((prevState) => ({ + ...prevState, + participants: manager.participants, + joined: false, + joining: false, + })); + }, 5000); + } + } else { + manager.leaveCall(); + + setState((prevState) => ({ + ...prevState, + participants: manager.participants, + joined: false, + joining: false, + })); + } + } + + // iOS doesn't fire beforeunload event, so leave the call when you hide the page. + if (isIOS()) { + window.addEventListener("pagehide", onBeforeUnload); + document.addEventListener("visibilitychange", onBeforeUnload); + } + + window.addEventListener("beforeunload", onBeforeUnload); + + return () => { + window.removeEventListener("pagehide", onBeforeUnload); + document.removeEventListener("visibilitychange", onBeforeUnload); + window.removeEventListener("beforeunload", onBeforeUnload); + clearTimeout(pageVisibilityTimeout); + }; + }, [manager]); + return { loading, joined,