From 856732ababa7ce3277301fb6f38520b3d9f2597e Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Sun, 15 Jan 2017 13:05:17 -0600 Subject: [PATCH] Preserve URLs --- react/features/app/components/AbstractApp.js | 81 ++++++++++++++----- react/features/app/components/App.web.js | 28 ++++--- react/features/base/conference/actions.js | 6 +- react/features/base/conference/reducer.js | 5 +- react/features/base/connection/actions.web.js | 4 +- react/index.web.js | 3 +- 6 files changed, 89 insertions(+), 38 deletions(-) diff --git a/react/features/app/components/AbstractApp.js b/react/features/app/components/AbstractApp.js index 4d766a2a2..fa1ff83bc 100644 --- a/react/features/app/components/AbstractApp.js +++ b/react/features/app/components/AbstractApp.js @@ -11,18 +11,6 @@ import { appWillUnmount } from '../actions'; -/** - * Default config. - * - * @type {Object} - */ -const DEFAULT_CONFIG = { - configLocation: './config.js', - hosts: { - domain: 'meet.jit.si' - } -}; - /** * Base (abstract) class for main App component. * @@ -57,12 +45,7 @@ export class AbstractApp extends Component { dispatch(localParticipantJoined()); - const config - = typeof this.props.config === 'object' - ? this.props.config - : DEFAULT_CONFIG; - - this._openURL(this.props.url || `https://${config.hosts.domain}`); + this._openURL(this._getDefaultURL()); } /** @@ -116,6 +99,68 @@ export class AbstractApp extends Component { return React.createElement(component, { ...thisProps, ...props }); } + /** + * Gets the default URL to be opened when this App mounts. + * + * @private + * @returns {string} The default URL to be opened when this App mounts. + */ + _getDefaultURL() { + // If the URL was explicitly specified to the React Component, then open + // it. + let url = this.props.url; + + if (url) { + return url; + } + + // If the execution environment provides a Location abstraction, then + // this App at already at that location but it must be made aware of the + // fact. + const windowLocation = this._getWindowLocation(); + + if (windowLocation) { + url = windowLocation.toString(); + if (url) { + return url; + } + } + + // By default, open the domain configured in the configuration file + // which may be the domain at which the whole server infrastructure is + // deployed. + const config = this.props.config; + + if (typeof config === 'object') { + const hosts = config.hosts; + + if (typeof hosts === 'object') { + const domain = hosts.domain; + + if (domain) { + return `https://${domain}`; + } + } + } + + return 'https://meet.jit.si'; + } + + /** + * Gets a Location object from the window with information about the current + * location of the document. Explicitly defined to allow extenders to + * override because React Native does not usually have a location property + * on its window unless debugging remotely in which case the browser that is + * the remote debugger will provide a location property on the window. + * + * @protected + * @returns {Location} A Location object with information about the current + * location of the document. + */ + _getWindowLocation() { + return undefined; + } + /** * Navigates this AbstractApp to (i.e. opens) a specific URL. * diff --git a/react/features/app/components/App.web.js b/react/features/app/components/App.web.js index 942c4884a..52679db86 100644 --- a/react/features/app/components/App.web.js +++ b/react/features/app/components/App.web.js @@ -1,9 +1,8 @@ import React from 'react'; import { Provider } from 'react-redux'; import { browserHistory, Route, Router } from 'react-router'; -import { push, syncHistoryWithStore } from 'react-router-redux'; +import { push, replace, syncHistoryWithStore } from 'react-router-redux'; -import { getDomain } from '../../base/connection'; import { RouteRegistry } from '../../base/navigator'; import { appInit } from '../actions'; @@ -73,6 +72,16 @@ export class App extends AbstractApp { ); } + /** + * Gets a Location object from the window with information about the current + * location of the document. + * + * @inheritdoc + */ + _getWindowLocation() { + return window.location; + } + /** * Navigates to a specific Route (via platform-specific means). * @@ -91,7 +100,10 @@ export class App extends AbstractApp { /:room/g, store.getState()['features/base/conference'].room); - return store.dispatch(push(path)); + return ( + store.dispatch( + (window.location.pathname === path ? replace : push)( + path))); } /** @@ -117,15 +129,7 @@ export class App extends AbstractApp { // Our Router configuration (at the time of this writing) is such that // each Route corresponds to a single URL. Hence, entering into a Route // is like opening a URL. - - // XXX In order to unify work with URLs in web and native environments, - // we will construct URL here with correct domain from config. - const currentDomain = getDomain(this.props.store.getState); - const url - = new URL(window.location.pathname, `https://${currentDomain}`) - .toString(); - - this._openURL(url); + this._openURL(window.location.toString()); } /** diff --git a/react/features/base/conference/actions.js b/react/features/base/conference/actions.js index c26ef4b52..4eb5af95f 100644 --- a/react/features/base/conference/actions.js +++ b/react/features/base/conference/actions.js @@ -182,7 +182,11 @@ export function createConference() { // TODO Take options from config. const conference - = connection.initJitsiConference(room, { openSctp: true }); + = connection.initJitsiConference( + + // XXX Lib-jitsi-meet does not accept uppercase letters. + room.toLowerCase(), + { openSctp: true }); _addConferenceListeners(conference, dispatch); diff --git a/react/features/base/conference/reducer.js b/react/features/base/conference/reducer.js index 7343a5a06..5d623e0fa 100644 --- a/react/features/base/conference/reducer.js +++ b/react/features/base/conference/reducer.js @@ -245,10 +245,7 @@ function _setPassword(state, action) { function _setRoom(state, action) { let room = action.room; - if (isRoomValid(room)) { - // XXX Lib-jitsi-meet does not accept uppercase letters. - room = room.toLowerCase(); - } else { + if (!isRoomValid(room)) { // Technically, there are multiple values which don't represent valid // room names. Practically, each of them is as bad as the rest of them // because we can't use any of them to join a conference. diff --git a/react/features/base/connection/actions.web.js b/react/features/base/connection/actions.web.js index e8a65f638..dc432eac2 100644 --- a/react/features/base/connection/actions.web.js +++ b/react/features/base/connection/actions.web.js @@ -16,7 +16,9 @@ const logger = require('jitsi-meet-logger').getLogger(__filename); export function connect() { return (dispatch, getState) => { const state = getState(); - const room = state['features/base/conference'].room; + + // XXX Lib-jitsi-meet does not accept uppercase letters. + const room = state['features/base/conference'].room.toLowerCase(); // XXX For web based version we use conference initialization logic // from the old app (at the moment of writing). diff --git a/react/index.web.js b/react/index.web.js index 4a18ed22e..e24f596d0 100644 --- a/react/index.web.js +++ b/react/index.web.js @@ -56,8 +56,7 @@ document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( , + store = { store } />, document.getElementById('react')); });