From df754f4f4115e3786f89e58c53e288390fb9b97f Mon Sep 17 00:00:00 2001 From: hristoterezov Date: Mon, 26 Feb 2018 16:50:27 -0600 Subject: [PATCH] fix(reload): Preserve URL params on reload/redirect. --- conference.js | 16 +++++---- modules/UI/authentication/AuthHandler.js | 2 ++ modules/UI/util/UIUtil.js | 8 +++++ modules/util/helpers.js | 18 ---------- react/features/app/actions.js | 42 ++++++++++++++++++++++++ react/features/overlay/actions.js | 9 ++--- 6 files changed, 64 insertions(+), 31 deletions(-) diff --git a/conference.js b/conference.js index 4ba1584da2..a2d0c46b00 100644 --- a/conference.js +++ b/conference.js @@ -7,7 +7,7 @@ import Recorder from './modules/recorder/Recorder'; import mediaDeviceHelper from './modules/devices/mediaDeviceHelper'; -import { reload, reportError } from './modules/util/helpers'; +import { reportError } from './modules/util/helpers'; import * as RemoteControlEvents from './service/remotecontrol/RemoteControlEvents'; @@ -24,6 +24,10 @@ import { initAnalytics, sendAnalytics } from './react/features/analytics'; +import { + redirectWithStoredParams, + reloadWithStoredParams +} from './react/features/app'; import EventEmitter from 'events'; @@ -216,7 +220,7 @@ function maybeRedirectToWelcomePage(options) { // save whether current user is guest or not, before navigating // to close page window.sessionStorage.setItem('guest', isGuest); - assignWindowLocationPathname(`static/${ + redirectToStaticPage(`static/${ options.feedbackSubmitted ? 'close.html' : 'close2.html'}`); return; @@ -234,7 +238,7 @@ function maybeRedirectToWelcomePage(options) { if (config.enableWelcomePage) { setTimeout( () => { - assignWindowLocationPathname('./'); + APP.store.dispatch(redirectWithStoredParams('/')); }, 3000); } @@ -250,7 +254,7 @@ function maybeRedirectToWelcomePage(options) { * assigning it to window.location.pathname. * @return {void} */ -function assignWindowLocationPathname(pathname) { +function redirectToStaticPage(pathname) { const windowLocation = window.location; let newPathname = pathname; @@ -310,7 +314,7 @@ class ConferenceConnector { case JitsiConferenceErrors.NOT_ALLOWED_ERROR: { // let's show some auth not allowed page - assignWindowLocationPathname('static/authError.html'); + redirectToStaticPage('static/authError.html'); break; } @@ -378,7 +382,7 @@ class ConferenceConnector { break; case JitsiConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS: - reload(); + APP.store.dispatch(reloadWithStoredParams()); break; default: diff --git a/modules/UI/authentication/AuthHandler.js b/modules/UI/authentication/AuthHandler.js index a8940c7573..177c9e7016 100644 --- a/modules/UI/authentication/AuthHandler.js +++ b/modules/UI/authentication/AuthHandler.js @@ -66,6 +66,8 @@ function doExternalAuth(room, lockPassword) { * @param {string} [roomName] the name of the conference room. */ function redirectToTokenAuthService(roomName) { + // FIXME: This method will not preserve the other URL params that were + // originally passed. UIUtil.redirect(getTokenAuthUrl(roomName, false)); } diff --git a/modules/UI/util/UIUtil.js b/modules/UI/util/UIUtil.js index 6b93cfbae0..edb2567ceb 100644 --- a/modules/UI/util/UIUtil.js +++ b/modules/UI/util/UIUtil.js @@ -217,6 +217,14 @@ const UIUtil = { } }, + /** + * Redirects to a given URL. + * + * @param {string} url - The redirect URL. + * NOTE: Currently used to redirect to 3rd party location for + * authentication. In most cases redirectWithStoredParams action must be + * used instead of this method in order to preserve curent URL params. + */ redirect(url) { window.location.href = url; }, diff --git a/modules/util/helpers.js b/modules/util/helpers.js index 5e93386cd3..d8fcf4dfc1 100644 --- a/modules/util/helpers.js +++ b/modules/util/helpers.js @@ -16,24 +16,6 @@ export function createDeferred() { return deferred; } -/** - * Reload page. - */ -export function reload() { - window.location.reload(); -} - -/** - * Redirects to a specific new URL by replacing the current location (in the - * history). - * - * @param {string} url the URL pointing to the location where the user should - * be redirected to. - */ -export function replace(url) { - window.location.replace(url); -} - /** * Prints the error and reports it to the global error handler. * diff --git a/react/features/app/actions.js b/react/features/app/actions.js index 6f0deb3d0e..79167cb870 100644 --- a/react/features/app/actions.js +++ b/react/features/app/actions.js @@ -24,6 +24,48 @@ export function appNavigate(uri: ?string) { _appNavigateToOptionalLocation(dispatch, getState, parseURIString(uri)); } +/** + * Redirects to another page generated by replacing the path in the original URL + * with the given path. + * + * @param {(string)} pathname - The path to navigate to. + * @returns {Function} + */ +export function redirectWithStoredParams(pathname: string) { + return (dispatch: Dispatch<*>, getState: Function) => { + const { locationURL } = getState()['features/base/connection']; + const newLocationURL = new URL(locationURL.href); + + newLocationURL.pathname = pathname; + window.location.assign(newLocationURL.toString()); + }; +} + +/** + * Reloads the page by restoring the original URL. + * + * @returns {Function} + */ +export function reloadWithStoredParams() { + return (dispatch: Dispatch<*>, getState: Function) => { + const { locationURL } = getState()['features/base/connection']; + const windowLocation = window.location; + const oldSearchString = windowLocation.search; + + windowLocation.replace(locationURL.toString()); + + if (window.self !== window.top + && locationURL.search === oldSearchString) { + // NOTE: Assuming that only the hash or search part of the URL will + // be changed! + // location.reload will not trigger redirect/reload for iframe when + // only the hash params are changed. That's why we need to call + // reload in addition to replace. + windowLocation.reload(); + } + }; +} + /** * Triggers an in-app navigation to a specific location URI. * diff --git a/react/features/overlay/actions.js b/react/features/overlay/actions.js index a751c5c079..6ea7020cd3 100644 --- a/react/features/overlay/actions.js +++ b/react/features/overlay/actions.js @@ -1,6 +1,5 @@ -import { appNavigate } from '../app'; +import { appNavigate, reloadWithStoredParams } from '../app'; import { toURLString } from '../base/util'; -import { reload, replace } from '../../../modules/util/helpers'; import { MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED, @@ -44,12 +43,8 @@ export function _reloadNow() { if (navigator.product === 'ReactNative') { dispatch(appNavigate(toURLString(locationURL))); - } else if (window.self === window.top) { - replace(locationURL); } else { - // In an iframe reload with the reload() utility because the - // replace() utility does not work on an iframe. - reload(); + dispatch(reloadWithStoredParams()); } }; }