Debug when user stays online at closing browser

This commit is contained in:
Alex Erdei 2025-05-07 22:46:45 +01:00
parent b2affa91c7
commit 545413d2ce
2 changed files with 172 additions and 132 deletions

View File

@ -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 ---------------------------------------------------------------
const patchOnline = async (on) => {
// patchOnline(on, keep = false) ← keep=true will add keepalive: true
const patchOnline = async (on, keep = false) => {
if (!authUser) return;
try {
await $fetch(USERS_URL, {
await fetch(USERS_URL, {
method: "PUT",
headers: { "Content-Type": "application/json", ...authHeader() },
body: JSON.stringify({ user_id: authUser, isOnline: on ? 1 : 0 }),
...(keep ? { keepalive: true } : {}),
});
} catch (e) {
console.warn("[online] PUT failed:", e.message);
@ -191,6 +179,77 @@ export const currentUserOnline = () => patchOnline(true);
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 -----------------------------------------
const bootstrapSession = async (uid) => {

View File

@ -86,7 +86,7 @@ const UserAccount = () => {
/* -------------------------------------------------- */
/* Firestore-like subscriptions & online/offline flag */
/* Firestore-like subscriptions */
/* -------------------------------------------------- */
@ -101,21 +101,6 @@ const UserAccount = () => {
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 */
return () => {
@ -124,10 +109,6 @@ const UserAccount = () => {
unsubUsers();
unsubPosts();
window.removeEventListener("beforeunload", beforeUnload);
document.removeEventListener("visibilitychange", visChange);
};
}, []);
@ -165,8 +146,8 @@ const UserAccount = () => {
/* -------------------------------------------------- */
return (
<div className='bg-200 vw-100 main-container overflow-hidden'>
<Container className='w-100 p-0' fluid>
<div className="bg-200 vw-100 main-container overflow-hidden">
<Container className="w-100 p-0" fluid>
<Router>
<RouteStateSync />
@ -175,29 +156,29 @@ const UserAccount = () => {
<Switch>
{/* Friends list ------------------------------------------------ */}
<Route path='/fakebook/friends/list' component={FriendsListPage} />
<Route path="/fakebook/friends/list" component={FriendsListPage} />
{/* Single photo ----------------------------------------------- */}
<Route path='/fakebook/photo/:userID/:n' component={PhotoViewer} />
<Route path="/fakebook/photo/:userID/:n" component={PhotoViewer} />
{/* Watch (video feed) ----------------------------------------- */}
<Route
path='/fakebook/watch'
render={(props) => <HomePage {...props} className='pt-5' />}
path="/fakebook/watch"
render={(props) => <HomePage {...props} className="pt-5" />}
/>
{/* User profile ----------------------------------------------- */}
<Route path='/fakebook/:userName' component={Profile} />
<Route path="/fakebook/:userName" component={Profile} />
{/* News-feed root --------------------------------------------- */}
<Route
path='/fakebook'
path="/fakebook"
exact
render={(props) => <HomePage {...props} className='pt-5' />}
render={(props) => <HomePage {...props} className="pt-5" />}
/>
</Switch>
</Router>