diff --git a/bigbluebutton-html5/.meteor/packages b/bigbluebutton-html5/.meteor/packages
index 66027107eeef83d267304a3bff0bb92dd17f6ca6..a0f2677c4c0edd35479d857cb77bcf15a282cd30 100644
--- a/bigbluebutton-html5/.meteor/packages
+++ b/bigbluebutton-html5/.meteor/packages
@@ -23,3 +23,4 @@ shell-server@0.3.0
 http@1.3.0
 dynamic-import@0.2.0
 rocketchat:streamer
+session
diff --git a/bigbluebutton-html5/client/main.jsx b/bigbluebutton-html5/client/main.jsx
index f38a45090020abe155247467e8768f2c81b91027..bbcfaa44921b690400c9d2c989d55f4d7429cdd1 100755
--- a/bigbluebutton-html5/client/main.jsx
+++ b/bigbluebutton-html5/client/main.jsx
@@ -1,19 +1,43 @@
 /* eslint no-unused-vars: 0 */
 import React from 'react';
 import { Meteor } from 'meteor/meteor';
+import { Session } from 'meteor/session';
 import { render } from 'react-dom';
-import renderRoutes from '/imports/startup/client/routes';
 import logger from '/imports/startup/client/logger';
+import { joinRouteHandler, authenticatedRouteHandler } from '/imports/startup/client/auth';
+import Base from '/imports/startup/client/base';
+import LoadingScreen from '/imports/ui/components/loading-screen/component';
 
 Meteor.startup(() => {
-  render(renderRoutes(), document.getElementById('app'));
+  render(<LoadingScreen />, document.getElementById('app'));
+
   // Logs all uncaught exceptions to the client logger
   window.addEventListener('error', (e) => {
-    const stack = e.error.stack;
+    const { stack } = e.error;
     let message = e.error.toString();
 
     // Checks if stack includes the message, if not add the two together.
-    (stack.includes(message)) ? message = stack : message += `\n${stack}`;
+    if (stack.includes(message)) {
+      message = stack;
+    } else {
+      message += `\n${stack}`;
+    }
     logger.error(message);
   });
+
+  // TODO make this a Promise
+  joinRouteHandler((value, error) => {
+    if (error) {
+      logger.error(`User faced [${value}] on main.joinRouteHandler. Error was:`, JSON.stringify(error));
+    } else {
+      logger.info(`User successfully went through main.joinRouteHandler with [${value}].`);
+    }
+    authenticatedRouteHandler(() => {
+      // set defaults
+      Session.set('isChatOpen', false);
+      Session.set('idChatOpen', '');
+      Session.set('isMeetingEnded', false);
+      render(<Base />, document.getElementById('app'));
+    });
+  });
 });
diff --git a/bigbluebutton-html5/imports/api/acl/Acl.js b/bigbluebutton-html5/imports/api/acl/Acl.js
index b5fcf8b91b6bfc01057f5a2e91d041bded544c3c..4485dee8884662be3b4991e271d166ad360579cd 100644
--- a/bigbluebutton-html5/imports/api/acl/Acl.js
+++ b/bigbluebutton-html5/imports/api/acl/Acl.js
@@ -28,7 +28,7 @@ export default class Acl {
       authToken,
       validated: true,
       connectionStatus: 'online',
-      // TODO: We cant check for approved until we move subscription login out of <Base />
+      // TODO: We cant check for approved until we move subscription login out of <Base /> // TODO 4767
       // approved: true,
     });
 
diff --git a/bigbluebutton-html5/imports/startup/client/auth.js b/bigbluebutton-html5/imports/startup/client/auth.js
index ea5de6e4964e3941e68a0b336a73ceb379dd0db4..6f50e762c62d406821a8d7f65d603220c1b58bef 100755
--- a/bigbluebutton-html5/imports/startup/client/auth.js
+++ b/bigbluebutton-html5/imports/startup/client/auth.js
@@ -3,16 +3,23 @@ import { setCustomLogoUrl } from '/imports/ui/components/user-list/service';
 import { log, makeCall } from '/imports/ui/services/api';
 import deviceInfo from '/imports/utils/deviceInfo';
 import logger from '/imports/startup/client/logger';
+import { Session } from 'meteor/session';
 
 // disconnected and trying to open a new connection
 const STATUS_CONNECTING = 'connecting';
 
-export function joinRouteHandler(nextState, replace, callback) {
-  const { sessionToken } = nextState.location.query;
+const setError = (errorCode) => {
+  Session.set('hasError', true);
+  Session.set('codeError', errorCode);
+};
 
-  if (!nextState || !sessionToken) {
-    replace({ pathname: '/error/404' });
-    callback();
+export function joinRouteHandler(callback) {
+  const urlParams = new URLSearchParams(window.location.search);
+  const sessionToken = urlParams.get('sessionToken');
+
+  if (!sessionToken) {
+    setError('404');
+    callback('failed - no sessionToken', urlParams);
   }
 
   // Old credentials stored in memory were being used when joining a new meeting
@@ -30,42 +37,40 @@ export function joinRouteHandler(nextState, replace, callback) {
       } = response;
 
       if (returncode === 'FAILED') {
-        replace({ pathname: '/error/404' });
-        callback();
-      }
-
-      setCustomLogoUrl(customLogoURL);
-
-      if (customdata.length) {
-        makeCall('addUserSettings', meetingID, internalUserID, customdata);
+        setError('404');
+        callback('failed during enter API call', response);
+      } else {
+        setCustomLogoUrl(customLogoURL);
+
+        if (customdata.length) {
+          makeCall('addUserSettings', meetingID, internalUserID, customdata);
+        }
+
+        Auth.set(
+          meetingID, internalUserID, authToken, logoutUrl,
+          sessionToken, fullname, externUserID, confname,
+        );
+
+        Session.set('isUserListOpen', deviceInfo.type().isPhone);
+        const userInfo = window.navigator;
+
+        // Browser information is sent once on startup
+        // Sent here instead of Meteor.startup, as the
+        // user might not be validated by then, thus user's data
+        // would not be sent with this information
+        const clientInfo = {
+          language: userInfo.language,
+          userAgent: userInfo.userAgent,
+          screenSize: { width: window.screen.width, height: window.screen.height },
+          windowSize: { width: window.innerWidth, height: window.innerHeight },
+          bbbVersion: Meteor.settings.public.app.bbbServerVersion,
+          location: window.location.href,
+        };
+
+        logger.info(clientInfo);
+
+        callback('all is good', null);
       }
-
-      Auth.set(
-        meetingID, internalUserID, authToken, logoutUrl,
-        sessionToken, fullname, externUserID, confname,
-      );
-
-      const path = deviceInfo.type().isPhone ? '/' : '/users';
-      const userInfo = window.navigator;
-
-      // Browser information is sent once on startup
-      // Sent here instead of Meteor.startup, as the
-      // user might not be validiated by then, thus user's data
-      // would not be sent with this information
-      const clientInfo = {
-        language: userInfo.language,
-        userAgent: userInfo.userAgent,
-        screenSize: { width: window.screen.width, height: window.screen.height },
-        windowSize: { width: window.innerWidth, height: window.innerHeight },
-        bbbVersion: Meteor.settings.public.app.bbbServerVersion,
-        location: window.location.href,
-      };
-
-      replace({ pathname: path });
-
-      logger.info(clientInfo);
-
-      return callback();
     });
 }
 
@@ -112,7 +117,7 @@ function _addReconnectObservable() {
   });
 }
 
-export function authenticatedRouteHandler(nextState, replace, callback) {
+export function authenticatedRouteHandler(callback) {
   if (Auth.loggedIn) {
     callback();
   }
@@ -123,7 +128,7 @@ export function authenticatedRouteHandler(nextState, replace, callback) {
     .then(callback)
     .catch((reason) => {
       log('error', reason);
-      replace({ pathname: `/error/${reason.error}` });
+      setError(reason.error);
       callback();
     });
 }
diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx
index 23d9e8f0616c4b463dacba173347c6061ec6651d..e5da55a01d98705a1597fe0c448377722ef283bc 100755
--- a/bigbluebutton-html5/imports/startup/client/base.jsx
+++ b/bigbluebutton-html5/imports/startup/client/base.jsx
@@ -1,6 +1,5 @@
 import React, { Component } from 'react';
 import { withTracker } from 'meteor/react-meteor-data';
-import { withRouter } from 'react-router';
 import PropTypes from 'prop-types';
 import Auth from '/imports/ui/services/auth';
 import AppContainer from '/imports/ui/components/app/container';
@@ -14,6 +13,7 @@ import Users from '/imports/api/users';
 import Annotations from '/imports/api/annotations';
 import AnnotationsLocal from '/imports/ui/components/whiteboard/service';
 import GroupChat from '/imports/api/group-chat';
+import { Session } from 'meteor/session';
 import IntlStartup from './intl';
 
 const CHAT_CONFIG = Meteor.settings.public.chat;
@@ -21,20 +21,16 @@ const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id;
 const PUBLIC_CHAT_TYPE = CHAT_CONFIG.type_public;
 
 const propTypes = {
-  error: PropTypes.object,
-  errorCode: PropTypes.number,
   subscriptionsReady: PropTypes.bool.isRequired,
   locale: PropTypes.string,
-  endedCode: PropTypes.string,
   approved: PropTypes.bool,
+  meetingEnded: PropTypes.bool,
 };
 
 const defaultProps = {
-  error: undefined,
-  errorCode: undefined,
   locale: undefined,
-  endedCode: undefined,
   approved: undefined,
+  meetingEnded: false,
 };
 
 class Base extends Component {
@@ -43,11 +39,9 @@ class Base extends Component {
 
     this.state = {
       loading: false,
-      error: props.error || null,
     };
 
     this.updateLoadingState = this.updateLoadingState.bind(this);
-    this.updateErrorState = this.updateErrorState.bind(this);
   }
 
   componentWillUpdate() {
@@ -63,29 +57,23 @@ class Base extends Component {
     });
   }
 
-  updateErrorState(error = null) {
-    this.setState({
-      error,
-    });
-  }
-
   renderByState() {
-    const { updateLoadingState, updateErrorState } = this;
-    const stateControls = { updateLoadingState, updateErrorState };
+    const { updateLoadingState } = this;
+    const stateControls = { updateLoadingState };
 
-    const { loading, error } = this.state;
+    const { loading } = this.state;
 
-    const { subscriptionsReady, errorCode } = this.props;
-    const { endedCode } = this.props.params;
+    const codeError = Session.get('codeError');
+    const { subscriptionsReady, meetingEnded } = this.props;
 
-    if (endedCode) {
+    if (meetingEnded) {
       AudioManager.exitAudio();
-      return (<MeetingEnded code={endedCode} />);
+      return (<MeetingEnded code={Session.get('codeError')} />);
     }
 
-    if (error || errorCode) {
-      logger.error(`User could not log in HTML5, hit ${errorCode}`);
-      return (<ErrorScreen code={errorCode}>{error}</ErrorScreen>);
+    if (codeError) {
+      logger.error(`User could not log in HTML5, hit ${codeError}`);
+      return (<ErrorScreen code={codeError} />);
     }
 
     if (loading || !subscriptionsReady) {
@@ -101,9 +89,9 @@ class Base extends Component {
   }
 
   render() {
-    const { updateLoadingState, updateErrorState } = this;
+    const { updateLoadingState } = this;
     const { locale } = this.props;
-    const stateControls = { updateLoadingState, updateErrorState };
+    const stateControls = { updateLoadingState };
 
     return (
       <IntlStartup locale={locale} baseControls={stateControls}>
@@ -122,9 +110,7 @@ const SUBSCRIPTIONS_NAME = [
   'group-chat', 'presentation-pods', 'users-settings',
 ];
 
-const BaseContainer = withRouter(withTracker(({ params, router }) => {
-  if (params.errorCode) return params;
-
+const BaseContainer = withTracker(() => {
   const { locale } = Settings.application;
   const { credentials, loggedIn } = Auth;
   const { meetingId, requesterUserId } = credentials;
@@ -139,7 +125,8 @@ const BaseContainer = withRouter(withTracker(({ params, router }) => {
   const subscriptionErrorHandler = {
     onError: (error) => {
       logger.error(error);
-      return router.push('/logout');
+      Session.set('isMeetingEnded', true);
+      Session.set('codeError', error.error);
     },
   };
 
@@ -179,11 +166,12 @@ const BaseContainer = withRouter(withTracker(({ params, router }) => {
   const subscriptionsReady = subscriptionsHandlers.every(handler => handler.ready());
   return {
     approved: Users.findOne({ userId: Auth.userID, approved: true, guest: true }),
+    meetingEnded: Session.get('isMeetingEnded'),
     locale,
     subscriptionsReady,
     annotationsHandler,
     groupChatMessageHandler,
   };
-})(Base));
+})(Base);
 
 export default BaseContainer;
diff --git a/bigbluebutton-html5/imports/startup/client/routes.js b/bigbluebutton-html5/imports/startup/client/routes.js
deleted file mode 100755
index 26f606b4a095c0ac2e3e637c8db70bd66d008802..0000000000000000000000000000000000000000
--- a/bigbluebutton-html5/imports/startup/client/routes.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import React from 'react';
-import { Router, Route, Redirect, IndexRoute, useRouterHistory } from 'react-router';
-import { createHistory } from 'history';
-import PollContainer from '/imports/ui/components/poll/container';
-import LoadingScreen from '/imports/ui/components/loading-screen/component';
-import ChatContainer from '/imports/ui/components/chat/container';
-import UserListContainer from '/imports/ui/components/user-list/container';
-import { joinRouteHandler, logoutRouteHandler, authenticatedRouteHandler } from './auth';
-import Base from './base';
-
-const browserHistory = useRouterHistory(createHistory)({
-  basename: Meteor.settings.public.app.basename,
-});
-
-const disconnect = () => {
-  Meteor.disconnect();
-};
-
-const renderRoutes = () => (
-  <Router history={browserHistory} >
-    <Route path="/logout" onEnter={logoutRouteHandler} />
-    <Route
-      path="/join"
-      component={LoadingScreen}
-      onEnter={joinRouteHandler}
-    />
-    <Route path="/" component={Base} onEnter={authenticatedRouteHandler} >
-      <IndexRoute components={{}} />
-      <Route name="users" path="users" components={{ userList: UserListContainer }} />
-
-      <Route
-        name="poll"
-        path="users/poll"
-        components={{
-          userList: UserListContainer,
-          poll: PollContainer,
-        }}
-      />
-
-      <Route
-        name="chat"
-        path="users/chat/:chatID"
-        components={{
-          userList: UserListContainer,
-          chat: ChatContainer,
-        }}
-      />
-      <Redirect from="users/chat" to="/users/chat/public" />
-    </Route>
-    <Route
-      name="meeting-ended"
-      path="/ended/:endedCode"
-      component={Base}
-      onEnter={disconnect}
-      onLeave={logoutRouteHandler}
-    />
-    <Route
-      name="error"
-      path="/error/:errorCode"
-      component={Base}
-      onEnter={disconnect}
-    />
-    <Redirect from="*" to="/error/404" />
-  </Router>
-);
-
-export default renderRoutes;
diff --git a/bigbluebutton-html5/imports/startup/server/redis.js b/bigbluebutton-html5/imports/startup/server/redis.js
index 768402d784b1963a8e939ae64762b3c9e397ebce..432f34ad61fab2ef3205ef3ef67c6b34e74e552d 100644
--- a/bigbluebutton-html5/imports/startup/server/redis.js
+++ b/bigbluebutton-html5/imports/startup/server/redis.js
@@ -159,6 +159,9 @@ class RedisPubSub {
 
     if (ignoredMessages.includes(channel)
       || ignoredMessages.includes(eventName)) {
+      if (eventName === 'CheckAlivePongSysMsg') {
+        return;
+      }
       this.debug(`${eventName} skipped`);
       return;
     }
diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
index fcfe49ef69251ecabdba7549d878982d64f1160f..0922c5984f01a1280edb7e8727c5d005ffa5b997 100644
--- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import { withTracker } from 'meteor/react-meteor-data';
+import { Session } from 'meteor/session';
 import getFromUserSettings from '/imports/ui/services/users-settings';
 import ActionsBar from './component';
 import Service from './service';
@@ -9,9 +10,18 @@ import { withRouter } from 'react-router';
 
 const ActionsBarContainer = props => <ActionsBar {...props} />;
 
-export default withRouter(withTracker(({ location, router }) => {
-  const togglePollMenu = () => (location.pathname.includes('poll')
-    ? router.push('/') : router.push('/users/poll'));
+export default withRouter(withTracker(({ }) => {
+  const togglePollMenu = () => {
+    if (Session.equals('isChatOpen', true)) Session.set('isChatOpen', false);
+
+    if (Session.equals('isPollOpen', false)) {
+      Session.set('isUserListOpen', true);
+      return Session.set('isPollOpen', true);
+    }
+
+    Session.set('isUserListOpen', true);
+    return Session.set('isPollOpen', false);
+  };
 
   return {
     isUserPresenter: Service.isUserPresenter(),
diff --git a/bigbluebutton-html5/imports/ui/components/app/component.jsx b/bigbluebutton-html5/imports/ui/components/app/component.jsx
index e8b2a3177c7ff7da4d17fdd60bda8c92130d6423..4123616f4ab7f2c0d4436a08dae349decbac4fab 100755
--- a/bigbluebutton-html5/imports/ui/components/app/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/app/component.jsx
@@ -13,6 +13,9 @@ import NotificationsBarContainer from '../notifications-bar/container';
 import AudioContainer from '../audio/container';
 import ChatAlertContainer from '../chat/alert/container';
 import { styles } from './styles';
+import UserListContainer from '../user-list/container';
+import ChatContainer from '../chat/container';
+import PollContainer from '/imports/ui/components/poll/container';
 
 const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
 const USERLIST_COMPACT_WIDTH = 50;
@@ -43,8 +46,9 @@ const propTypes = {
   media: PropTypes.element,
   actionsbar: PropTypes.element,
   closedCaption: PropTypes.element,
-  userList: PropTypes.element,
-  chat: PropTypes.element,
+  userListIsOpen: PropTypes.bool.isRequired,
+  chatIsOpen: PropTypes.bool.isRequired,
+  pollIsOpen: PropTypes.bool.isRequired,
   locale: PropTypes.string,
   intl: intlShape.isRequired,
 };
@@ -56,8 +60,6 @@ const defaultProps = {
   media: null,
   actionsbar: null,
   closedCaption: null,
-  userList: null,
-  chat: null,
   locale: 'en',
 };
 
@@ -106,13 +108,13 @@ class App extends Component {
   }
 
   renderPoll() {
-    const { poll } = this.props;
+    const { pollIsOpen } = this.props;
 
-    if (!poll) return null;
+    if (!pollIsOpen) return null;
 
     return (
       <div className={styles.poll}>
-        {poll}
+        <PollContainer />
       </div>
     );
   }
@@ -154,17 +156,19 @@ class App extends Component {
   }
 
   renderUserList() {
-    const { intl, chatIsOpen } = this.props;
-    let { userList } = this.props;
+    const {
+      intl, chatIsOpen, userListIsOpen,
+    } = this.props;
+
     const { compactUserList } = this.state;
 
-    if (!userList) return null;
+    if (!userListIsOpen) return null;
 
     const userListStyle = {};
     userListStyle[styles.compact] = compactUserList;
-    userList = React.cloneElement(userList, {
-      compact: compactUserList,
-    });
+    // userList = React.cloneElement(userList, {
+    //   compact: compactUserList, // TODO 4767
+    // });
 
     return (
       <div
@@ -172,13 +176,13 @@ class App extends Component {
         aria-label={intl.formatMessage(intlMessages.userListLabel)}
         aria-hidden={chatIsOpen}
       >
-        {userList}
+        <UserListContainer />
       </div>
     );
   }
 
   renderUserListResizable() {
-    const { userList } = this.props;
+    const { userListIsOpen } = this.props;
 
     // Variables for resizing user-list.
     const USERLIST_MIN_WIDTH_PX = 150;
@@ -188,7 +192,7 @@ class App extends Component {
     // decide whether using pixel or percentage unit as a default width for userList
     const USERLIST_DEFAULT_WIDTH = (window.innerWidth * (USERLIST_DEFAULT_WIDTH_RELATIVE / 100.0)) < USERLIST_MAX_WIDTH_PX ? `${USERLIST_DEFAULT_WIDTH_RELATIVE}%` : USERLIST_MAX_WIDTH_PX;
 
-    if (!userList) return null;
+    if (!userListIsOpen) return null;
 
     const resizableEnableOptions = {
       top: false,
@@ -222,29 +226,29 @@ class App extends Component {
   }
 
   renderChat() {
-    const { chat, intl } = this.props;
+    const { intl, chatIsOpen } = this.props;
 
-    if (!chat) return null;
+    if (!chatIsOpen) return null;
 
     return (
       <section
         className={styles.chat}
         aria-label={intl.formatMessage(intlMessages.chatLabel)}
       >
-        {chat}
+        <ChatContainer />
       </section>
     );
   }
 
   renderChatResizable() {
-    const { chat } = this.props;
+    const { chatIsOpen } = this.props;
 
     // Variables for resizing chat.
     const CHAT_MIN_WIDTH = '10%';
     const CHAT_MAX_WIDTH = '25%';
     const CHAT_DEFAULT_WIDTH = '15%';
 
-    if (!chat) return null;
+    if (!chatIsOpen) return null;
 
     const resizableEnableOptions = {
       top: false,
@@ -273,7 +277,7 @@ class App extends Component {
 
   renderMedia() {
     const {
-      media, intl, chatIsOpen, userlistIsOpen,
+      media, intl, chatIsOpen, userListIsOpen,
     } = this.props;
 
     if (!media) return null;
@@ -282,7 +286,7 @@ class App extends Component {
       <section
         className={styles.media}
         aria-label={intl.formatMessage(intlMessages.mediaLabel)}
-        aria-hidden={userlistIsOpen || chatIsOpen}
+        aria-hidden={userListIsOpen || chatIsOpen}
       >
         {media}
         {this.renderClosedCaption()}
@@ -292,7 +296,7 @@ class App extends Component {
 
   renderActionsBar() {
     const {
-      actionsbar, intl, userlistIsOpen, chatIsOpen,
+      actionsbar, intl, userListIsOpen, chatIsOpen,
     } = this.props;
 
     if (!actionsbar) return null;
@@ -301,7 +305,7 @@ class App extends Component {
       <section
         className={styles.actionsbar}
         aria-label={intl.formatMessage(intlMessages.actionsBarLabel)}
-        aria-hidden={userlistIsOpen || chatIsOpen}
+        aria-hidden={userListIsOpen || chatIsOpen}
       >
         {actionsbar}
       </section>
@@ -310,8 +314,9 @@ class App extends Component {
 
   render() {
     const {
-      params, userlistIsOpen, customStyle, customStyleUrl,
+      params, userListIsOpen, customStyle, customStyleUrl,
     } = this.props;
+
     const { enableResize } = this.state;
 
     return (
@@ -324,7 +329,7 @@ class App extends Component {
             {this.renderActionsBar()}
           </div>
           {enableResize ? this.renderUserListResizable() : this.renderUserList()}
-          {userlistIsOpen && enableResize ? <div className={styles.userlistPad} /> : null}
+          {userListIsOpen && enableResize ? <div className={styles.userlistPad} /> : null}
           {enableResize ? this.renderChatResizable() : this.renderChat()}
           {this.renderPoll()}
           {this.renderSidebar()}
@@ -333,7 +338,7 @@ class App extends Component {
         <ModalContainer />
         <AudioContainer />
         <ToastContainer />
-        <ChatAlertContainer currentChatID={params.chatID} />
+        <ChatAlertContainer currentChatID={params} />
         { customStyleUrl ? <link rel="stylesheet" type="text/css" href={customStyleUrl} /> : null }
         { customStyle ? <link rel="stylesheet" type="text/css" href={`data:text/css;charset=UTF-8,${encodeURIComponent(customStyle)}`} /> : null }
       </main>
diff --git a/bigbluebutton-html5/imports/ui/components/app/container.jsx b/bigbluebutton-html5/imports/ui/components/app/container.jsx
index 98cb025c1ef5d83b60b5b06ab044a97d382830a2..63de9a39074c4fd43605b194b6840162d69e85c4 100755
--- a/bigbluebutton-html5/imports/ui/components/app/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/app/container.jsx
@@ -1,6 +1,5 @@
-import React, { cloneElement } from 'react';
+import React from 'react';
 import { withTracker } from 'meteor/react-meteor-data';
-import { withRouter } from 'react-router';
 import { defineMessages, injectIntl } from 'react-intl';
 import PropTypes from 'prop-types';
 import Auth from '/imports/ui/services/auth';
@@ -29,7 +28,6 @@ const propTypes = {
   navbar: PropTypes.node,
   actionsbar: PropTypes.node,
   media: PropTypes.node,
-  location: PropTypes.shape({}).isRequired,
 };
 
 const defaultProps = {
@@ -45,8 +43,12 @@ const intlMessages = defineMessages({
   },
 });
 
+const endMeeting = (code) => {
+  Session.set('codeError', code);
+  Session.set('isMeetingEnded', true);
+};
+
 const AppContainer = (props) => {
-  // inject location on the navbar container
   const {
     navbar,
     actionsbar,
@@ -54,11 +56,9 @@ const AppContainer = (props) => {
     ...otherProps
   } = props;
 
-  const navbarWithLocation = cloneElement(navbar, { location: props.location });
-
   return (
     <App
-      navbar={navbarWithLocation}
+      navbar={navbar}
       actionsbar={actionsbar}
       media={media}
       {...otherProps}
@@ -67,7 +67,7 @@ const AppContainer = (props) => {
 };
 
 
-export default withRouter(injectIntl(withModalMounter(withTracker(({ router, intl, baseControls }) => {
+export default injectIntl(withModalMounter(withTracker(({ intl, baseControls }) => {
   const currentUser = Users.findOne({ userId: Auth.userID });
   const isMeetingBreakout = meetingIsBreakout();
 
@@ -83,7 +83,7 @@ export default withRouter(injectIntl(withModalMounter(withTracker(({ router, int
       const hasNewConnection = 'connectionId' in fields && (fields.connectionId !== Meteor.connection._lastSessionId);
 
       if (fields.ejected || hasNewConnection) {
-        router.push(`/ended/${403}`);
+        endMeeting('403');
       }
     },
   });
@@ -94,7 +94,7 @@ export default withRouter(injectIntl(withModalMounter(withTracker(({ router, int
       if (isMeetingBreakout) {
         Auth.clearCredentials().then(window.close);
       } else {
-        router.push(`/ended/${410}`);
+        endMeeting('410');
       }
     },
   });
@@ -109,12 +109,13 @@ export default withRouter(injectIntl(withModalMounter(withTracker(({ router, int
   return {
     closedCaption: getCaptionsStatus() ? <ClosedCaptionsContainer /> : null,
     fontSize: getFontSize(),
-    userlistIsOpen: window.location.pathname.includes('users'),
-    chatIsOpen: window.location.pathname.includes('chat'),
+    userListIsOpen: Boolean(Session.get('isUserListOpen')),
+    chatIsOpen: Boolean(Session.get('isChatOpen') && Session.get('isUserListOpen')),
+    pollIsOpen: Boolean(Session.get('isPollOpen') && Session.get('isUserListOpen')),
     customStyle: getFromUserSettings('customStyle', false),
     customStyleUrl: getFromUserSettings('customStyleUrl', false),
   };
-})(AppContainer))));
+})(AppContainer)));
 
 AppContainer.defaultProps = defaultProps;
 AppContainer.propTypes = propTypes;
diff --git a/bigbluebutton-html5/imports/ui/components/chat/alert/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/alert/component.jsx
index b84d4ed0c471afc4fa527e700dfbcf7b2962f543..923f1b97d5970f580c99747fc86cad3cc57e089f 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/alert/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/alert/component.jsx
@@ -1,6 +1,7 @@
 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl } from 'react-intl';
+import { Session } from 'meteor/session';
 import _ from 'lodash';
 import UnreadMessages from '/imports/ui/services/unread-messages';
 import ChatAudioAlert from './audio-alert/component';
@@ -113,7 +114,6 @@ class ChatAlert extends Component {
       disableNotify,
       openChats,
       intl,
-      currentChatID,
     } = this.props;
 
     if (disableNotify) return;
@@ -121,7 +121,7 @@ class ChatAlert extends Component {
     const hasUnread = ({ unreadCounter }) => unreadCounter > 0;
     const isNotNotified = ({ id, unreadCounter }) => unreadCounter !== this.state.notified[id];
     const isPrivate = ({ id }) => id !== PUBLIC_KEY;
-    const thisChatClosed = ({ id }) => id !== currentChatID;
+    const thisChatClosed = ({ id }) => !Session.equals('idChatOpen', id);
 
     const chatsNotify = openChats
       .filter(hasUnread)
@@ -158,7 +158,7 @@ class ChatAlert extends Component {
           const limitingMessages = flatMessages;
 
           return (<ChatPushAlert
-            key={id}
+            key={_.uniqueId('id-')}
             chatId={id}
             content={limitingMessages}
             message={<span >{message}</span>}
@@ -184,7 +184,6 @@ class ChatAlert extends Component {
       publicUserId,
       intl,
       disableNotify,
-      currentChatID,
     } = this.props;
 
     const publicUnread = UnreadMessages.getUnreadMessages(publicUserId);
@@ -192,7 +191,7 @@ class ChatAlert extends Component {
 
     if (disableNotify) return;
     if (!Service.hasUnreadMessages(publicUserId)) return;
-    if (currentChatID === PUBLIC_KEY) return;
+    if (Session.equals('idChatOpen', PUBLIC_KEY)) return;
 
     const checkIfBeenNotified = ({ sender, time }) =>
       time > (this.state.publicNotified[sender.id] || 0);
diff --git a/bigbluebutton-html5/imports/ui/components/chat/alert/push-alert/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/alert/push-alert/component.jsx
index 19a0ddc66cee0dd7181a2969b0ecd1bfb2a01d2d..6cae1188ed8aaf5be5db05cfdf538b5e58ae679a 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/alert/push-alert/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/alert/push-alert/component.jsx
@@ -2,8 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import _ from 'lodash';
 import injectNotify from '/imports/ui/components/toast/inject-notify/component';
-import { Link } from 'react-router';
-import { styles } from '../../styles.scss';
+import { Session } from 'meteor/session';
 
 const ALERT_INTERVAL = 2000; // 2 seconds
 const ALERT_LIFETIME = 4000; // 4 seconds
@@ -11,14 +10,26 @@ const ALERT_LIFETIME = 4000; // 4 seconds
 const propTypes = {
   notify: PropTypes.func.isRequired,
   onOpen: PropTypes.func.isRequired,
+  chatId: PropTypes.string.isRequired,
+  message: PropTypes.node.isRequired,
+  content: PropTypes.node.isRequired,
 };
 
 class ChatPushAlert extends React.Component {
   static link(message, chatId) {
     return (
-      <Link className={styles.link} to={`/users/chat/${chatId}`}>
-        {message}
-      </Link>
+      <div
+        role="button"
+        aria-label={message}
+        tabIndex={0}
+        onClick={() => {
+        Session.set('isUserListOpen', true);
+        Session.set('isChatOpen', true);
+        Session.set('idChatOpen', chatId);
+      }}
+      >
+        { message }
+      </div>
     );
   }
 
diff --git a/bigbluebutton-html5/imports/ui/components/chat/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/component.jsx
index 18fb18fb7b0f31655a43cc626bf5088aeaae0252..9390c88e2a393823aa41c62e13195b712b768ab4 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/component.jsx
@@ -1,9 +1,9 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { Link } from 'react-router';
 import { defineMessages, injectIntl } from 'react-intl';
 import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
 import Button from '/imports/ui/components/button/component';
+import { Session } from 'meteor/session';
 import { styles } from './styles';
 import MessageForm from './message-form/component';
 import MessageList from './message-list/component';
@@ -54,33 +54,34 @@ const Chat = (props) => {
           data-test="chatTitle"
           className={styles.title}
         >
-          <Link
-            to="/users"
-            role="button"
+          <Button
+            onClick={() => {
+              Session.set('isChatOpen', false);
+            }}
             aria-label={intl.formatMessage(intlMessages.hideChatLabel, { 0: title })}
             accessKey={HIDE_CHAT_AK}
-          >
-            <Icon iconName="left_arrow" /> {title}
-          </Link>
+            label={title}
+            icon="left_arrow"
+            className={styles.hideBtn}
+          />
         </div>
         {
           chatID !== 'public' ?
-            <Link
-              to="/users"
-              role="button"
-              tabIndex={-1}
-            >
-              <Button
-                className={styles.closeBtn}
-                icon="close"
-                size="md"
-                hideLabel
-                onClick={() => actions.handleClosePrivateChat(chatID)}
-                aria-label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
-                label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
-                accessKey={CLOSE_CHAT_AK}
-              />
-            </Link> :
+            <Button
+              className={styles.closeBtn}
+              icon="close"
+              size="md"
+              hideLabel
+              onClick={() => {
+                actions.handleClosePrivateChat(chatID);
+                Session.set('isChatOpen', false);
+                Session.set('idChatOpen', '');
+              }}
+              aria-label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
+              label={intl.formatMessage(intlMessages.closeChatLabel, { 0: title })}
+              accessKey={CLOSE_CHAT_AK}
+            />
+            :
             <ChatDropdown />
         }
       </header>
diff --git a/bigbluebutton-html5/imports/ui/components/chat/container.jsx b/bigbluebutton-html5/imports/ui/components/chat/container.jsx
index f4174e8266ef374b4abd2ea8f6e28a1741cea1fa..be1314c06f583ccafc5ec8017395f2229d37b751 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/container.jsx
@@ -1,6 +1,7 @@
 import React, { Component } from 'react';
 import { defineMessages, injectIntl } from 'react-intl';
 import { withTracker } from 'meteor/react-meteor-data';
+import { Session } from 'meteor/session';
 import Auth from '/imports/ui/services/auth';
 import Chat from './component';
 import ChatService from './service';
@@ -31,7 +32,7 @@ const intlMessages = defineMessages({
 class ChatContainer extends Component {
   componentDidMount() {
     // in case of reopening a chat, need to make sure it's removed from closed list
-    ChatService.removeFromClosedChatsSession(this.props.chatID);
+    ChatService.removeFromClosedChatsSession();
   }
   render() {
     return (
@@ -42,9 +43,8 @@ class ChatContainer extends Component {
   }
 }
 
-export default injectIntl(withTracker(({ params, intl }) => {
-  const chatID = params.chatID || PUBLIC_CHAT_KEY;
-
+export default injectIntl(withTracker(({ intl }) => {
+  const chatID = Session.get('idChatOpen') || PUBLIC_CHAT_KEY;
   let messages = [];
   let isChatLocked = ChatService.isChatLocked(chatID);
   let title = intl.formatMessage(intlMessages.titlePublic);
@@ -109,7 +109,7 @@ export default injectIntl(withTracker(({ params, intl }) => {
 
     messages = messagesFormated.sort((a, b) => (a.time - b.time));
   } else {
-    messages = ChatService.getPrivateGroupMessages(chatID);
+    messages = ChatService.getPrivateGroupMessages();
 
     const user = ChatService.getUser(chatID);
     chatName = user.name;
@@ -155,7 +155,7 @@ export default injectIntl(withTracker(({ params, intl }) => {
   const lastReadMessageTime = ChatService.lastReadMessageTime(chatID);
 
   return {
-    chatID,
+    chatID: Session.get('idChatOpen'),
     chatName,
     title,
     messages,
@@ -170,13 +170,13 @@ export default injectIntl(withTracker(({ params, intl }) => {
       handleClosePrivateChat: chatId => ChatService.closePrivateChat(chatId),
 
       handleSendMessage: (message) => {
-        ChatService.updateScrollPosition(chatID, null);
-        return ChatService.sendGroupMessage(chatID, message);
+        ChatService.updateScrollPosition(null);
+        return ChatService.sendGroupMessage(message);
       },
 
-      handleScrollUpdate: position => ChatService.updateScrollPosition(chatID, position),
+      handleScrollUpdate: position => ChatService.updateScrollPosition(position),
 
-      handleReadMessage: timestamp => ChatService.updateUnreadMessage(chatID, timestamp),
+      handleReadMessage: timestamp => ChatService.updateUnreadMessage(timestamp),
     },
   };
 })(ChatContainer));
diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
index a4c569b573fc742cd3a5e8243a10075317e30fb8..78bcc8081ed27b1ccc14ae0dcdc0358bc505bd76 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
@@ -129,7 +129,6 @@ class MessageForm extends Component {
   render() {
     const {
       intl, chatTitle, chatName, disabled,
-      minMessageLength, maxMessageLength,
     } = this.props;
 
     const { hasErrors, error } = this.state;
diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx
index 254d2d9ebd0849ed61b2f29ff4842214e7b18bfa..04dff92add6f08f587cc18068197663acbf3fef2 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/component.jsx
@@ -39,7 +39,7 @@ class MessageList extends Component {
     const { scrollArea } = this;
 
     this.setState({
-      scrollArea: this.scrollArea
+      scrollArea: this.scrollArea,
     });
 
     this.scrollTo(this.props.scrollPosition);
@@ -60,7 +60,7 @@ class MessageList extends Component {
       partnerIsLoggedOut,
     } = this.props;
 
-    if(!this.state.scrollArea && nextState.scrollArea) return true;
+    if (!this.state.scrollArea && nextState.scrollArea) return true;
 
     const switchingCorrespondent = chatId !== nextProps.chatId;
     const hasNewUnreadMessages = hasUnreadMessages !== nextProps.hasUnreadMessages;
@@ -164,14 +164,16 @@ class MessageList extends Component {
   }
 
   render() {
-    const { messages, intl } = this.props;
+    const {
+      messages, intl, id, lastReadMessageTime, handleReadMessage,
+    } = this.props;
     const isEmpty = messages.length === 0;
     return (
       <div className={styles.messageListWrapper}>
         <div
           role="log"
           ref={(ref) => { if (ref != null) { this.scrollArea = ref; } }}
-          id={this.props.id}
+          id={id}
           className={styles.messageList}
           aria-live="polite"
           aria-atomic="false"
@@ -180,14 +182,14 @@ class MessageList extends Component {
         >
           {messages.map(message => (
             <MessageListItem
-              handleReadMessage={this.props.handleReadMessage}
+              handleReadMessage={handleReadMessage}
               className={styles.messageListItem}
               key={message.id}
               messages={message.content}
               user={message.sender}
               time={message.time}
-              chatAreaId={this.props.id}
-              lastReadMessageTime={this.props.lastReadMessageTime}
+              chatAreaId={id}
+              lastReadMessageTime={lastReadMessageTime}
               scrollArea={this.state.scrollArea}
             />
           ))}
diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss
index 8956bbcba7360e98bcc5e04fa9c732d8bb2bb109..6cae52b42fce33aa9cb8980406ebc74302447415 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss
@@ -17,6 +17,7 @@
 
 .systemMessage {
   padding: var(--line-height-computed) 0;
+  padding-top: 0px;
   border-bottom: 1px solid var(--color-gray-lighter);
 
   .item:not(&) + & {
diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js
index 62e6aaae189e58094f074982e83ebf34419750df..f93eee9dc6c895a0f32adab86e4611d477d8c2f6 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/service.js
+++ b/bigbluebutton-html5/imports/ui/components/chat/service.js
@@ -88,7 +88,8 @@ const getPublicGroupMessages = () => {
   return publicGroupMessages;
 };
 
-const getPrivateGroupMessages = (chatID) => {
+const getPrivateGroupMessages = () => {
+  const chatID = Session.get('idChatOpen');
   const sender = getUser(Auth.userID);
 
   const privateChat = GroupChat.findOne({
@@ -143,7 +144,8 @@ const lastReadMessageTime = (receiverID) => {
   return UnreadMessages.get(chatType);
 };
 
-const sendGroupMessage = (chatID, message) => {
+const sendGroupMessage = (message) => {
+  const chatID = Session.get('idChatOpen');
   const isPublicChat = chatID === PUBLIC_CHAT_ID;
 
   let chatId = PUBLIC_GROUP_CHAT_ID;
@@ -188,20 +190,22 @@ const getScrollPosition = (receiverID) => {
 };
 
 const updateScrollPosition =
-  (receiverID, position) => ScrollCollection.upsert(
-    { receiver: receiverID },
+  position => ScrollCollection.upsert(
+    { receiver: Session.get('idChatOpen') },
     { $set: { position } },
   );
 
-const updateUnreadMessage = (receiverID, timestamp) => {
-  const isPublic = receiverID === PUBLIC_CHAT_ID;
-  const chatType = isPublic ? PUBLIC_GROUP_CHAT_ID : receiverID;
+const updateUnreadMessage = (timestamp) => {
+  const chatID = Session.get('idChatOpen');
+  const isPublic = chatID === PUBLIC_CHAT_ID;
+  const chatType = isPublic ? PUBLIC_GROUP_CHAT_ID : chatID;
   return UnreadMessages.update(chatType, timestamp);
 };
 
 const clearPublicChatHistory = () => (makeCall('clearPublicChatHistory'));
 
-const closePrivateChat = (chatID) => {
+const closePrivateChat = () => {
+  const chatID = Session.get('idChatOpen');
   const currentClosedChats = Storage.getItem(CLOSED_CHAT_LIST_KEY) || [];
 
   if (_.indexOf(currentClosedChats, chatID) < 0) {
@@ -212,7 +216,8 @@ const closePrivateChat = (chatID) => {
 };
 
 // if this private chat has been added to the list of closed ones, remove it
-const removeFromClosedChatsSession = (chatID) => {
+const removeFromClosedChatsSession = () => {
+  const chatID = Session.get('idChatOpen');
   const currentClosedChats = Storage.getItem(CLOSED_CHAT_LIST_KEY);
   if (_.indexOf(currentClosedChats, chatID) > -1) {
     Storage.setItem(CLOSED_CHAT_LIST_KEY, _.without(currentClosedChats, chatID));
diff --git a/bigbluebutton-html5/imports/ui/components/chat/styles.scss b/bigbluebutton-html5/imports/ui/components/chat/styles.scss
index 49fcb9e21855fd8421d8522b4ac3b4a103d90a10..c8754fe53080045e030e1847873a170856a9e5d3 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/chat/styles.scss
@@ -92,6 +92,23 @@
   }
 }
 
+.hideBtn {
+  position: relative;
+  background-color: white;
+  display: block;
+  margin: 4px;
+  margin-bottom: 2px;
+  padding-left: 0px;
+
+  > i {
+    color: black;
+  }
+
+  &:hover {
+    background-color: #fff;
+  }
+}
+
 .link {
   text-decoration: none;
   background-color: inherit;
diff --git a/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx b/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx
index 95496e1bad2d39b88a75fd830c92a45cb8405884..abd09fe45840c6cd4ca50029ab3210699a104481 100755
--- a/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/dropdown/list/component.jsx
@@ -8,10 +8,9 @@ import ListSeparator from './separator/component';
 import ListTitle from './title/component';
 
 const propTypes = {
-  /*  We should recheck this proptype, sometimes we need to create an container and send to dropdown,
-   but with this */
-  // proptype, is not possible.
-  children: PropTypes.arrayOf((propValue, key, componentName, location, propFullName) => {
+  /*  We should recheck this proptype, sometimes we need to create an container and send to
+   dropdown, but with this proptype, is not possible. */
+  children: PropTypes.arrayOf((propValue, key, componentName, propFullName) => {
     if (propValue[key].type !== ListItem &&
       propValue[key].type !== ListSeparator &&
       propValue[key].type !== ListTitle) {
diff --git a/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx b/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx
index d9cd49a84afa00bc0e2f586c1be33561b6f73181..9770e2851b0e19fe9281eb37153e2fcba1e05e4e 100644
--- a/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx
@@ -2,7 +2,6 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl } from 'react-intl';
 import Button from '/imports/ui/components/button/component';
-import { withRouter } from 'react-router';
 import { styles } from './styles';
 
 const intlMessages = defineMessages({
@@ -37,7 +36,9 @@ const defaultProps = {
 class ErrorScreen extends React.PureComponent {
   render() {
     const {
-      intl, code, children, router,
+      intl,
+      code,
+      children,
     } = this.props;
 
     let formatedMessage = intl.formatMessage(intlMessages[defaultProps.code]);
@@ -60,7 +61,7 @@ class ErrorScreen extends React.PureComponent {
         <div className={styles.content}>
           <Button
             size="sm"
-            onClick={() => router.push('/logout/')}
+            onClick={() => Session.set('isMeetingEnded', true)}
             label={intl.formatMessage(intlMessages.leave)}
           />
         </div>
@@ -69,7 +70,7 @@ class ErrorScreen extends React.PureComponent {
   }
 }
 
-export default withRouter(injectIntl(ErrorScreen));
+export default injectIntl(ErrorScreen);
 
 ErrorScreen.propTypes = propTypes;
 ErrorScreen.defaultProps = defaultProps;
diff --git a/bigbluebutton-html5/imports/ui/components/logout-confirmation/component.jsx b/bigbluebutton-html5/imports/ui/components/logout-confirmation/component.jsx
index 1f46906c7b848f40aeda64f198e5682425246666..e6d34c39f8af75c9444aec626035a714ac43cc94 100755
--- a/bigbluebutton-html5/imports/ui/components/logout-confirmation/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/logout-confirmation/component.jsx
@@ -7,6 +7,7 @@ import { styles } from './styles';
 
 const propTypes = {
   handleEndMeeting: PropTypes.func.isRequired,
+  confirmLeaving: PropTypes.func.isRequired,
   intl: PropTypes.shape({
     formatMessage: PropTypes.func.isRequired,
   }).isRequired,
@@ -55,15 +56,14 @@ const intlMessages = defineMessages({
 
 const LeaveConfirmation = ({
   intl,
-  router,
   handleEndMeeting,
   showEndMeeting,
-  showFeedback,
+  confirmLeaving,
 }) => (
   <Modal
     title={intl.formatMessage(intlMessages.title)}
     confirm={{
-      callback: showFeedback,
+      callback: confirmLeaving,
       label: intl.formatMessage(intlMessages.confirmLabel),
       description: intl.formatMessage(intlMessages.confirmDesc),
     }}
@@ -79,7 +79,7 @@ const LeaveConfirmation = ({
         className={styles.endMeeting}
         label={intl.formatMessage(intlMessages.endMeetingLabel)}
         onClick={handleEndMeeting}
-        aria-describedby={'modalEndMeetingDesc'}
+        aria-describedby="modalEndMeetingDesc"
       /> : null
     }
     <div id="modalEndMeetingDesc" hidden>{intl.formatMessage(intlMessages.endMeetingDesc)}</div>
diff --git a/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx b/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx
index 3bb70c02b42cdb4961c0ddd890049cb51eaf39eb..0e215ec5e87985aacf5ac144079039268453bb37 100755
--- a/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx
@@ -1,8 +1,8 @@
 import React from 'react';
 import { meetingIsBreakout } from '/imports/ui/components/app/service';
 import { withTracker } from 'meteor/react-meteor-data';
-import { withRouter } from 'react-router';
-import getFromUserSettings from '/imports/ui/services/users-settings';
+import { Session } from 'meteor/session';
+
 import LogoutConfirmation from './component';
 import {
   isModerator,
@@ -13,14 +13,15 @@ const LogoutConfirmationContainer = props => (
   <LogoutConfirmation {...props} />
 );
 
-export default withRouter(withTracker(({ router }) => {
-  const APP_CONFIG = Meteor.settings.public.app;
-  const shouldShowFeedback = !meetingIsBreakout() && getFromUserSettings('askForFeedbackOnLogout', APP_CONFIG.askForFeedbackOnLogout);
-  const showFeedback = shouldShowFeedback ? () => router.push('/ended/430') : () => router.push('/logout');
+export default withTracker(() => {
+  const confirmLeaving = () => {
+    Session.set('isMeetingEnded', true);
+    Session.set('codeError', '430');
+  };
 
   return {
     showEndMeeting: !meetingIsBreakout() && isModerator(),
     handleEndMeeting: endMeeting,
-    showFeedback,
+    confirmLeaving,
   };
-})(LogoutConfirmationContainer));
+})(LogoutConfirmationContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
index 60359a8904b1750c27b817b5d3667b1e50173f1b..f5e93483f9cd1da6400492cc0338e2e409ca55b9 100755
--- a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
@@ -1,10 +1,10 @@
 import React from 'react';
-import { withRouter } from 'react-router';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl } from 'react-intl';
 import Auth from '/imports/ui/services/auth';
 import Button from '/imports/ui/components/button/component';
 import getFromUserSettings from '/imports/ui/services/users-settings';
+import { logoutRouteHandler } from '/imports/startup/client/auth';
 import Rating from './rating/component';
 import { styles } from './styles';
 
@@ -64,9 +64,6 @@ const propTypes = {
     formatMessage: PropTypes.func.isRequired,
   }).isRequired,
   code: PropTypes.string.isRequired,
-  router: PropTypes.shape({
-    push: PropTypes.func.isRequired,
-  }).isRequired,
 };
 
 class MeetingEnded extends React.PureComponent {
@@ -96,12 +93,8 @@ class MeetingEnded extends React.PureComponent {
       selected,
     } = this.state;
 
-    const {
-      router,
-    } = this.props;
-
     if (selected <= 0) {
-      router.push('/logout');
+      logoutRouteHandler();
       return;
     }
 
@@ -122,7 +115,9 @@ class MeetingEnded extends React.PureComponent {
     };
 
     fetch(url, options)
-      .finally(() => router.push('/logout'));
+      .finally(() => {
+        logoutRouteHandler();
+      });
   }
 
   render() {
@@ -173,4 +168,4 @@ class MeetingEnded extends React.PureComponent {
 
 MeetingEnded.propTypes = propTypes;
 
-export default injectIntl(withRouter(MeetingEnded));
+export default injectIntl(MeetingEnded);
diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx
index 0c009bcb50d2fbccaeaa798744ea17b90469bb4b..45318056af4e6a51b16b9eee11f9a9543bbff365 100755
--- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx
@@ -79,22 +79,19 @@ class NavBar extends Component {
     this.handleToggleUserList = this.handleToggleUserList.bind(this);
   }
 
-  handleToggleUserList() {
-    this.props.toggleUserList();
-  }
-
   componentDidUpdate(oldProps) {
     const {
       breakouts,
       getBreakoutJoinURL,
       isBreakoutRoom,
+      mountModal,
     } = this.props;
 
     const hadBreakouts = oldProps.breakouts.length;
     const hasBreakouts = breakouts.length;
 
     if (!hasBreakouts && hadBreakouts) {
-      closeBreakoutJoinConfirmation(this.props.mountModal);
+      closeBreakoutJoinConfirmation(mountModal);
     }
 
     breakouts.forEach((breakout) => {
@@ -112,6 +109,10 @@ class NavBar extends Component {
     }
   }
 
+  handleToggleUserList() {
+    this.props.toggleUserList();
+  }
+
   inviteUserToBreakout(breakout) {
     const {
       mountModal,
@@ -182,6 +183,9 @@ class NavBar extends Component {
     toggleBtnClasses[styles.btn] = true;
     toggleBtnClasses[styles.btnWithNotificationDot] = hasUnreadMessages;
 
+    let ariaLabel = intl.formatMessage(intlMessages.toggleUserListAria);
+    ariaLabel += hasUnreadMessages ? (` ${intl.formatMessage(intlMessages.newMessages)}`) : '';
+
     return (
       <div className={styles.navbar}>
         <div className={styles.left}>
@@ -192,17 +196,12 @@ class NavBar extends Component {
             circle
             hideLabel
             label={intl.formatMessage(intlMessages.toggleUserListLabel)}
-            aria-label={intl.formatMessage(intlMessages.toggleUserListAria)}
+            aria-label={ariaLabel}
             icon="user"
             className={cx(toggleBtnClasses)}
             aria-expanded={isExpanded}
-            aria-describedby="newMessage"
             accessKey={TOGGLE_USERLIST_AK}
           />
-          <div
-            id="newMessage"
-            aria-label={hasUnreadMessages ? intl.formatMessage(intlMessages.newMessages) : null}
-          />
         </div>
         <div className={styles.center}>
           {this.renderPresentationTitle()}
diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx
index 56796f79ebb1eacb443a0d7ddf618145eea9d203..25a03f51595c1c18d41ec314c0cc407c2edb22ed 100755
--- a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx
@@ -1,7 +1,7 @@
 import React from 'react';
 import { Meteor } from 'meteor/meteor';
 import { withTracker } from 'meteor/react-meteor-data';
-import { withRouter } from 'react-router';
+import { Session } from 'meteor/session';
 import Meetings from '/imports/api/meetings';
 import Auth from '/imports/ui/services/auth';
 import { meetingIsBreakout } from '/imports/ui/components/app/service';
@@ -20,7 +20,7 @@ const NavBarContainer = ({ children, ...props }) => (
   </NavBar>
 );
 
-export default withRouter(withTracker(({ location, router }) => {
+export default withTracker(() => {
   const CLIENT_TITLE = getFromUserSettings('clientTitle', PUBLIC_CONFIG.app.clientTitle);
 
   let meetingTitle;
@@ -54,7 +54,7 @@ export default withRouter(withTracker(({ location, router }) => {
   const breakouts = Service.getBreakouts();
   const currentUserId = Auth.userID;
 
-  const isExpanded = location.pathname.indexOf('/users') !== -1;
+  const isExpanded = Session.get('isUserListOpen');
 
   return {
     isExpanded,
@@ -66,11 +66,7 @@ export default withRouter(withTracker(({ location, router }) => {
     isBreakoutRoom: meetingIsBreakout(),
     beingRecorded: meetingRecorded,
     toggleUserList: () => {
-      if (location.pathname.indexOf('/users') !== -1) {
-        router.push('/');
-      } else {
-        router.push('/users');
-      }
+      Session.set('isUserListOpen', !isExpanded);
     },
   };
-})(NavBarContainer));
+})(NavBarContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/poll/component.jsx b/bigbluebutton-html5/imports/ui/components/poll/component.jsx
index 3d8455f04afd5ca910d96b391bb417494e0b5105..3f53f03e61b55221480f5b87ccf1283297a21fb8 100644
--- a/bigbluebutton-html5/imports/ui/components/poll/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/poll/component.jsx
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl } from 'react-intl';
 import _ from 'lodash';
-import { Link } from 'react-router';
+import { Session } from 'meteor/session';
 import Button from '/imports/ui/components/button/component';
 import Icon from '/imports/ui/components/icon/component';
 import LiveResultContainer from './live-result/container';
@@ -37,14 +37,6 @@ const intlMessages = defineMessages({
     id: 'app.poll.activePollInstruction',
     description: 'instructions displayed when a poll is active',
   },
-  publishLabel: {
-    id: 'app.poll.publishLabel',
-    description: 'label for the publish button',
-  },
-  backLabel: {
-    id: 'app.poll.backLabel',
-    description: 'label for the return to poll options button',
-  },
   customPlaceholder: {
     id: 'app.poll.customPlaceholder',
     description: 'custom poll input field placeholder text',
@@ -95,6 +87,13 @@ class Poll extends Component {
     this.nonPresenterRedirect = this.nonPresenterRedirect.bind(this);
     this.getInputFields = this.getInputFields.bind(this);
     this.handleInputChange = this.handleInputChange.bind(this);
+    this.back = this.back.bind(this);
+  }
+
+  componentWillUnmount() {
+    const { stopPoll } = this.props;
+
+    stopPoll();
   }
 
   componentWillMount() {
@@ -131,8 +130,11 @@ class Poll extends Component {
   }
 
   nonPresenterRedirect() {
-    const { currentUser, router } = this.props;
-    if (!currentUser.presenter) return router.push('/users');
+    const { currentUser } = this.props;
+    if (!currentUser.presenter) {
+      Session.set('isUserListOpen', true);
+      return Session.set('isPollOpen', false);
+    }
   }
 
   toggleCustomFields() {
@@ -192,9 +194,20 @@ class Poll extends Component {
     );
   }
 
+  back() {
+    const { stopPoll } = this.props;
+
+    stopPoll();
+    this.inputEditor = [];
+    this.setState({
+      isPolling: false,
+      customPollValues: this.inputEditor,
+    }, document.activeElement.blur());
+  }
+
   renderActivePollOptions() {
     const {
-      intl, router, publishPoll, stopPoll,
+      intl, publishPoll, stopPoll,
     } = this.props;
 
     return (
@@ -202,30 +215,7 @@ class Poll extends Component {
         <div className={styles.instructions}>
           {intl.formatMessage(intlMessages.activePollInstruction)}
         </div>
-        <LiveResultContainer />
-        <Button
-          onClick={() => {
-            publishPoll();
-            stopPoll();
-            router.push('/users');
-          }}
-          label={intl.formatMessage(intlMessages.publishLabel)}
-          color="primary"
-          className={styles.btn}
-        />
-        <Button
-          onClick={() => {
-            stopPoll();
-            this.inputEditor = [];
-            this.setState({
-              isPolling: false,
-              customPollValues: this.inputEditor,
-            }, document.activeElement.blur());
-          }}
-          label={intl.formatMessage(intlMessages.backLabel)}
-          color="default"
-          className={styles.btn}
-        />
+        <LiveResultContainer publishPoll={publishPoll} stopPoll={stopPoll} back={this.back} />
       </div>
     );
   }
@@ -264,18 +254,35 @@ class Poll extends Component {
     return (
       <div>
         <header className={styles.header}>
-          <Link
-            to="/users"
-            role="button"
+          <Button
+            tabIndex={0}
+            label={intl.formatMessage(intlMessages.pollPaneTitle)}
+            icon="left_arrow"
             aria-label={intl.formatMessage(intlMessages.hidePollDesc)}
+            className={styles.hideBtn}
             onClick={() => {
               if (this.state.isPolling) {
                 stopPoll();
               }
+              Session.set('isPollOpen', false);
+              Session.set('forcePollOpen', true);
+              Session.set('isUserListOpen', true);
             }}
-          >
-            <Icon iconName="left_arrow" />{intl.formatMessage(intlMessages.pollPaneTitle)}
-          </Link>
+          />
+
+          <Button
+            onClick={() => {
+            if (this.state.isPolling) {
+              stopPoll();
+            }
+            Session.set('isPollOpen', false);
+            Session.set('forcePollOpen', false);
+            Session.set('isUserListOpen', true);
+          }}
+            className={styles.closeBtn}
+            label="X"
+          />
+
         </header>
         {
           this.state.isPolling ? this.renderActivePollOptions() : this.renderPollOptions()
diff --git a/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx b/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx
index 6630148abb9b375e318033adc21e8314cb1a123f..828f0b45cd1f84dea7a22d8eeda768696faafc6e 100644
--- a/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx
@@ -2,6 +2,8 @@ import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import _ from 'lodash';
 import { defineMessages, injectIntl } from 'react-intl';
+import { Session } from 'meteor/session';
+import Button from '/imports/ui/components/button/component';
 import { styles } from './styles';
 
 const intlMessages = defineMessages({
@@ -13,6 +15,14 @@ const intlMessages = defineMessages({
     id: 'app.poll.liveResult.responsesTitle',
     description: 'heading label for poll responses',
   },
+  publishLabel: {
+    id: 'app.poll.publishLabel',
+    description: 'label for the publish button',
+  },
+  backLabel: {
+    id: 'app.poll.backLabel',
+    description: 'label for the return to poll options button',
+  },
 });
 
 class LiveResult extends Component {
@@ -116,13 +126,35 @@ class LiveResult extends Component {
   }
 
   render() {
-    const { intl } = this.props;
+    const {
+      intl, publishPoll, stopPoll, back,
+    } = this.props;
 
     return (
       <div>
         <div className={styles.stats}>
           {this.getPollStats()}
         </div>
+        <Button
+          onClick={() => {
+            publishPoll();
+            stopPoll();
+            Session.set('isUserListOpen', true);
+            Session.set('isPollOpen', false);
+            Session.set('forcePollOpen', false);
+          }}
+          label={intl.formatMessage(intlMessages.publishLabel)}
+          color="primary"
+          className={styles.btn}
+        />
+        <Button
+          onClick={() => {
+            back();
+          }}
+          label={intl.formatMessage(intlMessages.backLabel)}
+          color="default"
+          className={styles.btn}
+        />
         <div className={styles.container}>
           <div className={styles.usersHeading}>{intl.formatMessage(intlMessages.usersTitle)}</div>
           <div className={styles.responseHeading}>{intl.formatMessage(intlMessages.responsesTitle)}</div>
diff --git a/bigbluebutton-html5/imports/ui/components/poll/live-result/styles.scss b/bigbluebutton-html5/imports/ui/components/poll/live-result/styles.scss
index 6dbdc796d25b76be4bd139f4287f61ad3774d851..ad7a8acf052df71820d85eafb4e42349e7711073 100644
--- a/bigbluebutton-html5/imports/ui/components/poll/live-result/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/poll/live-result/styles.scss
@@ -7,6 +7,12 @@ $stats-element-width: 17%;
 $sm-margin: 0.3125rem;
 $user-line-height: 1.75rem;
 
+.btn {
+  width: 100%;
+  margin-top: var(--sm-padding-y);
+  margin-bottom: var(--sm-padding-y);
+}
+
 .main {
   display: flex;
   justify-content: space-between;
diff --git a/bigbluebutton-html5/imports/ui/components/poll/styles.scss b/bigbluebutton-html5/imports/ui/components/poll/styles.scss
index 403dcfe849ee4f5de41ec4d67afc202245257254..b97daef807c1517f1a83b6c011cf5933d9ff6e37 100644
--- a/bigbluebutton-html5/imports/ui/components/poll/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/poll/styles.scss
@@ -4,14 +4,37 @@
 $column-amount: 2;
 $poll-blue: #1A73D4;
 
-.customBtn,
-.btn {
-    width: 100%;
+.closeBtn {
+    position: relative;
+    margin-left: 9.125rem;
 }
 
+<<<<<<< HEAD
 .btn {
     margin-top: var(--sm-padding-y);
     margin-bottom: var(--sm-padding-y);
+=======
+.hideBtn {
+    position: relative;
+    background-color: white;
+    display: block;
+    margin: 4px;
+    margin-bottom: 2px;
+    padding-left: 0px;
+
+    > i {
+        color: black;
+        font-size: 85%;
+    }
+
+    &:hover {
+        background-color: #fff;
+    }
+  }
+
+.customBtn {
+    width: 100%;
+>>>>>>> test-merge-anton
 }
 
 .customInputWrapper {
@@ -19,8 +42,13 @@ $poll-blue: #1A73D4;
 
     > input {
         width: 100%;
+<<<<<<< HEAD
         margin-top: .3rem;
         margin-bottom: .3rem;
+=======
+        margin-top: var(--sm-padding-y);
+        margin-bottom: var(--sm-padding-y);
+>>>>>>> test-merge-anton
     }
 
     > input:first-child {
@@ -38,6 +66,7 @@ $poll-blue: #1A73D4;
     display: flex;
     flex-direction: row;
     align-items: center;
+    justify-content: space-between;
     margin-bottom: var(--md-padding-y);
 
     > a {
diff --git a/bigbluebutton-html5/imports/ui/components/polling/component.jsx b/bigbluebutton-html5/imports/ui/components/polling/component.jsx
index c5397dabd96f53973a5115d35409f9e5deeb6625..c55e6654f4cc55730f079e7c60cb0aac21a968dc 100644
--- a/bigbluebutton-html5/imports/ui/components/polling/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/polling/component.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import Button from '/imports/ui/components/button/component';
 import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
@@ -18,53 +18,71 @@ const intlMessages = defineMessages({
   },
 });
 
-const Polling = ({ intl, poll, handleVote }) => {
-  this.alert = new Audio(`${Meteor.settings.public.app.basename}/resources/sounds/Poll.mp3`);
-  this.alert.play();
+class Polling extends Component {
+  constructor(props) {
+    super(props);
 
-  return (
-    <div className={styles.pollingContainer} role="alert">
-      <div className={styles.pollingTitle}>
-        {intl.formatMessage(intlMessages.pollingTitleLabel)}
-      </div>
-      <div className={styles.pollingAnswers}>
-        {poll.answers.map(pollAnswer => (
-          <div
-            key={pollAnswer.id}
-            className={styles.pollButtonWrapper}
-          >
-            <Tooltip
-              key={pollAnswer.id}
-              title={pollAnswer.key}
-            >
-              <Button
-                className={styles.pollingButton}
-                color="primary"
-                size="md"
-                label={pollAnswer.key}
-                key={pollAnswer.key}
-                onClick={() => handleVote(poll.pollId, pollAnswer)}
-                aria-labelledby={`pollAnswerLabel${pollAnswer.key}`}
-                aria-describedby={`pollAnswerDesc${pollAnswer.key}`}
-              />
-            </Tooltip>
-            <div
-              className={styles.hidden}
-              id={`pollAnswerLabel${pollAnswer.key}`}
-            >
-              {intl.formatMessage(intlMessages.pollAnswerLabel, { 0: pollAnswer.key })}
-            </div>
-            <div
-              className={styles.hidden}
-              id={`pollAnswerDesc${pollAnswer.key}`}
-            >
-              {intl.formatMessage(intlMessages.pollAnswerDesc, { 0: pollAnswer.key })}
-            </div>
+    this.play = this.play.bind(this);
+  }
+
+  componentDidMount() {
+    this.play();
+  }
+
+  play() {
+    this.alert = new Audio(`${Meteor.settings.public.app.basename}/resources/sounds/Poll.mp3`);
+    this.alert.play();
+  }
+
+  render() {
+    const { intl, poll, handleVote } = this.props;
+
+    return (
+      <div className={styles.overlay}>
+        <div className={styles.pollingContainer} role="alert">
+          <div className={styles.pollingTitle}>
+            {intl.formatMessage(intlMessages.pollingTitleLabel)}
           </div>
-      ))}
-      </div>
-    </div>);
-};
+          <div className={styles.pollingAnswers}>
+            {poll.answers.map(pollAnswer => (
+              <div
+                key={pollAnswer.id}
+                className={styles.pollButtonWrapper}
+              >
+                <Tooltip
+                  key={pollAnswer.id}
+                  title={pollAnswer.key}
+                >
+                  <Button
+                    className={styles.pollingButton}
+                    color="primary"
+                    size="md"
+                    label={pollAnswer.key}
+                    key={pollAnswer.key}
+                    onClick={() => handleVote(poll.pollId, pollAnswer)}
+                    aria-labelledby={`pollAnswerLabel${pollAnswer.key}`}
+                    aria-describedby={`pollAnswerDesc${pollAnswer.key}`}
+                  />
+                </Tooltip>
+                <div
+                  className={styles.hidden}
+                  id={`pollAnswerLabel${pollAnswer.key}`}
+                >
+                  {intl.formatMessage(intlMessages.pollAnswerLabel, { 0: pollAnswer.key })}
+                </div>
+                <div
+                  className={styles.hidden}
+                  id={`pollAnswerDesc${pollAnswer.key}`}
+                >
+                  {intl.formatMessage(intlMessages.pollAnswerDesc, { 0: pollAnswer.key })}
+                </div>
+              </div>
+        ))}
+          </div>
+        </div>
+      </div>);
+  }
+}
 
 export default injectIntl(injectWbResizeEvent(Polling));
 
diff --git a/bigbluebutton-html5/imports/ui/components/polling/styles.scss b/bigbluebutton-html5/imports/ui/components/polling/styles.scss
index b34ff0f27769230169aff35c82d19c073e241048..19c1f343f3fe11d3dc818a8d4af29391d8407e02 100644
--- a/bigbluebutton-html5/imports/ui/components/polling/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/polling/styles.scss
@@ -4,16 +4,24 @@ $poll-width: 18rem;
 $max-btn-width: 9em;
 $col-amount: 2;
 
-// pollingAnswer position offsets
-$xs-portrait-offset: 8.75em;
-$xs-landscape-offset: 4.75em;
-$s-portrait-offset: 11.75em;
-$s-landscape-offset: 1.75em;
+.overlay {
+  position: absolute;
+  height: 100vh;
+  width: 100vw;
+  z-index: 1015;
+  pointer-events: none;
+
+  @media screen and (max-width: 479px), screen and (max-height: 479px) {
+    background-color: rgba(0, 0, 0, 0.349);
+  }
+}
 
 .pollingContainer {
+  pointer-events:auto;
   width: $poll-width;
   position: absolute;
-  z-index: 2;
+
+  z-index: 1016;
   border: 1px solid var(--color-off-white);
   border-radius: var(--border-radius);
   box-shadow: var(--color-gray-dark) 0px 0px var(--lg-padding-y);
@@ -27,10 +35,20 @@ $s-landscape-offset: 1.75em;
 }
 
 .pollingTitle {
-  color: var(--color-text);
+  color: var(--color-white);
   white-space: nowrap;
   padding-bottom: var(--md-padding-y);
   padding-top: var(--md-padding-y);
+
+  @media screen and (max-height: 479px), screen and (max-width: 479px)  {
+    bottom: auto;
+    right: auto;
+    top: 50%;
+    left: 50%;
+    margin-right: -50%;
+    transform: translate(-50%, -50%);
+  }
+
 }
 
 .pollingAnswers {
@@ -45,32 +63,33 @@ $s-landscape-offset: 1.75em;
       grid-column: $col-amount;
   }
 
-  z-index: 1;
+  @media screen and (max-width: 479px) {
+    grid-template-columns: repeat(1, 1fr);
 
-  :global(.browser-safari) & {
-    @include mq($ip5-portrait) {
-      bottom: 8.75em;
-    }
-    @include mq($ip678-portrait) {
-      bottom: 4.75em;
+    > pollButtonWrapper:nth-child(odd) {
+        grid-column: 1;
     }
-    @include mq($ip5-landscape) {
-      bottom: 11.75em;
-    }
-    @include mq($ip678-landscape) {
-      bottom: 1.75em;
+  
+    > pollButtonWrapper:nth-child(even) {
+        grid-column: 1;
     }
   }
+
+  z-index: 1;
 }
 
 .pollButtonWrapper {
   text-align: center;
   padding: var(--sm-padding-y);
+  width: 100%;
 }
 
 .pollingButton {
   width: 100%;
   max-width: $max-btn-width;
+  @media screen and (max-width: 479px) { 
+    max-width: none;
+  }
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
diff --git a/bigbluebutton-html5/imports/ui/components/settings/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/component.jsx
index bd499f6835bd8ecc81f384205120221619d8d55b..7f7e6a3f7dc8f8caed4f840aaa210f295387419f 100644
--- a/bigbluebutton-html5/imports/ui/components/settings/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/settings/component.jsx
@@ -208,8 +208,6 @@ class Settings extends Component {
   render() {
     const {
       intl,
-      router,
-      location,
       mountModal,
     } = this.props;
 
@@ -219,7 +217,7 @@ class Settings extends Component {
         confirm={{
           callback: () => {
             this.updateSettings(this.state.current);
-            router.push(location.pathname);
+            // router.push(location.pathname); // TODO 4767
             /* We need to use mountModal(null) here to prevent submenu state updates,
             *  from re-opening the modal.
             */
diff --git a/bigbluebutton-html5/imports/ui/components/settings/container.jsx b/bigbluebutton-html5/imports/ui/components/settings/container.jsx
index 0663334319a4d3629b5a406b70e396d4975e0a6b..bcff47570f5c477079dce9f36f45cac450fabe35 100644
--- a/bigbluebutton-html5/imports/ui/components/settings/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/settings/container.jsx
@@ -1,6 +1,5 @@
 import React from 'react';
 import { withTracker } from 'meteor/react-meteor-data';
-import { withRouter } from 'react-router';
 import SettingsService from '/imports/ui/services/settings';
 import Settings from './component';
 
@@ -15,7 +14,7 @@ const SettingsContainer = props => (
   <Settings {...props} />
 );
 
-export default withRouter(withTracker(() => ({
+export default withTracker(() => ({
   audio: SettingsService.audio,
   dataSaving: SettingsService.dataSaving,
   application: SettingsService.application,
@@ -25,4 +24,4 @@ export default withRouter(withTracker(() => ({
   locales: getClosedCaptionLocales(),
   availableLocales: getAvailableLocales(),
   isModerator: getUserRoles() === 'MODERATOR',
-}))(SettingsContainer));
+}))(SettingsContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx
index 824c2c59b758a2c3082531babb61b29a58db8892..286bc1cfdb0c24d653dfc4b83fc97f0595946172 100644
--- a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx
@@ -1,6 +1,5 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { withRouter, Link } from 'react-router';
 import cx from 'classnames';
 import { defineMessages, injectIntl } from 'react-intl';
 import { styles } from './styles';
@@ -23,10 +22,6 @@ const intlMessages = defineMessages({
   },
 });
 
-const CHAT_CONFIG = Meteor.settings.public.chat;
-const PRIVATE_CHAT_PATH = CHAT_CONFIG.path_route;
-const CLOSED_CHAT_PATH = 'users/';
-
 const SHORTCUTS_CONFIG = Meteor.settings.public.app.shortcuts;
 const TOGGLE_CHAT_PUB_AK = SHORTCUTS_CONFIG.togglePublicChat.accesskey;
 
@@ -57,25 +52,32 @@ const ChatListItem = (props) => {
     intl,
     tabIndex,
     isPublicChat,
-    location,
   } = props;
 
-  let linkPath = [PRIVATE_CHAT_PATH, chat.id].join('');
-  linkPath = location.pathname.includes(linkPath) ? CLOSED_CHAT_PATH : linkPath;
   const isCurrentChat = chat.id === openChat;
   const linkClasses = {};
   linkClasses[styles.active] = isCurrentChat;
 
   return (
-    <Link
-      data-test="publicChatLink"
-      to={linkPath}
-      className={cx(styles.chatListItem, linkClasses)}
+    <div
       role="button"
+      className={cx(styles.chatListItem, linkClasses)}
       aria-expanded={isCurrentChat}
       tabIndex={tabIndex}
       accessKey={isPublicChat(chat) ? TOGGLE_CHAT_PUB_AK : null}
+      onClick={() => {
+        Session.set('isChatOpen', true);
+        Session.set('idChatOpen', chat.id);
+
+        if (Session.equals('isPollOpen', true)) {
+          Session.set('isPollOpen', false);
+          Session.set('forcePollOpen', true);
+        }
+      }}
+      id="chat-toggle-button"
+      aria-label={isPublicChat(chat) ? intl.formatMessage(intlMessages.titlePublic) : chat.name}
     >
+
       <div className={styles.chatListItemLink}>
         <div className={styles.chatIcon}>
           {chat.icon ?
@@ -90,7 +92,8 @@ const ChatListItem = (props) => {
         <div className={styles.chatName}>
           {!compact ?
             <span className={styles.chatNameMain}>
-              {isPublicChat(chat) ? intl.formatMessage(intlMessages.titlePublic) : chat.name}
+              {isPublicChat(chat) ?
+              intl.formatMessage(intlMessages.titlePublic) : chat.name}
             </span> : null}
         </div>
         {(chat.unreadCounter > 0) ?
@@ -99,11 +102,11 @@ const ChatListItem = (props) => {
           />
           : null}
       </div>
-    </Link>
+    </div>
   );
 };
 
 ChatListItem.propTypes = propTypes;
 ChatListItem.defaultProps = defaultProps;
 
-export default withRouter(injectIntl(ChatListItem));
+export default injectIntl(ChatListItem);
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/styles.scss b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/styles.scss
index f106dbd5854de1fe6c29a7a4fc5617c5498ea691..84e607db44144cfdb830ba654f779cf1a655d136 100755
--- a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/styles.scss
+++ b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/styles.scss
@@ -7,6 +7,7 @@
   padding: 0;
   text-decoration: none;
   color: var(--color-gray-dark);
+  background-color: var(--color-off-white);
 }
 
 .chatListItemLink {
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx
index 1cee41caf0a7ac6642fbdd6f9c12e6338bac0310..789117627a72808428547193593fc45bc6e20000 100755
--- a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx
@@ -1,11 +1,10 @@
 import React, { Component } from 'react';
 import { injectIntl } from 'react-intl';
 import PropTypes from 'prop-types';
-import { withRouter } from 'react-router';
 import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
 import { styles } from './styles';
 import CustomLogo from './custom-logo/component';
-import UserContent from './user-list-content/component';
+import UserContentContainer from './user-list-content/container';
 
 const propTypes = {
   openChats: PropTypes.arrayOf(String).isRequired,
@@ -40,10 +39,6 @@ const defaultProps = {
 };
 
 class UserList extends Component {
-  constructor(props) {
-    super(props);
-  }
-
   render() {
     const {
       intl,
@@ -79,7 +74,7 @@ class UserList extends Component {
           && CustomLogoUrl
           ? <CustomLogo CustomLogoUrl={CustomLogoUrl} /> : null
         }
-        {<UserContent
+        {<UserContentContainer
           {...{
           intl,
           openChats,
@@ -113,4 +108,4 @@ class UserList extends Component {
 UserList.propTypes = propTypes;
 UserList.defaultProps = defaultProps;
 
-export default withRouter(injectWbResizeEvent(injectIntl(UserList)));
+export default injectWbResizeEvent(injectIntl(UserList));
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js
index b54412be33cc08a3d24abe26550e0583bf685222..9594b4dbdd2940a0e02f1236dd6b821c38fd981a 100755
--- a/bigbluebutton-html5/imports/ui/components/user-list/service.js
+++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js
@@ -258,7 +258,7 @@ const getOpenChats = (chatID) => {
 
 const isVoiceOnlyUser = userId => userId.toString().startsWith('v_');
 
-const getAvailableActions = (currentUser, user, router, isBreakoutRoom) => {
+const getAvailableActions = (currentUser, user, isBreakoutRoom) => {
   const isDialInUser = isVoiceOnlyUser(user.id) || user.isPhoneUser;
 
   const hasAuthority = currentUser.isModerator || user.isCurrent;
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx
index 19ac118b3939da6d5e507817de2dd0f5da04652f..dd8d2a60e34e95543ee61f3802390e995dfa5a93 100644
--- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
 import { styles } from './styles';
 import UserParticipants from './user-participants/component';
 import UserMessages from './user-messages/component';
+import UserPolls from './user-polls/component';
 
 const propTypes = {
   openChats: PropTypes.arrayOf(String).isRequired,
@@ -35,7 +36,7 @@ const defaultProps = {
   meeting: {},
 };
 
-class UserContent extends React.PureComponent {
+class UserContent extends React.Component {
   render() {
     const {
       users,
@@ -59,8 +60,13 @@ class UserContent extends React.PureComponent {
       isPublicChat,
       openChats,
       getGroupChatPrivate,
+      pollIsOpen,
+      forcePollOpen,
     } = this.props;
 
+    const showPoll = pollIsOpen && currentUser.isPresenter;
+    const keepPollOpen = forcePollOpen && !pollIsOpen && currentUser.isPresenter;
+
     return (
       <div
         data-test="userListContent"
@@ -76,7 +82,10 @@ class UserContent extends React.PureComponent {
             roving,
           }}
         />
-
+        {
+          showPoll || keepPollOpen ?
+            <UserPolls /> : null
+        }
         <UserParticipants
           {...{
             users,
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..f9daa37e1f0ee3e31ca5e865d0da36af9dad3211
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import { withTracker } from 'meteor/react-meteor-data';
+import { Session } from 'meteor/session';
+import UserContent from './component';
+
+const UserContentContainer = ({ ...props }) => <UserContent {...props} />;
+
+export default withTracker(({ }) => ({
+  pollIsOpen: Session.equals('isPollOpen', true),
+  forcePollOpen: Session.equals('forcePollOpen', true),
+}))(UserContentContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx
index 6cf653de7481a201eab910cc9c639390f8a47414..54d5fa0d7b24d8bdb4f50fe855d5dfd3e4d7990c 100644
--- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx
@@ -1,6 +1,5 @@
 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
-import { withRouter } from 'react-router';
 import { injectIntl } from 'react-intl';
 import UserDropdown from './user-dropdown/component';
 
@@ -21,7 +20,6 @@ const propTypes = {
   intl: PropTypes.shape({
     formatMessage: PropTypes.func.isRequired,
   }).isRequired,
-  router: PropTypes.shape({}).isRequired,
   isBreakoutRoom: PropTypes.bool,
   getAvailableActions: PropTypes.func.isRequired,
   meeting: PropTypes.shape({}).isRequired,
@@ -53,7 +51,6 @@ class UserListItem extends Component {
       meeting,
       normalizeEmojiName,
       removeUser,
-      router,
       setEmojiStatus,
       toggleVoice,
       user,
@@ -77,7 +74,6 @@ class UserListItem extends Component {
         meeting,
         normalizeEmojiName,
         removeUser,
-        router,
         setEmojiStatus,
         toggleVoice,
         user,
@@ -91,4 +87,4 @@ class UserListItem extends Component {
 UserListItem.propTypes = propTypes;
 UserListItem.defaultProps = defaultProps;
 
-export default withRouter(injectIntl(UserListItem));
+export default injectIntl(UserListItem);
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx
index a5f41d69f6b4b5a2c8457bca493d5b7868ab2384..14cf981a9381212a1305afceb567eabfc8a7b1ff 100755
--- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx
@@ -11,6 +11,7 @@ import DropdownList from '/imports/ui/components/dropdown/list/component';
 import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
 import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
 import _ from 'lodash';
+import { Session } from 'meteor/session';
 import { styles } from './styles';
 import UserName from './../user-name/component';
 import UserIcons from './../user-icons/component';
@@ -169,7 +170,6 @@ class UserDropdown extends Component {
       intl,
       currentUser,
       user,
-      router,
       isBreakoutRoom,
       getAvailableActions,
       getGroupChatPrivate,
@@ -182,7 +182,7 @@ class UserDropdown extends Component {
       changeRole,
     } = this.props;
 
-    const actionPermissions = getAvailableActions(currentUser, user, router, isBreakoutRoom);
+    const actionPermissions = getAvailableActions(currentUser, user, isBreakoutRoom);
     const actions = [];
 
     const {
@@ -236,7 +236,13 @@ class UserDropdown extends Component {
         intl.formatMessage(messages.ChatLabel),
         () => {
           getGroupChatPrivate(currentUser, user);
-          this.onActionsHide(router.push(`/users/chat/${user.id}`));
+          // this.onActionsHide(router.push(`/users/chat/${user.id}`));
+          if (Session.equals('isPollOpen', true)) {
+            Session.set('isPollOpen', false);
+            Session.set('forcePollOpen', true);
+          }
+          Session.set('idChatOpen', user.id);
+          Session.set('isChatOpen', true);
         },
         'chat',
       ));
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..8d91f2b086f0c59ad6db11503cbbdbebd00e7562
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx
@@ -0,0 +1,51 @@
+import React, { Component } from 'react';
+import _ from 'lodash';
+import { defineMessages, injectIntl } from 'react-intl';
+import Icon from '/imports/ui/components/icon/component';
+import { Session } from 'meteor/session';
+import { styles } from './styles';
+
+const intlMessages = defineMessages({
+  pollLabel: {
+    id: 'app.poll.pollPaneTitle',
+    description: 'label for user-list poll button',
+  },
+});
+
+class UserPolls extends Component {
+  constructor(props) {
+    super(props);
+  }
+
+  render() {
+    const { intl } = this.props;
+
+    return (
+      <div className={styles.messages}>
+        {
+          <h2 className={styles.smallTitle}>
+            {'Polling'}
+          </h2>
+        }
+        <div className={styles.scrollableList}>
+          <div
+            role="button"
+            tabIndex={0}
+            className={styles.pollLink}
+            label="Polling"
+            icon="polling"
+            onClick={() => {
+              if (Session.equals('isChatOpen', true)) Session.set('isChatOpen', false);
+              if (Session.equals('isPollOpen', false)) Session.set('isPollOpen', true);
+            }}
+          >
+            <Icon iconName="polling" className={styles.icon} />
+            <span className={styles.label} >{intl.formatMessage(intlMessages.pollLabel)}</span>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default injectIntl(UserPolls);
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..fe468dc689b9ec408661dbad3773d9098eaa6d36
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import Users from '/imports/api/users';
+import Polls from '/imports/api/polls';
+import Auth from '/imports/ui/services/auth';
+import { withTracker } from 'meteor/react-meteor-data';
+import UserPolls from './component';
+
+const UserPollsContainer = ({ ...props }) => <UserPolls {...props} />;
+
+export default withTracker(({ }) => {
+  Meteor.subscribe('results', Auth.meetingID);
+
+  // const getUser = userId => Users.findOne({ userId });
+
+  // const currentUser = Users.findOne({ userId: Auth.userID });
+
+  // const currentPoll = Polls.findOne({ meetingId: Auth.meetingID });
+
+  return {
+    // currentUser,
+    // currentPoll,
+  };
+})(UserPollsContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/styles.scss b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/styles.scss
new file mode 100644
index 0000000000000000000000000000000000000000..8d2a89157dfb7d7956d2d04c488222578955b34d
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/styles.scss
@@ -0,0 +1,64 @@
+@import "../../styles.scss";
+@import "/imports/ui/stylesheets/variables/_all";
+
+$list-item-bg-hover: darken(#F3F6F9, 7%);
+$item-focus-border: #92BCEA;
+
+.smallTitle {
+    font-size: 0.85rem;
+    font-weight: 600;
+    text-transform: uppercase;
+    padding: 0 0.75rem;
+    margin: 0 0 0.625rem 0;
+    color: #8B9AA8;
+    margin-bottom: 12px;
+    margin-top: 8px;
+}
+
+.scrollableList {
+    margin-left: 0.45rem;
+    margin-bottom: 1px;
+    outline: none;
+}
+
+.pollLink {
+    @extend %list-item;
+
+    cursor: pointer;
+    display: flex;
+    flex-flow: row;
+    flex-grow: 0;
+    flex-shrink: 0;
+    padding-top: 10px;
+    padding-bottom: 8px;
+    padding-left: 12px;
+    text-decoration: none;
+    width: 100%;
+    color: var(--color-gray-dark);
+    background-color: var(--color-off-white);
+
+    > i {
+        display: flex;
+        font-size: 175%;
+        color: #8B9AA8;
+        flex: 0 0 2.2rem;
+    }
+
+    > span {
+        font-size: 0.9rem;
+        font-weight: 400;
+        color: black;
+        position: relative;
+        flex-grow: 1;
+        line-height: 2;
+        text-align: left;
+        padding-left: 10px;
+        text-overflow: ellipsis;
+    }
+
+    &:active {
+        background-color: $list-item-bg-hover;
+        box-shadow: inset 0 0 0 var(--border-size) $item-focus-border, inset 1px 0 0 1px $item-focus-border;
+        outline: none;
+    }
+}
diff --git a/bigbluebutton-html5/imports/ui/services/api/index.js b/bigbluebutton-html5/imports/ui/services/api/index.js
index eb93965ead32ce97eaa77c3d87b5a11ec1549955..1d0003969e0bbdae36c17050260e4d1dfb10a51f 100755
--- a/bigbluebutton-html5/imports/ui/services/api/index.js
+++ b/bigbluebutton-html5/imports/ui/services/api/index.js
@@ -56,7 +56,7 @@ export function log(type = 'error', message, ...args) {
   const topic = logContents[0] ? logContents[0].topic : null;
 
   const messageOrStack = message.stack || message.message || JSON.stringify(message);
-  console.debug(`CLIENT LOG (${topic ? type.toUpperCase() + '.' + topic : type.toUpperCase()}): `, messageOrStack, ...args);
+  console.debug(`CLIENT LOG (${topic ? `${type.toUpperCase()}.${topic}` : type.toUpperCase()}): `, messageOrStack, ...args);
 
   Meteor.call('logClient', type, messageOrStack, {
     clientInfo,
diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json
index 4aa691b9405c0ead6f698d9a19161f6a9495c279..24f444492dc48ee884b79e9fa7b1095b2ac4880b 100755
--- a/bigbluebutton-html5/package-lock.json
+++ b/bigbluebutton-html5/package-lock.json
@@ -755,16 +755,6 @@
         "readable-stream": "2.3.6"
       }
     },
-    "create-react-class": {
-      "version": "15.6.2",
-      "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz",
-      "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=",
-      "requires": {
-        "fbjs": "0.8.16",
-        "loose-envify": "1.3.1",
-        "object-assign": "4.1.1"
-      }
-    },
     "cross-spawn": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
@@ -1911,11 +1901,6 @@
         "warning": "3.0.0"
       }
     },
-    "hoist-non-react-statics": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
-      "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
-    },
     "hosted-git-info": {
       "version": "2.7.1",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
@@ -4647,20 +4632,6 @@
         "react-dom": "16.0.1"
       }
     },
-    "react-router": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.5.tgz",
-      "integrity": "sha1-w7eHN1gEWou8lWKu9P9LyMznwTY=",
-      "requires": {
-        "create-react-class": "15.6.2",
-        "history": "3.3.0",
-        "hoist-non-react-statics": "1.2.0",
-        "invariant": "2.2.2",
-        "loose-envify": "1.3.1",
-        "prop-types": "15.6.2",
-        "warning": "3.0.0"
-      }
-    },
     "react-tabs": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-2.1.1.tgz",
diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json
index 7d61104aff416d82da9b7363be42590d17e66fe7..353e348034c1916ef0b7f4c35f4c47e33c342169 100755
--- a/bigbluebutton-html5/package.json
+++ b/bigbluebutton-html5/package.json
@@ -58,7 +58,6 @@
     "react-intl": "~2.4.0",
     "react-modal": "~3.0.4",
     "react-render-in-browser": "^1.0.0",
-    "react-router": "~3.0.2",
     "react-tabs": "~2.1.0",
     "react-toastify": "~2.1.2",
     "react-toggle": "~4.0.2",
diff --git a/bigbluebutton-html5/private/config/settings.yml b/bigbluebutton-html5/private/config/settings.yml
index bed859076c6dc190cc46b4cb4ce0ee4566a991b7..285d378a7910ffeed43c5614ad80101d20a8e959 100644
--- a/bigbluebutton-html5/private/config/settings.yml
+++ b/bigbluebutton-html5/private/config/settings.yml
@@ -173,7 +173,6 @@ public:
     public_userid: public_chat_userid
     public_username: public_chat_username
     storage_key: UNREAD_CHATS
-    path_route: users/chat/
     system_messages_keys:
       chat_clear: PUBLIC_CHAT_CLEAR
   layout: