From c49f53257c73359c5e7e40eb6d9195dfc24e4dc7 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 27 Apr 2022 15:14:35 -0400 Subject: [PATCH] Update dialog history handling --- src/components/appRouter.js | 9 ++-- src/components/dialogHelper/dialogHelper.js | 54 +++++++++++---------- src/scripts/routes.js | 5 -- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/components/appRouter.js b/src/components/appRouter.js index a75d8823df..2119d2095e 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -11,7 +11,7 @@ import ServerConnections from './ServerConnections'; import alert from './alert'; import reactControllerFactory from './reactControllerFactory'; -const history = createHashHistory(); +export const history = createHashHistory(); /** * Page types of "no return" (when "Go back" should behave differently, probably quitting the application). @@ -20,14 +20,13 @@ const START_PAGE_TYPES = ['home', 'login', 'selectserver']; class AppRouter { allRoutes = new Map(); - currentRouteInfo; + currentRouteInfo = { route: {} }; currentViewLoadRequest; firstConnectionResult; forcedLogoutMsg; msgTimeout; promiseShow; resolveOnNextShow; - previousRoute = {}; constructor() { document.addEventListener('viewshow', () => this.onViewShow()); @@ -482,9 +481,9 @@ class AppRouter { #getHandler(route) { return (ctx, next) => { - const ignore = route.dummyRoute === true || this.previousRoute.dummyRoute === true; - this.previousRoute = route; + const ignore = ctx.path === this.currentRouteInfo.path; if (ignore) { + console.debug('[appRouter] path did not change, ignoring route change'); // Resolve 'show' promise this.onViewShow(); return; diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index 59b249b8f5..aa41043476 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -1,4 +1,4 @@ -import { appRouter } from '../appRouter'; +import { history } from '../appRouter'; import focusManager from '../focusManager'; import browser from '../../scripts/browser'; import layoutManager from '../layoutManager'; @@ -49,17 +49,19 @@ import '../../assets/css/scrollstyles.scss'; self.originalUrl = window.location.href; const activeElement = document.activeElement; let removeScrollLockOnClose = false; + let unlisten; - function onHashChange() { - const isBack = self.originalUrl === window.location.href; + function onHashChange({ location }) { + const dialogs = location.state?.dialogs || []; + const shouldClose = !dialogs.includes(hash); - if (isBack || !isOpened(dlg)) { - window.removeEventListener('popstate', onHashChange); + if ((shouldClose || !isOpened(dlg)) && unlisten) { + unlisten(); } - if (isBack) { + if (shouldClose) { self.closedByBack = true; - closeDialog(dlg); + close(dlg); } } @@ -68,7 +70,7 @@ import '../../assets/css/scrollstyles.scss'; self.closedByBack = true; e.preventDefault(); e.stopPropagation(); - closeDialog(dlg); + close(dlg); } } @@ -77,7 +79,9 @@ import '../../assets/css/scrollstyles.scss'; inputManager.off(dlg, onBackCommand); } - window.removeEventListener('popstate', onHashChange); + if (unlisten) { + unlisten(); + } removeBackdrop(dlg); dlg.classList.remove('opened'); @@ -86,10 +90,10 @@ import '../../assets/css/scrollstyles.scss'; document.body.classList.remove('noScroll'); } - if (!self.closedByBack && isHistoryEnabled(dlg)) { - const state = window.history.state || {}; - if (state.dialogId === hash) { - appRouter.back(); + if (isHistoryEnabled(dlg)) { + const state = history.location.state || {}; + if (state.dialogs?.length > 0 && state.dialogs[0] === hash) { + history.back(); } } @@ -144,9 +148,19 @@ import '../../assets/css/scrollstyles.scss'; animateDialogOpen(dlg); if (isHistoryEnabled(dlg)) { - appRouter.show(`/dialog?dlg=${hash}`, { dialogId: hash }); + const state = history.location.state || {}; + const dialogs = state.dialogs || []; + dialogs.push(hash); - window.addEventListener('popstate', onHashChange); + history.push( + `${history.location.pathname}${history.location.search}`, + { + ...state, + dialogs + } + ); + + unlisten = history.listen(onHashChange); } else { inputManager.on(dlg, onBackCommand); } @@ -213,16 +227,6 @@ import '../../assets/css/scrollstyles.scss'; } export function close(dlg) { - if (isOpened(dlg)) { - if (isHistoryEnabled(dlg)) { - appRouter.back(); - } else { - closeDialog(dlg); - } - } - } - - function closeDialog(dlg) { if (!dlg.classList.contains('hide')) { dlg.dispatchEvent(new CustomEvent('closing', { bubbles: false, diff --git a/src/scripts/routes.js b/src/scripts/routes.js index 6fd437d1cd..a96ab7a30d 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -560,11 +560,6 @@ import { appRouter } from '../components/appRouter'; serverRequest: true }); - defineRoute({ - path: '/dialog', - dummyRoute: true - }); - defineRoute({ path: '/', autoFocus: false,