Debug when user stays online at closing browser
This commit is contained in:
parent
b2affa91c7
commit
545413d2ce
|
@ -153,34 +153,22 @@ const openSocket = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// auth helpers -----------------------------------------------------------
|
|
||||||
|
|
||||||
const setAuth = (t, u) => {
|
|
||||||
authToken = t;
|
|
||||||
authUser = u;
|
|
||||||
saveAuthToStorage(t, u);
|
|
||||||
openSocket();
|
|
||||||
};
|
|
||||||
|
|
||||||
const clearAuth = () => {
|
|
||||||
authToken = null;
|
|
||||||
authUser = null;
|
|
||||||
clearAuthStorage();
|
|
||||||
if (hub) {
|
|
||||||
hub.stop();
|
|
||||||
hub = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// presence ---------------------------------------------------------------
|
// presence ---------------------------------------------------------------
|
||||||
|
|
||||||
const patchOnline = async (on) => {
|
// patchOnline(on, keep = false) ← keep=true will add keepalive: true
|
||||||
|
|
||||||
|
const patchOnline = async (on, keep = false) => {
|
||||||
if (!authUser) return;
|
if (!authUser) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await $fetch(USERS_URL, {
|
await fetch(USERS_URL, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
|
||||||
|
headers: { "Content-Type": "application/json", ...authHeader() },
|
||||||
|
|
||||||
body: JSON.stringify({ user_id: authUser, isOnline: on ? 1 : 0 }),
|
body: JSON.stringify({ user_id: authUser, isOnline: on ? 1 : 0 }),
|
||||||
|
|
||||||
|
...(keep ? { keepalive: true } : {}),
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("[online] PUT failed:", e.message);
|
console.warn("[online] PUT failed:", e.message);
|
||||||
|
@ -191,6 +179,77 @@ export const currentUserOnline = () => patchOnline(true);
|
||||||
|
|
||||||
export const currentUserOffline = () => patchOnline(false);
|
export const currentUserOffline = () => patchOnline(false);
|
||||||
|
|
||||||
|
// leave / background handlers -------------------------------------------
|
||||||
|
|
||||||
|
let leaveHandlerInstalled = false;
|
||||||
|
|
||||||
|
const sendOfflineKeepalive = () => patchOnline(false, true);
|
||||||
|
|
||||||
|
const handleVisibility = () => {
|
||||||
|
if (document.visibilityState === "hidden") sendOfflineKeepalive();
|
||||||
|
|
||||||
|
if (document.visibilityState === "visible") currentUserOnline();
|
||||||
|
};
|
||||||
|
|
||||||
|
const installLeaveHandlers = () => {
|
||||||
|
if (leaveHandlerInstalled) return;
|
||||||
|
|
||||||
|
window.addEventListener("pagehide", sendOfflineKeepalive); // tab / window close
|
||||||
|
|
||||||
|
window.addEventListener("freeze", sendOfflineKeepalive); // page-lifecycle freeze
|
||||||
|
|
||||||
|
window.addEventListener("resume", currentUserOnline); // page-lifecycle resume
|
||||||
|
|
||||||
|
document.addEventListener("visibilitychange", handleVisibility);
|
||||||
|
|
||||||
|
leaveHandlerInstalled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeLeaveHandlers = () => {
|
||||||
|
if (!leaveHandlerInstalled) return;
|
||||||
|
|
||||||
|
window.removeEventListener("pagehide", sendOfflineKeepalive);
|
||||||
|
|
||||||
|
window.removeEventListener("freeze", sendOfflineKeepalive);
|
||||||
|
|
||||||
|
window.removeEventListener("resume", currentUserOnline);
|
||||||
|
|
||||||
|
document.removeEventListener("visibilitychange", handleVisibility);
|
||||||
|
|
||||||
|
leaveHandlerInstalled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// setAuth … add
|
||||||
|
|
||||||
|
const setAuth = (t, u) => {
|
||||||
|
authToken = t;
|
||||||
|
|
||||||
|
authUser = u;
|
||||||
|
|
||||||
|
saveAuthToStorage(t, u);
|
||||||
|
|
||||||
|
openSocket();
|
||||||
|
|
||||||
|
installLeaveHandlers(); // ← here
|
||||||
|
};
|
||||||
|
|
||||||
|
// clearAuth … add
|
||||||
|
|
||||||
|
const clearAuth = () => {
|
||||||
|
authToken = null;
|
||||||
|
|
||||||
|
authUser = null;
|
||||||
|
|
||||||
|
clearAuthStorage();
|
||||||
|
|
||||||
|
if (hub) {
|
||||||
|
hub.stop();
|
||||||
|
hub = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeLeaveHandlers(); // ← here
|
||||||
|
};
|
||||||
|
|
||||||
// bootstrap after login/restore -----------------------------------------
|
// bootstrap after login/restore -----------------------------------------
|
||||||
|
|
||||||
const bootstrapSession = async (uid) => {
|
const bootstrapSession = async (uid) => {
|
||||||
|
|
|
@ -86,7 +86,7 @@ const UserAccount = () => {
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
|
|
||||||
/* Firestore-like subscriptions & online/offline flag */
|
/* Firestore-like subscriptions */
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -101,21 +101,6 @@ const UserAccount = () => {
|
||||||
|
|
||||||
currentUserOnline();
|
currentUserOnline();
|
||||||
|
|
||||||
/* window closed or refreshed */
|
|
||||||
|
|
||||||
const beforeUnload = () => currentUserOffline();
|
|
||||||
|
|
||||||
window.addEventListener("beforeunload", beforeUnload);
|
|
||||||
|
|
||||||
/* tab visibility switch */
|
|
||||||
|
|
||||||
const visChange = () =>
|
|
||||||
document.visibilityState === "visible"
|
|
||||||
? currentUserOnline()
|
|
||||||
: currentUserOffline();
|
|
||||||
|
|
||||||
document.addEventListener("visibilitychange", visChange);
|
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -124,10 +109,6 @@ const UserAccount = () => {
|
||||||
unsubUsers();
|
unsubUsers();
|
||||||
|
|
||||||
unsubPosts();
|
unsubPosts();
|
||||||
|
|
||||||
window.removeEventListener("beforeunload", beforeUnload);
|
|
||||||
|
|
||||||
document.removeEventListener("visibilitychange", visChange);
|
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -165,8 +146,8 @@ const UserAccount = () => {
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='bg-200 vw-100 main-container overflow-hidden'>
|
<div className="bg-200 vw-100 main-container overflow-hidden">
|
||||||
<Container className='w-100 p-0' fluid>
|
<Container className="w-100 p-0" fluid>
|
||||||
<Router>
|
<Router>
|
||||||
<RouteStateSync />
|
<RouteStateSync />
|
||||||
|
|
||||||
|
@ -175,29 +156,29 @@ const UserAccount = () => {
|
||||||
<Switch>
|
<Switch>
|
||||||
{/* Friends list ------------------------------------------------ */}
|
{/* Friends list ------------------------------------------------ */}
|
||||||
|
|
||||||
<Route path='/fakebook/friends/list' component={FriendsListPage} />
|
<Route path="/fakebook/friends/list" component={FriendsListPage} />
|
||||||
|
|
||||||
{/* Single photo ----------------------------------------------- */}
|
{/* Single photo ----------------------------------------------- */}
|
||||||
|
|
||||||
<Route path='/fakebook/photo/:userID/:n' component={PhotoViewer} />
|
<Route path="/fakebook/photo/:userID/:n" component={PhotoViewer} />
|
||||||
|
|
||||||
{/* Watch (video feed) ----------------------------------------- */}
|
{/* Watch (video feed) ----------------------------------------- */}
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path='/fakebook/watch'
|
path="/fakebook/watch"
|
||||||
render={(props) => <HomePage {...props} className='pt-5' />}
|
render={(props) => <HomePage {...props} className="pt-5" />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* User profile ----------------------------------------------- */}
|
{/* User profile ----------------------------------------------- */}
|
||||||
|
|
||||||
<Route path='/fakebook/:userName' component={Profile} />
|
<Route path="/fakebook/:userName" component={Profile} />
|
||||||
|
|
||||||
{/* News-feed root --------------------------------------------- */}
|
{/* News-feed root --------------------------------------------- */}
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path='/fakebook'
|
path="/fakebook"
|
||||||
exact
|
exact
|
||||||
render={(props) => <HomePage {...props} className='pt-5' />}
|
render={(props) => <HomePage {...props} className="pt-5" />}
|
||||||
/>
|
/>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Router>
|
</Router>
|
||||||
|
|
Loading…
Reference in New Issue