feat: refine navigation protection to only warn when leaving the app

This commit is contained in:
ergosteur
2026-03-07 02:41:16 -05:00
parent 9e306eb85e
commit 67f7750157

View File

@@ -629,39 +629,38 @@ export default function App() {
refreshCachedArchives(); refreshCachedArchives();
}, [refreshCachedArchives]); }, [refreshCachedArchives]);
// Intercept back button and page exit when in an archive // Intercept back button and page exit
useEffect(() => { useEffect(() => {
const inArchive = allPosts.length > 0; const hasData = allPosts.length > 0;
const handleBeforeUnload = (e: BeforeUnloadEvent) => { const handleBeforeUnload = (e: BeforeUnloadEvent) => {
if (inArchive) { // Always show warning if data is loaded and browser tries to UNLOAD (refresh/close/navigate away)
if (hasData) {
const message = 'Are you sure you want to leave? Your current archive session will be cleared.'; const message = 'Are you sure you want to leave? Your current archive session will be cleared.';
e.preventDefault(); e.preventDefault();
e.returnValue = message; // Standard for most browsers e.returnValue = message;
return message; // For some older browsers return message;
} }
}; };
const handlePopState = (e: PopStateEvent) => { const handlePopState = (e: PopStateEvent) => {
if (inArchive) { if (allPosts.length > 0) {
if (window.confirm('Exit current archive and return to explorer?')) { // If we are IN an archive, the first "Back" just takes us to explorer
// Exit the archive
setAllPosts([]); setAllPosts([]);
setAllStories([]); setAllStories([]);
setCurrentArchive(null); setCurrentArchive(null);
resetProfileState(); resetProfileState();
} else { // We don't pushState here, so the NEXT "Back" will actually try to leave the page
// Push the state back so the URL stays the same and we can intercept again // and thus trigger the handleBeforeUnload warning.
window.history.pushState(null, '');
}
} }
}; };
if (inArchive) {
window.addEventListener('beforeunload', handleBeforeUnload); window.addEventListener('beforeunload', handleBeforeUnload);
window.addEventListener('popstate', handlePopState); window.addEventListener('popstate', handlePopState);
// Add a history entry so the back button has something to pop
window.history.pushState(null, ''); if (hasData) {
// Create a history entry so the "Back" button can be intercepted once
window.history.pushState({ inApp: true }, '');
} }
return () => { return () => {