MDL-74545 mod_bigbluebuttonbn: Allow changing the polling value

* The polling time on the BBB room page can be changed via the poll_interval
settings (general settings)
This commit is contained in:
Laurent David 2022-06-29 22:13:52 +02:00
parent 720bd60fc6
commit 1077d473c4
13 changed files with 159 additions and 63 deletions

View File

@ -5,6 +5,6 @@ define("mod_bigbluebuttonbn/rooms",["exports","./actions","./repository","./room
* @module mod_bigbluebuttonbn/rooms * @module mod_bigbluebuttonbn/rooms
* @copyright 2021 Blindside Networks Inc * @copyright 2021 Blindside Networks Inc
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @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 //# sourceMappingURL=rooms.min.js.map

View File

@ -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"} {"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"}

View File

@ -5,6 +5,6 @@ define("mod_bigbluebuttonbn/roomupdater",["exports","core/templates","core/notif
* @module mod_bigbluebuttonbn/roomupdater * @module mod_bigbluebuttonbn/roomupdater
* @copyright 2021 Blindside Networks Inc * @copyright 2021 Blindside Networks Inc
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @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 //# sourceMappingURL=roomupdater.min.js.map

View File

@ -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"} {"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"}

View File

@ -31,9 +31,13 @@ import {
import {eventTypes, notifyCurrentSessionEnded} from './events'; import {eventTypes, notifyCurrentSessionEnded} from './events';
const timeoutjoin = 5000; /**
* Init the room
export const init = (bigbluebuttonbnid) => { *
* @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]'); const completionElement = document.querySelector('a[href*=completion_validate]');
if (completionElement) { if (completionElement) {
completionElement.addEventListener("click", () => { completionElement.addEventListener("click", () => {
@ -46,10 +50,10 @@ export const init = (bigbluebuttonbnid) => {
if (joinButton) { if (joinButton) {
window.open(joinButton.href, 'bigbluebutton_conference'); window.open(joinButton.href, 'bigbluebutton_conference');
e.preventDefault(); 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(() => { setTimeout(() => {
roomUpdater.updateRoom(true); roomUpdater.updateRoom(true);
}, timeoutjoin); }, pollInterval);
} }
}); });
@ -65,25 +69,22 @@ export const init = (bigbluebuttonbnid) => {
fetchNotifications(); fetchNotifications();
}); });
// Room update. // Room update.
roomUpdater.start(); roomUpdater.start(pollInterval);
};
/**
* Handle autoclosing of the window.
*/
const autoclose = () => {
window.opener.setTimeout(() => {
roomUpdater.updateRoom(true);
}, timeoutjoin);
window.removeEventListener('onbeforeunload', autoclose);
}; };
/** /**
* Auto close child windows when clicking the End meeting button. * 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); 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. window.close(); // This does not work as scripts can only close windows that are opened by themselves.
}; };

View File

@ -25,70 +25,65 @@ import Templates from "core/templates";
import {exception as displayException} from 'core/notification'; import {exception as displayException} from 'core/notification';
import {getMeetingInfo} from './repository'; import {getMeetingInfo} from './repository';
const timeout = 5000;
const maxFactor = 10;
let updateCount = 0;
let updateFactor = 1;
let timerReference = null; let timerReference = null;
let timerRunning = false; let timerRunning = false;
let pollInterval = 0;
let pollIntervalFactor = 1;
const MAX_POLL_INTERVAL_FACTOR = 10;
const resetValues = () => { const resetValues = () => {
updateCount = 0; timerRunning = false;
updateFactor = 1; timerReference = null;
pollInterval = 0;
pollIntervalFactor = 1;
}; };
/** /**
* Start the information poller. * Start the information poller.
* @param {Number} interval interval in miliseconds between each poll action.
*/ */
export const start = () => { export const start = (interval) => {
resetValues();
timerRunning = true; timerRunning = true;
timerReference = setTimeout(() => poll(), timeout); pollInterval = interval;
poll();
}; };
/** /**
* Stop the room updater. * Stop the room updater.
*/ */
export const stop = () => { export const stop = () => {
timerRunning = false;
if (timerReference) { if (timerReference) {
clearInterval(timerReference); clearTimeout(timerReference);
timerReference = null;
} }
resetValues(); resetValues();
}; };
/**
* Start the information poller.
*/
const poll = () => { const poll = () => {
if (!timerRunning) { if (!timerRunning || !pollInterval) {
// The poller has been stopped. // The poller has been stopped.
return; return;
} }
if ((updateCount % updateFactor) === 0) { updateRoom()
updateRoom() .then((updateOk) => {
.then(() => { if (!updateOk) {
if (updateFactor >= maxFactor) { pollIntervalFactor = (pollIntervalFactor < MAX_POLL_INTERVAL_FACTOR) ?
updateFactor = 1; pollIntervalFactor + 1 : MAX_POLL_INTERVAL_FACTOR;
} else { // We make sure if there is an error that we do not try too often.
updateFactor++;
} }
timerReference = setTimeout(() => poll(), pollInterval * pollIntervalFactor);
return; return true;
})
.catch()
.then(() => {
timerReference = setTimeout(() => poll(), timeout);
return;
}) })
.catch(); .catch();
}
}; };
/** /**
* Update the room information. * Update the room information.
* *
* @param {boolean} [updatecache=false] * @param {boolean} [updatecache=false] should we update cache
* @returns {Promise} * @returns {Promise}
*/ */
export const updateRoom = (updatecache = false) => { export const updateRoom = (updatecache = false) => {
@ -98,12 +93,13 @@ export const updateRoom = (updatecache = false) => {
return getMeetingInfo(bbbId, groupId, updatecache) return getMeetingInfo(bbbId, groupId, updatecache)
.then(data => { .then(data => {
// Just make sure we have the right information for the template. // Just make sure we have the right information for the template.
data.haspresentations = false; data.haspresentations = !!(data.presentations && data.presentations.length);
if (data.presentations && data.presentations.length) {
data.haspresentations = true;
}
return Templates.renderForPromise('mod_bigbluebuttonbn/room_view', data); return Templates.renderForPromise('mod_bigbluebuttonbn/room_view', data);
}) })
.then(({html, js}) => Templates.replaceNodeContents(bbbRoomViewElement, html, js)) .then(({html, js}) => Templates.replaceNodeContents(bbbRoomViewElement, html, js))
.catch(displayException); .then(() => true)
.catch((ex) => {
displayException(ex);
return false;
});
}; };

View File

@ -17,6 +17,7 @@
namespace mod_bigbluebuttonbn\local; namespace mod_bigbluebuttonbn\local;
use mod_bigbluebuttonbn\instance; use mod_bigbluebuttonbn\instance;
use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
use mod_bigbluebuttonbn\recording; use mod_bigbluebuttonbn\recording;
/** /**
@ -110,6 +111,7 @@ class config {
'hideuserlist_editable' => true, 'hideuserlist_editable' => true,
'welcome_default' => '', 'welcome_default' => '',
'default_dpa_accepted' => false, 'default_dpa_accepted' => false,
'poll_interval' => bigbluebutton_proxy::DEFAULT_POLL_INTERVAL,
]; ];
} }
@ -215,6 +217,7 @@ class config {
'hideuserlist_default' => self::get('hideuserlist_default'), 'hideuserlist_default' => self::get('hideuserlist_default'),
'welcome_default' => self::get('welcome_default'), 'welcome_default' => self::get('welcome_default'),
'welcome_editable' => self::get('welcome_editable'), 'welcome_editable' => self::get('welcome_editable'),
'poll_interval' => self::get('poll_interval'),
]; ];
} }

View File

@ -40,6 +40,16 @@ use stdClass;
*/ */
class bigbluebutton_proxy extends proxy_base { 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. * Builds and returns a url for joining a bigbluebutton meeting.
* *
@ -490,4 +500,20 @@ class bigbluebutton_proxy extends proxy_base {
$hendslength = count($hends); $hendslength = count($hends);
return ($hends[$hendslength - 1] == 'com' && $hends[$hendslength - 2] == 'blindsidenetworks'); 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;
}
} }

View File

@ -20,6 +20,7 @@ use core\check\result;
use core\output\notification; use core\output\notification;
use mod_bigbluebuttonbn\instance; use mod_bigbluebuttonbn\instance;
use mod_bigbluebuttonbn\local\config; use mod_bigbluebuttonbn\local\config;
use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
use mod_bigbluebuttonbn\meeting; use mod_bigbluebuttonbn\meeting;
use renderable; use renderable;
use renderer_base; use renderer_base;
@ -55,8 +56,10 @@ class view_page implements renderable, templatable {
* @return stdClass * @return stdClass
*/ */
public function export_for_template(renderer_base $output): stdClass { public function export_for_template(renderer_base $output): stdClass {
$pollinterval = bigbluebutton_proxy::get_poll_interval();
$templatedata = (object) [ $templatedata = (object) [
'instanceid' => $this->instance->get_instance_id(), 'instanceid' => $this->instance->get_instance_id(),
'pollinterval' => $pollinterval * 1000, // Javascript poll interval is in miliseconds.
'groupselector' => $output->render_groups_selector($this->instance), 'groupselector' => $output->render_groups_selector($this->instance),
'meetingname' => $this->instance->get_meeting_name(), 'meetingname' => $this->instance->get_meeting_name(),
'description' => $this->instance->get_meeting_description(true), 'description' => $this->instance->get_meeting_description(true),

View File

@ -30,6 +30,7 @@ use cache_helper;
use lang_string; use lang_string;
use mod_bigbluebuttonbn\local\config; use mod_bigbluebuttonbn\local\config;
use mod_bigbluebuttonbn\local\helpers\roles; use mod_bigbluebuttonbn\local\helpers\roles;
use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
/** /**
* The mod_bigbluebuttonbn settings helper * The mod_bigbluebuttonbn settings helper
@ -218,6 +219,18 @@ class settings {
$item, $item,
$settingsgeneral $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; return $settingsgeneral;
} }

View File

@ -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'] = 'Moderator';
$string['config_participant_moderator_default_description'] = 'This rule is used by default when a new room is added.'; $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'] = '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_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'; $string['config_userlimit_default'] = 'User limit enabled by default';

View File

@ -35,8 +35,10 @@
"title": "Upgrade now" "title": "Upgrade now"
} }
] ]
} },
"pollinterval": 5
} }
}} }}
{{{groupselector}}} {{{groupselector}}}
@ -62,8 +64,9 @@
{{#js}} {{#js}}
require(['mod_bigbluebuttonbn/rooms'], function(rooms) { require(['mod_bigbluebuttonbn/rooms'], function(rooms) {
// Register action on all buttons. // Register action on all buttons.
rooms.init({ rooms.init(
bigbluebuttonbnid: {{{instanceid}}}, {{instanceid}},
{{pollinterval}}
);
}); });
});
{{/js}} {{/js}}

View File

@ -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());
}
}