diff --git a/mod/bigbluebuttonbn/amd/build/rooms.min.js b/mod/bigbluebuttonbn/amd/build/rooms.min.js
index 4239cce6539..c579824e0b4 100644
--- a/mod/bigbluebuttonbn/amd/build/rooms.min.js
+++ b/mod/bigbluebuttonbn/amd/build/rooms.min.js
@@ -5,6 +5,6 @@ define("mod_bigbluebuttonbn/rooms",["exports","./actions","./repository","./room
    * @module      mod_bigbluebuttonbn/rooms
    * @copyright   2021 Blindside Networks Inc
    * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-   */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setupWindowAutoClose=_exports.init=void 0,repository=_interopRequireWildcard(repository),roomUpdater=_interopRequireWildcard(roomUpdater);_exports.init=bigbluebuttonbnid=>{const completionElement=document.querySelector("a[href*=completion_validate]");completionElement&&completionElement.addEventListener("click",(()=>{repository.completionValidate(bigbluebuttonbnid).catch(_notification.exception)})),document.addEventListener("click",(e=>{const joinButton=e.target.closest('[data-action="join"]');joinButton&&(window.open(joinButton.href,"bigbluebutton_conference"),e.preventDefault(),setTimeout((()=>{roomUpdater.updateRoom(!0)}),5e3))})),document.addEventListener(_events.eventTypes.sessionEnded,(()=>{roomUpdater.stop(),roomUpdater.updateRoom(),(0,_notification.fetchNotifications)()})),window.addEventListener(_events.eventTypes.currentSessionEnded,(()=>{roomUpdater.stop(),roomUpdater.updateRoom(),(0,_notification.fetchNotifications)()})),roomUpdater.start()};const autoclose=()=>{window.opener.setTimeout((()=>{roomUpdater.updateRoom(!0)}),5e3),window.removeEventListener("onbeforeunload",autoclose)};_exports.setupWindowAutoClose=()=>{(0,_events.notifyCurrentSessionEnded)(window.opener),window.addEventListener("onbeforeunload",autoclose),window.close()}}));
+   */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setupWindowAutoClose=_exports.init=void 0,repository=_interopRequireWildcard(repository),roomUpdater=_interopRequireWildcard(roomUpdater);_exports.init=(bigbluebuttonbnid,pollInterval)=>{const completionElement=document.querySelector("a[href*=completion_validate]");completionElement&&completionElement.addEventListener("click",(()=>{repository.completionValidate(bigbluebuttonbnid).catch(_notification.exception)})),document.addEventListener("click",(e=>{const joinButton=e.target.closest('[data-action="join"]');joinButton&&(window.open(joinButton.href,"bigbluebutton_conference"),e.preventDefault(),setTimeout((()=>{roomUpdater.updateRoom(!0)}),pollInterval))})),document.addEventListener(_events.eventTypes.sessionEnded,(()=>{roomUpdater.stop(),roomUpdater.updateRoom(),(0,_notification.fetchNotifications)()})),window.addEventListener(_events.eventTypes.currentSessionEnded,(()=>{roomUpdater.stop(),roomUpdater.updateRoom(),(0,_notification.fetchNotifications)()})),roomUpdater.start(pollInterval)};_exports.setupWindowAutoClose=function(){let closeDelay=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2e3;(0,_events.notifyCurrentSessionEnded)(window.opener),window.addEventListener("onbeforeunload",(()=>{window.opener.setTimeout((()=>{roomUpdater.updateRoom(!0)}),closeDelay)}),{once:!0}),window.close()}}));
 
 //# sourceMappingURL=rooms.min.js.map
\ No newline at end of file
diff --git a/mod/bigbluebuttonbn/amd/build/rooms.min.js.map b/mod/bigbluebuttonbn/amd/build/rooms.min.js.map
index 80b618f7a2f..313dbe95918 100644
--- a/mod/bigbluebuttonbn/amd/build/rooms.min.js.map
+++ b/mod/bigbluebuttonbn/amd/build/rooms.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"rooms.min.js","sources":["../src/rooms.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * JS actions for the rooms page for mod_bigbluebuttonbn.\n *\n * @module      mod_bigbluebuttonbn/rooms\n * @copyright   2021 Blindside Networks Inc\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport './actions';\nimport * as repository from './repository';\nimport * as roomUpdater from './roomupdater';\nimport {\n    exception as displayException,\n    fetchNotifications,\n} from 'core/notification';\n\nimport {eventTypes, notifyCurrentSessionEnded} from './events';\n\nconst timeoutjoin = 5000;\n\nexport const init = (bigbluebuttonbnid) => {\n    const completionElement = document.querySelector('a[href*=completion_validate]');\n    if (completionElement) {\n        completionElement.addEventListener(\"click\", () => {\n            repository.completionValidate(bigbluebuttonbnid).catch(displayException);\n        });\n    }\n\n    document.addEventListener('click', e => {\n        const joinButton = e.target.closest('[data-action=\"join\"]');\n        if (joinButton) {\n            window.open(joinButton.href, 'bigbluebutton_conference');\n            e.preventDefault();\n            // Gives the user a bit of time to go into the meeting.\n            setTimeout(() => {\n                roomUpdater.updateRoom(true);\n                }, timeoutjoin);\n        }\n    });\n\n    document.addEventListener(eventTypes.sessionEnded, () => {\n        roomUpdater.stop();\n        roomUpdater.updateRoom();\n        fetchNotifications();\n    });\n\n    window.addEventListener(eventTypes.currentSessionEnded, () => {\n        roomUpdater.stop();\n        roomUpdater.updateRoom();\n        fetchNotifications();\n    });\n    // Room update.\n    roomUpdater.start();\n};\n\n/**\n * Handle autoclosing of the window.\n */\nconst autoclose = () => {\n    window.opener.setTimeout(() => {\n        roomUpdater.updateRoom(true);\n    }, timeoutjoin);\n    window.removeEventListener('onbeforeunload', autoclose);\n};\n\n/**\n * Auto close child windows when clicking the End meeting button.\n */\nexport const setupWindowAutoClose = () => {\n    notifyCurrentSessionEnded(window.opener);\n    window.addEventListener('onbeforeunload', autoclose);\n\n    window.close(); // This does not work as scripts can only close windows that are opened by themselves.\n};\n"],"names":["bigbluebuttonbnid","completionElement","document","querySelector","addEventListener","repository","completionValidate","catch","displayException","e","joinButton","target","closest","window","open","href","preventDefault","setTimeout","roomUpdater","updateRoom","eventTypes","sessionEnded","stop","currentSessionEnded","start","autoclose","opener","removeEventListener","close"],"mappings":";;;;;;;8NAmCqBA,0BACXC,kBAAoBC,SAASC,cAAc,gCAC7CF,mBACAA,kBAAkBG,iBAAiB,SAAS,KACxCC,WAAWC,mBAAmBN,mBAAmBO,MAAMC,4BAI/DN,SAASE,iBAAiB,SAASK,UACzBC,WAAaD,EAAEE,OAAOC,QAAQ,wBAChCF,aACAG,OAAOC,KAAKJ,WAAWK,KAAM,4BAC7BN,EAAEO,iBAEFC,YAAW,KACPC,YAAYC,YAAW,KAjBnB,SAsBhBjB,SAASE,iBAAiBgB,mBAAWC,cAAc,KAC/CH,YAAYI,OACZJ,YAAYC,uDAIhBN,OAAOT,iBAAiBgB,mBAAWG,qBAAqB,KACpDL,YAAYI,OACZJ,YAAYC,uDAIhBD,YAAYM,eAMVC,UAAY,KACdZ,OAAOa,OAAOT,YAAW,KACrBC,YAAYC,YAAW,KA1CX,KA4ChBN,OAAOc,oBAAoB,iBAAkBF,0CAMb,2CACNZ,OAAOa,QACjCb,OAAOT,iBAAiB,iBAAkBqB,WAE1CZ,OAAOe"}
\ No newline at end of file
+{"version":3,"file":"rooms.min.js","sources":["../src/rooms.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * JS actions for the rooms page for mod_bigbluebuttonbn.\n *\n * @module      mod_bigbluebuttonbn/rooms\n * @copyright   2021 Blindside Networks Inc\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport './actions';\nimport * as repository from './repository';\nimport * as roomUpdater from './roomupdater';\nimport {\n    exception as displayException,\n    fetchNotifications,\n} from 'core/notification';\n\nimport {eventTypes, notifyCurrentSessionEnded} from './events';\n\n/**\n * Init the room\n *\n * @param {Number} bigbluebuttonbnid bigblubeutton identifier\n * @param {Number} pollInterval poll interval in miliseconds\n */\nexport const init = (bigbluebuttonbnid, pollInterval) => {\n    const completionElement = document.querySelector('a[href*=completion_validate]');\n    if (completionElement) {\n        completionElement.addEventListener(\"click\", () => {\n            repository.completionValidate(bigbluebuttonbnid).catch(displayException);\n        });\n    }\n\n    document.addEventListener('click', e => {\n        const joinButton = e.target.closest('[data-action=\"join\"]');\n        if (joinButton) {\n            window.open(joinButton.href, 'bigbluebutton_conference');\n            e.preventDefault();\n            // Gives the user a bit of time to go into the meeting before polling the room.\n            setTimeout(() => {\n                roomUpdater.updateRoom(true);\n            }, pollInterval);\n        }\n    });\n\n    document.addEventListener(eventTypes.sessionEnded, () => {\n        roomUpdater.stop();\n        roomUpdater.updateRoom();\n        fetchNotifications();\n    });\n\n    window.addEventListener(eventTypes.currentSessionEnded, () => {\n        roomUpdater.stop();\n        roomUpdater.updateRoom();\n        fetchNotifications();\n    });\n    // Room update.\n    roomUpdater.start(pollInterval);\n};\n\n/**\n * Auto close child windows when clicking the End meeting button.\n * @param {Number} closeDelay time to wait in miliseconds before closing the window\n */\nexport const setupWindowAutoClose = (closeDelay = 2000) => {\n    notifyCurrentSessionEnded(window.opener);\n    window.addEventListener('onbeforeunload', () => {\n            window.opener.setTimeout(() => {\n                roomUpdater.updateRoom(true);\n            }, closeDelay);\n        },\n        {\n            once: true\n        });\n    window.close(); // This does not work as scripts can only close windows that are opened by themselves.\n};\n"],"names":["bigbluebuttonbnid","pollInterval","completionElement","document","querySelector","addEventListener","repository","completionValidate","catch","displayException","e","joinButton","target","closest","window","open","href","preventDefault","setTimeout","roomUpdater","updateRoom","eventTypes","sessionEnded","stop","currentSessionEnded","start","closeDelay","opener","once","close"],"mappings":";;;;;;;8NAuCoB,CAACA,kBAAmBC,sBAC9BC,kBAAoBC,SAASC,cAAc,gCAC7CF,mBACAA,kBAAkBG,iBAAiB,SAAS,KACxCC,WAAWC,mBAAmBP,mBAAmBQ,MAAMC,4BAI/DN,SAASE,iBAAiB,SAASK,UACzBC,WAAaD,EAAEE,OAAOC,QAAQ,wBAChCF,aACAG,OAAOC,KAAKJ,WAAWK,KAAM,4BAC7BN,EAAEO,iBAEFC,YAAW,KACPC,YAAYC,YAAW,KACxBnB,kBAIXE,SAASE,iBAAiBgB,mBAAWC,cAAc,KAC/CH,YAAYI,OACZJ,YAAYC,uDAIhBN,OAAOT,iBAAiBgB,mBAAWG,qBAAqB,KACpDL,YAAYI,OACZJ,YAAYC,uDAIhBD,YAAYM,MAAMxB,6CAOc,eAACyB,kEAAa,0CACpBZ,OAAOa,QACjCb,OAAOT,iBAAiB,kBAAkB,KAClCS,OAAOa,OAAOT,YAAW,KACrBC,YAAYC,YAAW,KACxBM,cAEP,CACIE,MAAM,IAEdd,OAAOe"}
\ No newline at end of file
diff --git a/mod/bigbluebuttonbn/amd/build/roomupdater.min.js b/mod/bigbluebuttonbn/amd/build/roomupdater.min.js
index 5709e4fb278..4825735118e 100644
--- a/mod/bigbluebuttonbn/amd/build/roomupdater.min.js
+++ b/mod/bigbluebuttonbn/amd/build/roomupdater.min.js
@@ -5,6 +5,6 @@ define("mod_bigbluebuttonbn/roomupdater",["exports","core/templates","core/notif
    * @module      mod_bigbluebuttonbn/roomupdater
    * @copyright   2021 Blindside Networks Inc
    * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-   */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.updateRoom=_exports.stop=_exports.start=void 0,_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};let updateCount=0,updateFactor=1,timerReference=null,timerRunning=!1;_exports.start=()=>{timerRunning=!0,timerReference=setTimeout((()=>poll()),5e3)};_exports.stop=()=>{timerRunning=!1,timerReference&&(clearInterval(timerReference),timerReference=null),updateCount=0,updateFactor=1};const poll=()=>{timerRunning&&updateCount%updateFactor==0&&updateRoom().then((()=>{updateFactor>=10?updateFactor=1:updateFactor++})).catch().then((()=>{timerReference=setTimeout((()=>poll()),5e3)})).catch()},updateRoom=function(){let updatecache=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const bbbRoomViewElement=document.getElementById("bbb-room-view"),bbbId=bbbRoomViewElement.dataset.bbbId,groupId=bbbRoomViewElement.dataset.groupId;return(0,_repository.getMeetingInfo)(bbbId,groupId,updatecache).then((data=>(data.haspresentations=!1,data.presentations&&data.presentations.length&&(data.haspresentations=!0),_templates.default.renderForPromise("mod_bigbluebuttonbn/room_view",data)))).then((_ref=>{let{html:html,js:js}=_ref;return _templates.default.replaceNodeContents(bbbRoomViewElement,html,js)})).catch(_notification.exception)};_exports.updateRoom=updateRoom}));
+   */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.updateRoom=_exports.stop=_exports.start=void 0,_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};let timerReference=null,timerRunning=!1,pollInterval=0,pollIntervalFactor=1;const resetValues=()=>{timerRunning=!1,timerReference=null,pollInterval=0,pollIntervalFactor=1};_exports.start=interval=>{resetValues(),timerRunning=!0,pollInterval=interval,poll()};_exports.stop=()=>{timerReference&&clearTimeout(timerReference),resetValues()};const poll=()=>{timerRunning&&pollInterval&&updateRoom().then((updateOk=>(updateOk||(pollIntervalFactor=pollIntervalFactor<10?pollIntervalFactor+1:10),timerReference=setTimeout((()=>poll()),pollInterval*pollIntervalFactor),!0))).catch()},updateRoom=function(){let updatecache=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const bbbRoomViewElement=document.getElementById("bbb-room-view"),bbbId=bbbRoomViewElement.dataset.bbbId,groupId=bbbRoomViewElement.dataset.groupId;return(0,_repository.getMeetingInfo)(bbbId,groupId,updatecache).then((data=>(data.haspresentations=!(!data.presentations||!data.presentations.length),_templates.default.renderForPromise("mod_bigbluebuttonbn/room_view",data)))).then((_ref=>{let{html:html,js:js}=_ref;return _templates.default.replaceNodeContents(bbbRoomViewElement,html,js)})).then((()=>!0)).catch((ex=>((0,_notification.exception)(ex),!1)))};_exports.updateRoom=updateRoom}));
 
 //# sourceMappingURL=roomupdater.min.js.map
\ No newline at end of file
diff --git a/mod/bigbluebuttonbn/amd/build/roomupdater.min.js.map b/mod/bigbluebuttonbn/amd/build/roomupdater.min.js.map
index 069d694dbb7..8e4f5469e4b 100644
--- a/mod/bigbluebuttonbn/amd/build/roomupdater.min.js.map
+++ b/mod/bigbluebuttonbn/amd/build/roomupdater.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"roomupdater.min.js","sources":["../src/roomupdater.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * JS room updater.\n *\n * @module      mod_bigbluebuttonbn/roomupdater\n * @copyright   2021 Blindside Networks Inc\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from \"core/templates\";\nimport {exception as displayException} from 'core/notification';\nimport {getMeetingInfo} from './repository';\n\nconst timeout = 5000;\nconst maxFactor = 10;\n\nlet updateCount = 0;\nlet updateFactor = 1;\nlet timerReference = null;\nlet timerRunning = false;\n\nconst resetValues = () => {\n    updateCount = 0;\n    updateFactor = 1;\n};\n\n/**\n * Start the information poller.\n */\nexport const start = () => {\n    timerRunning = true;\n    timerReference = setTimeout(() => poll(), timeout);\n};\n\n/**\n * Stop the room updater.\n */\nexport const stop = () => {\n    timerRunning = false;\n    if (timerReference) {\n        clearInterval(timerReference);\n        timerReference = null;\n    }\n\n    resetValues();\n};\n\nconst poll = () => {\n    if (!timerRunning) {\n        // The poller has been stopped.\n        return;\n    }\n    if ((updateCount % updateFactor) === 0) {\n        updateRoom()\n        .then(() => {\n            if (updateFactor >= maxFactor) {\n                updateFactor = 1;\n            } else {\n                updateFactor++;\n            }\n\n            return;\n\n        })\n        .catch()\n        .then(() => {\n            timerReference = setTimeout(() => poll(), timeout);\n            return;\n        })\n        .catch();\n    }\n};\n\n/**\n * Update the room information.\n *\n * @param {boolean} [updatecache=false]\n * @returns {Promise}\n */\nexport const updateRoom = (updatecache = false) => {\n    const bbbRoomViewElement = document.getElementById('bbb-room-view');\n    const bbbId = bbbRoomViewElement.dataset.bbbId;\n    const groupId = bbbRoomViewElement.dataset.groupId;\n    return getMeetingInfo(bbbId, groupId, updatecache)\n        .then(data => {\n            // Just make sure we have the right information for the template.\n            data.haspresentations = false;\n            if (data.presentations && data.presentations.length) {\n                data.haspresentations = true;\n            }\n            return Templates.renderForPromise('mod_bigbluebuttonbn/room_view', data);\n        })\n        .then(({html, js}) => Templates.replaceNodeContents(bbbRoomViewElement, html, js))\n        .catch(displayException);\n};\n"],"names":["updateCount","updateFactor","timerReference","timerRunning","setTimeout","poll","clearInterval","updateRoom","then","catch","updatecache","bbbRoomViewElement","document","getElementById","bbbId","dataset","groupId","data","haspresentations","presentations","length","Templates","renderForPromise","_ref","html","js","replaceNodeContents","displayException"],"mappings":";;;;;;;uLA8BIA,YAAc,EACdC,aAAe,EACfC,eAAiB,KACjBC,cAAe,iBAUE,KACjBA,cAAe,EACfD,eAAiBE,YAAW,IAAMC,QAlBtB,oBAwBI,KAChBF,cAAe,EACXD,iBACAI,cAAcJ,gBACdA,eAAiB,MAnBrBF,YAAc,EACdC,aAAe,SAwBbI,KAAO,KACJF,cAIAH,YAAcC,cAAkB,GACjCM,aACCC,MAAK,KACEP,cAzCE,GA0CFA,aAAe,EAEfA,kBAMPQ,QACAD,MAAK,KACFN,eAAiBE,YAAW,IAAMC,QArD9B,QAwDPI,SAUIF,WAAa,eAACG,0EACjBC,mBAAqBC,SAASC,eAAe,iBAC7CC,MAAQH,mBAAmBI,QAAQD,MACnCE,QAAUL,mBAAmBI,QAAQC,eACpC,8BAAeF,MAAOE,QAASN,aACjCF,MAAKS,OAEFA,KAAKC,kBAAmB,EACpBD,KAAKE,eAAiBF,KAAKE,cAAcC,SACzCH,KAAKC,kBAAmB,GAErBG,mBAAUC,iBAAiB,gCAAiCL,SAEtET,MAAKe,WAACC,KAACA,KAADC,GAAOA,gBAAQJ,mBAAUK,oBAAoBf,mBAAoBa,KAAMC,OAC7EhB,MAAMkB"}
\ No newline at end of file
+{"version":3,"file":"roomupdater.min.js","sources":["../src/roomupdater.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * JS room updater.\n *\n * @module      mod_bigbluebuttonbn/roomupdater\n * @copyright   2021 Blindside Networks Inc\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from \"core/templates\";\nimport {exception as displayException} from 'core/notification';\nimport {getMeetingInfo} from './repository';\n\nlet timerReference = null;\nlet timerRunning = false;\nlet pollInterval = 0;\nlet pollIntervalFactor = 1;\nconst MAX_POLL_INTERVAL_FACTOR = 10;\n\nconst resetValues = () => {\n    timerRunning = false;\n    timerReference = null;\n    pollInterval = 0;\n    pollIntervalFactor = 1;\n};\n\n/**\n * Start the information poller.\n * @param {Number} interval interval in miliseconds between each poll action.\n */\nexport const start = (interval) => {\n    resetValues();\n    timerRunning = true;\n    pollInterval = interval;\n    poll();\n};\n\n/**\n * Stop the room updater.\n */\nexport const stop = () => {\n    if (timerReference) {\n        clearTimeout(timerReference);\n    }\n    resetValues();\n};\n\n/**\n * Start the information poller.\n */\nconst poll = () => {\n    if (!timerRunning || !pollInterval) {\n        // The poller has been stopped.\n        return;\n    }\n    updateRoom()\n        .then((updateOk) => {\n            if (!updateOk) {\n                pollIntervalFactor = (pollIntervalFactor < MAX_POLL_INTERVAL_FACTOR) ?\n                    pollIntervalFactor + 1 : MAX_POLL_INTERVAL_FACTOR;\n                // We make sure if there is an error that we do not try too often.\n            }\n            timerReference = setTimeout(() => poll(), pollInterval * pollIntervalFactor);\n            return true;\n        })\n        .catch();\n};\n\n/**\n * Update the room information.\n *\n * @param {boolean} [updatecache=false] should we update cache\n * @returns {Promise}\n */\nexport const updateRoom = (updatecache = false) => {\n    const bbbRoomViewElement = document.getElementById('bbb-room-view');\n    const bbbId = bbbRoomViewElement.dataset.bbbId;\n    const groupId = bbbRoomViewElement.dataset.groupId;\n    return getMeetingInfo(bbbId, groupId, updatecache)\n        .then(data => {\n            // Just make sure we have the right information for the template.\n            data.haspresentations = !!(data.presentations && data.presentations.length);\n            return Templates.renderForPromise('mod_bigbluebuttonbn/room_view', data);\n        })\n        .then(({html, js}) => Templates.replaceNodeContents(bbbRoomViewElement, html, js))\n        .then(() => true)\n        .catch((ex) => {\n            displayException(ex);\n            return false;\n        });\n};\n"],"names":["timerReference","timerRunning","pollInterval","pollIntervalFactor","resetValues","interval","poll","clearTimeout","updateRoom","then","updateOk","setTimeout","catch","updatecache","bbbRoomViewElement","document","getElementById","bbbId","dataset","groupId","data","haspresentations","presentations","length","Templates","renderForPromise","_ref","html","js","replaceNodeContents","ex"],"mappings":";;;;;;;uLA2BIA,eAAiB,KACjBC,cAAe,EACfC,aAAe,EACfC,mBAAqB,QAGnBC,YAAc,KAChBH,cAAe,EACfD,eAAiB,KACjBE,aAAe,EACfC,mBAAqB,kBAOHE,WAClBD,cACAH,cAAe,EACfC,aAAeG,SACfC,sBAMgB,KACZN,gBACAO,aAAaP,gBAEjBI,qBAMEE,KAAO,KACJL,cAAiBC,cAItBM,aACKC,MAAMC,WACEA,WACDP,mBAAsBA,mBAzCL,GA0CbA,mBAAqB,EA1CR,IA6CrBH,eAAiBW,YAAW,IAAML,QAAQJ,aAAeC,qBAClD,KAEVS,SASIJ,WAAa,eAACK,0EACjBC,mBAAqBC,SAASC,eAAe,iBAC7CC,MAAQH,mBAAmBI,QAAQD,MACnCE,QAAUL,mBAAmBI,QAAQC,eACpC,8BAAeF,MAAOE,QAASN,aACjCJ,MAAKW,OAEFA,KAAKC,oBAAsBD,KAAKE,gBAAiBF,KAAKE,cAAcC,QAC7DC,mBAAUC,iBAAiB,gCAAiCL,SAEtEX,MAAKiB,WAACC,KAACA,KAADC,GAAOA,gBAAQJ,mBAAUK,oBAAoBf,mBAAoBa,KAAMC,OAC7EnB,MAAK,KAAM,IACXG,OAAOkB,iCACaA,KACV"}
\ No newline at end of file
diff --git a/mod/bigbluebuttonbn/amd/src/rooms.js b/mod/bigbluebuttonbn/amd/src/rooms.js
index 75266f114bf..da72f10ba07 100644
--- a/mod/bigbluebuttonbn/amd/src/rooms.js
+++ b/mod/bigbluebuttonbn/amd/src/rooms.js
@@ -31,9 +31,13 @@ import {
 
 import {eventTypes, notifyCurrentSessionEnded} from './events';
 
-const timeoutjoin = 5000;
-
-export const init = (bigbluebuttonbnid) => {
+/**
+ * Init the room
+ *
+ * @param {Number} bigbluebuttonbnid bigblubeutton identifier
+ * @param {Number} pollInterval poll interval in miliseconds
+ */
+export const init = (bigbluebuttonbnid, pollInterval) => {
     const completionElement = document.querySelector('a[href*=completion_validate]');
     if (completionElement) {
         completionElement.addEventListener("click", () => {
@@ -46,10 +50,10 @@ export const init = (bigbluebuttonbnid) => {
         if (joinButton) {
             window.open(joinButton.href, 'bigbluebutton_conference');
             e.preventDefault();
-            // Gives the user a bit of time to go into the meeting.
+            // Gives the user a bit of time to go into the meeting before polling the room.
             setTimeout(() => {
                 roomUpdater.updateRoom(true);
-                }, timeoutjoin);
+            }, pollInterval);
         }
     });
 
@@ -65,25 +69,22 @@ export const init = (bigbluebuttonbnid) => {
         fetchNotifications();
     });
     // Room update.
-    roomUpdater.start();
-};
-
-/**
- * Handle autoclosing of the window.
- */
-const autoclose = () => {
-    window.opener.setTimeout(() => {
-        roomUpdater.updateRoom(true);
-    }, timeoutjoin);
-    window.removeEventListener('onbeforeunload', autoclose);
+    roomUpdater.start(pollInterval);
 };
 
 /**
  * Auto close child windows when clicking the End meeting button.
+ * @param {Number} closeDelay time to wait in miliseconds before closing the window
  */
-export const setupWindowAutoClose = () => {
+export const setupWindowAutoClose = (closeDelay = 2000) => {
     notifyCurrentSessionEnded(window.opener);
-    window.addEventListener('onbeforeunload', autoclose);
-
+    window.addEventListener('onbeforeunload', () => {
+            window.opener.setTimeout(() => {
+                roomUpdater.updateRoom(true);
+            }, closeDelay);
+        },
+        {
+            once: true
+        });
     window.close(); // This does not work as scripts can only close windows that are opened by themselves.
 };
diff --git a/mod/bigbluebuttonbn/amd/src/roomupdater.js b/mod/bigbluebuttonbn/amd/src/roomupdater.js
index 21bea7fdf5c..4792c8aba90 100644
--- a/mod/bigbluebuttonbn/amd/src/roomupdater.js
+++ b/mod/bigbluebuttonbn/amd/src/roomupdater.js
@@ -25,70 +25,65 @@ import Templates from "core/templates";
 import {exception as displayException} from 'core/notification';
 import {getMeetingInfo} from './repository';
 
-const timeout = 5000;
-const maxFactor = 10;
-
-let updateCount = 0;
-let updateFactor = 1;
 let timerReference = null;
 let timerRunning = false;
+let pollInterval = 0;
+let pollIntervalFactor = 1;
+const MAX_POLL_INTERVAL_FACTOR = 10;
 
 const resetValues = () => {
-    updateCount = 0;
-    updateFactor = 1;
+    timerRunning = false;
+    timerReference = null;
+    pollInterval = 0;
+    pollIntervalFactor = 1;
 };
 
 /**
  * Start the information poller.
+ * @param {Number} interval interval in miliseconds between each poll action.
  */
-export const start = () => {
+export const start = (interval) => {
+    resetValues();
     timerRunning = true;
-    timerReference = setTimeout(() => poll(), timeout);
+    pollInterval = interval;
+    poll();
 };
 
 /**
  * Stop the room updater.
  */
 export const stop = () => {
-    timerRunning = false;
     if (timerReference) {
-        clearInterval(timerReference);
-        timerReference = null;
+        clearTimeout(timerReference);
     }
-
     resetValues();
 };
 
+/**
+ * Start the information poller.
+ */
 const poll = () => {
-    if (!timerRunning) {
+    if (!timerRunning || !pollInterval) {
         // The poller has been stopped.
         return;
     }
-    if ((updateCount % updateFactor) === 0) {
-        updateRoom()
-        .then(() => {
-            if (updateFactor >= maxFactor) {
-                updateFactor = 1;
-            } else {
-                updateFactor++;
+    updateRoom()
+        .then((updateOk) => {
+            if (!updateOk) {
+                pollIntervalFactor = (pollIntervalFactor < MAX_POLL_INTERVAL_FACTOR) ?
+                    pollIntervalFactor + 1 : MAX_POLL_INTERVAL_FACTOR;
+                // We make sure if there is an error that we do not try too often.
             }
-
-            return;
-
-        })
-        .catch()
-        .then(() => {
-            timerReference = setTimeout(() => poll(), timeout);
-            return;
+            timerReference = setTimeout(() => poll(), pollInterval * pollIntervalFactor);
+            return true;
         })
         .catch();
-    }
 };
 
 /**
  * Update the room information.
  *
- * @param {boolean} [updatecache=false]
+ * @param {boolean} [updatecache=false] should we update cache
  * @returns {Promise}
  */
 export const updateRoom = (updatecache = false) => {
@@ -98,12 +93,13 @@ export const updateRoom = (updatecache = false) => {
     return getMeetingInfo(bbbId, groupId, updatecache)
         .then(data => {
             // Just make sure we have the right information for the template.
-            data.haspresentations = false;
-            if (data.presentations && data.presentations.length) {
-                data.haspresentations = true;
-            }
+            data.haspresentations = !!(data.presentations && data.presentations.length);
             return Templates.renderForPromise('mod_bigbluebuttonbn/room_view', data);
         })
         .then(({html, js}) => Templates.replaceNodeContents(bbbRoomViewElement, html, js))
-        .catch(displayException);
+        .then(() => true)
+        .catch((ex) => {
+            displayException(ex);
+            return false;
+        });
 };
diff --git a/mod/bigbluebuttonbn/classes/local/config.php b/mod/bigbluebuttonbn/classes/local/config.php
index 4717fa05e87..39a0d0124d7 100644
--- a/mod/bigbluebuttonbn/classes/local/config.php
+++ b/mod/bigbluebuttonbn/classes/local/config.php
@@ -17,6 +17,7 @@
 namespace mod_bigbluebuttonbn\local;
 
 use mod_bigbluebuttonbn\instance;
+use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
 use mod_bigbluebuttonbn\recording;
 
 /**
@@ -110,6 +111,7 @@ class config {
             'hideuserlist_editable' => true,
             'welcome_default' => '',
             'default_dpa_accepted' => false,
+            'poll_interval' => bigbluebutton_proxy::DEFAULT_POLL_INTERVAL,
         ];
     }
 
@@ -215,6 +217,7 @@ class config {
             'hideuserlist_default' => self::get('hideuserlist_default'),
             'welcome_default' => self::get('welcome_default'),
             'welcome_editable' => self::get('welcome_editable'),
+            'poll_interval' => self::get('poll_interval'),
         ];
     }
 
diff --git a/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php b/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php
index a62303544b8..4c144f10ced 100644
--- a/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php
+++ b/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php
@@ -40,6 +40,16 @@ use stdClass;
  */
 class bigbluebutton_proxy extends proxy_base {
 
+    /**
+     * Minimum poll interval for remote bigbluebutton server in seconds.
+     */
+    const MIN_POLL_INTERVAL = 2;
+
+    /**
+     * Default poll interval for remote bigbluebutton server in seconds.
+     */
+    const DEFAULT_POLL_INTERVAL = 5;
+
     /**
      * Builds and returns a url for joining a bigbluebutton meeting.
      *
@@ -490,4 +500,20 @@ class bigbluebutton_proxy extends proxy_base {
         $hendslength = count($hends);
         return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks');
     }
+
+    /**
+     * Get the poll interval as it is set in the configuration
+     *
+     * If configuration value is under the threshold of {@see self::MIN_POLL_INTERVAL},
+     * then return the {@see self::MIN_POLL_INTERVAL} value.
+     *
+     * @return int the poll interval in seconds
+     */
+    public static function get_poll_interval(): int {
+        $pollinterval = intval(config::get('poll_interval'));
+        if ($pollinterval < self::MIN_POLL_INTERVAL) {
+            $pollinterval = self::MIN_POLL_INTERVAL;
+        }
+        return $pollinterval;
+    }
 }
diff --git a/mod/bigbluebuttonbn/classes/output/view_page.php b/mod/bigbluebuttonbn/classes/output/view_page.php
index a087c2278c6..09339f85cb5 100644
--- a/mod/bigbluebuttonbn/classes/output/view_page.php
+++ b/mod/bigbluebuttonbn/classes/output/view_page.php
@@ -20,6 +20,7 @@ use core\check\result;
 use core\output\notification;
 use mod_bigbluebuttonbn\instance;
 use mod_bigbluebuttonbn\local\config;
+use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
 use mod_bigbluebuttonbn\meeting;
 use renderable;
 use renderer_base;
@@ -55,8 +56,10 @@ class view_page implements renderable, templatable {
      * @return stdClass
      */
     public function export_for_template(renderer_base $output): stdClass {
+        $pollinterval = bigbluebutton_proxy::get_poll_interval();
         $templatedata = (object) [
             'instanceid' => $this->instance->get_instance_id(),
+            'pollinterval' => $pollinterval * 1000, // Javascript poll interval is in miliseconds.
             'groupselector' => $output->render_groups_selector($this->instance),
             'meetingname' => $this->instance->get_meeting_name(),
             'description' => $this->instance->get_meeting_description(true),
diff --git a/mod/bigbluebuttonbn/classes/settings.php b/mod/bigbluebuttonbn/classes/settings.php
index 56d60d933cb..0ea2bc274c0 100644
--- a/mod/bigbluebuttonbn/classes/settings.php
+++ b/mod/bigbluebuttonbn/classes/settings.php
@@ -30,6 +30,7 @@ use cache_helper;
 use lang_string;
 use mod_bigbluebuttonbn\local\config;
 use mod_bigbluebuttonbn\local\helpers\roles;
+use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
 
 /**
  * The mod_bigbluebuttonbn settings helper
@@ -218,6 +219,18 @@ class settings {
                 $item,
                 $settingsgeneral
             );
+            $item = new admin_setting_configtext(
+                'bigbluebuttonbn_poll_interval',
+                get_string('config_poll_interval', 'bigbluebuttonbn'),
+                get_string('config_poll_interval_description', 'bigbluebuttonbn'),
+                bigbluebutton_proxy::DEFAULT_POLL_INTERVAL,
+                PARAM_INT
+            );
+            $this->add_conditional_element(
+                'poll_interval',
+                $item,
+                $settingsgeneral
+            );
         }
         return $settingsgeneral;
     }
diff --git a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php
index 91f9ec5b7c3..0d68efc7873 100644
--- a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php
+++ b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php
@@ -216,6 +216,10 @@ $string['config_participant_description'] = 'These settings define the default r
 $string['config_participant_moderator_default'] = 'Moderator';
 $string['config_participant_moderator_default_description'] = 'This rule is used by default when a new room is added.';
 
+$string['config_poll_interval'] = 'Poll interval to refresh the room\'s status';
+$string['config_poll_interval_description'] = 'Poll interval to refresh the room\'s status. Please make sure that this value is
+ no too low as it might have an impact on the remote server. It cannot be less than two seconds.';
+
 $string['config_userlimit'] = 'User limit';
 $string['config_userlimit_description'] = 'These settings enable or disable options in the UI and also define default values for these options.';
 $string['config_userlimit_default'] = 'User limit enabled by default';
diff --git a/mod/bigbluebuttonbn/templates/view_page.mustache b/mod/bigbluebuttonbn/templates/view_page.mustache
index 933b3537d1e..b467f643b1f 100644
--- a/mod/bigbluebuttonbn/templates/view_page.mustache
+++ b/mod/bigbluebuttonbn/templates/view_page.mustache
@@ -35,8 +35,10 @@
                     "title": "Upgrade now"
                 }
             ]
-        }
+        },
+        "pollinterval": 5
     }
+
 }}
 {{{groupselector}}}
 
@@ -62,8 +64,9 @@
 {{#js}}
 require(['mod_bigbluebuttonbn/rooms'], function(rooms) {
     // Register action on all buttons.
-    rooms.init({
-        bigbluebuttonbnid: {{{instanceid}}},
+    rooms.init(
+        {{instanceid}},
+        {{pollinterval}}
+        );
     });
-});
 {{/js}}
diff --git a/mod/bigbluebuttonbn/tests/local/proxy/bigbluebutton_proxy_test.php b/mod/bigbluebuttonbn/tests/local/proxy/bigbluebutton_proxy_test.php
new file mode 100644
index 00000000000..789f80c457d
--- /dev/null
+++ b/mod/bigbluebuttonbn/tests/local/proxy/bigbluebutton_proxy_test.php
@@ -0,0 +1,47 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+namespace mod_bigbluebuttonbn\local\proxy;
+
+use mod_bigbluebuttonbn\instance;
+use mod_bigbluebuttonbn\test\testcase_helper_trait;
+
+/**
+ * Recording proxy tests class.
+ *
+ * @package   mod_bigbluebuttonbn
+ * @copyright 2018 - present, Blindside Networks Inc
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
+ * @covers  \mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy
+ * @coversDefaultClass \mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy
+ */
+class bigbluebutton_proxy_test extends \advanced_testcase {
+    /**
+     * Test poll interval value
+     *
+     * @covers  \mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy::get_poll_interval
+     * @return void
+     */
+    public function test_get_poll_interval() {
+        global $CFG;
+        $this->resetAfterTest();
+        $CFG->bigbluebuttonbn['poll_interval'] = 15;
+        $this->assertEquals(15, bigbluebutton_proxy::get_poll_interval());
+        $CFG->bigbluebuttonbn['poll_interval'] = 0;
+        $this->assertEquals(bigbluebutton_proxy::MIN_POLL_INTERVAL, bigbluebutton_proxy::get_poll_interval());
+    }
+}