1. 1 : import { WrapperObject } from '../../mel_metapage/js/lib/BaseObjects/WrapperObject.js';
  2. 2 : import { FramesManager } from '../../mel_metapage/js/lib/classes/frame_manager.js';
  3. 3 : import { MelObject } from '../../mel_metapage/js/lib/mel_object.js';
  4. 4 : import { VisioFunctions } from './lib/helpers.js';
  5. 5 :
  6. 6 : /**
  7. 7 : * Contient les classes d'aide pour utiliser ou lancer la visioconférence correctement.
  8. 8 : * @module Visio/Helper
  9. 9 : * @local BnumVisio
  10. 10 : * @local VisioHelper
  11. 11 : */
  12. 12 :
  13. 13 : /**
  14. 14 : * @class
  15. 15 : * @classdesc Classe d'aide de la visioconférence. Donne des fonctions utile pour appeler ou utiliser la visio
  16. 16 : */
  17. 17 : class BnumVisio extends MelObject {
  18. 18 : /**
  19. 19 : * Contient les fonctions qui permettent de récupérer les codes voxify ou de lancer une visio.
  20. 20 : */
  21. 21 : constructor() {
  22. 22 : super();
  23. 23 : }
  24. 24 :
  25. 25 : /**
  26. 26 : *Cette fonction est appelé dans le constructeur.
  27. 27 : * @override
  28. 28 : */
  29. 29 : main() {
  30. 30 : super.main();
  31. 31 :
  32. 32 : this.rcmail().addEventListener('visio.start', (args) => {
  33. 33 : const { room: key, workspace: wsp, locks, pass, extra } = args;
  34. 34 :
  35. 35 : this.start({ key, wsp, locks, pass, extra });
  36. 36 : });
  37. 37 : }
  38. 38 :
  39. 39 : /**
  40. 40 : * Récupère l'url de voxify
  41. 41 : * @returns {Promise<string>}
  42. 42 : * @async
  43. 43 : */
  44. 44 : async voxify_url() {
  45. 45 : //Si on récupère déjà l'url, ça ne sert à rien de le redemander, on attend la résolution précédente.
  46. 46 : if (this.voxify_url.waiting) {
  47. 47 : let it = 0;
  48. 48 : await new Promise((ok, nok) => {
  49. 49 : const interval = setInterval(() => {
  50. 50 : console.debug('Waiting voxify url...');
  51. 51 : if (!this.voxify_url.waiting) {
  52. 52 : clearInterval(interval);
  53. 53 : console.debug('Voxify url ok !');
  54. 54 : ok();
  55. 55 : }
  56. 56 :
  57. 57 : if (++it > 50) {
  58. 58 : this.voxify_url.waiting = false;
  59. 59 : console.debug('Voxify url not ok !');
  60. 60 : nok();
  61. 61 : }
  62. 62 : }, 100);
  63. 63 : });
  64. 64 : }
  65. 65 :
  66. 66 : let navigator = top ?? parent ?? window;
  67. 67 :
  68. 68 : if (!navigator.voxify_url) {
  69. 69 : this.voxify_url.waiting = true;
  70. 70 : console.info('Starting get voxify url !');
  71. 71 : await MelObject.Empty().http_internal_get({
  72. 72 : task: 'mel_settings',
  73. 73 : action: 'get',
  74. 74 : params: {
  75. 75 : _option: 'voxify_url',
  76. 76 : _default_value: 'https://webconf.numerique.gouv.fr/voxapi',
  77. 77 : },
  78. 78 : on_success(data) {
  79. 79 : console.info('Voxify url ok !');
  80. 80 : data = JSON.parse(data);
  81. 81 : navigator.voxify_url = data;
  82. 82 : },
  83. 83 : });
  84. 84 : console.info('Finishing get voxify url !');
  85. 85 : this.voxify_url.waiting = false;
  86. 86 : }
  87. 87 :
  88. 88 : return navigator.voxify_url;
  89. 89 : }
  90. 90 :
  91. 91 : /**
  92. 92 : * Récupère le numéro de téléphone lié à la visioconférence
  93. 93 : * @param {string} webconf Room de la visio
  94. 94 : * @returns {Promise<string>}
  95. 95 : * @async
  96. 96 : */
  97. 97 : async getWebconfPhoneNumber(webconf) {
  98. 98 : const url = `${await this.voxify_url()}/api/v1/conn/jitsi/phoneNumbers?conference=${webconf}@conference.webconf.numerique.gouv.fr`;
  99. 99 : let phoneNumber = null;
  100. 100 : window.disable_x_roundcube = true;
  101. 101 :
  102. 102 : await this.http_call({
  103. 103 : url,
  104. 104 : on_success: (data) => {
  105. 105 : const indicator = rcmail.env['mel_metapage.webconf_voxify_indicatif'];
  106. 106 : if (
  107. 107 : !!data &&
  108. 108 : data.numbersEnabled &&
  109. 109 : !!data.numbers[indicator] &&
  110. 110 : data.numbers[indicator].length > 0
  111. 111 : )
  112. 112 : phoneNumber = data.numbers[indicator][0];
  113. 113 : },
  114. 114 : type: 'GET',
  115. 115 : });
  116. 116 :
  117. 117 : window.disable_x_roundcube = false;
  118. 118 :
  119. 119 : return phoneNumber;
  120. 120 : }
  121. 121 :
  122. 122 : /**
  123. 123 : * Récupère le code pin lié à la visio
  124. 124 : * @param {string} webconf Room de la visio
  125. 125 : * @returns {Promise<?string>}
  126. 126 : * @async
  127. 127 : */
  128. 128 : async getWebconfPhonePin(webconf) {
  129. 129 : const url = `${await this.voxify_url()}/api/v1/conn/jitsi/conference/code?conference=${webconf}@conference.webconf.numerique.gouv.fr`;
  130. 130 : let phoneNumber = null;
  131. 131 : window.disable_x_roundcube = true;
  132. 132 : // await mel_metapage.Functions.get(url, {}, (datas) => {
  133. 133 : // if (!!datas && !!datas.id) phoneNumber = datas.id;
  134. 134 : // });
  135. 135 : await this.http_call({
  136. 136 : url,
  137. 137 : on_success: (data) => {
  138. 138 : if (data?.id) phoneNumber = data.id;
  139. 139 : },
  140. 140 : type: 'GET',
  141. 141 : });
  142. 142 :
  143. 143 : window.disable_x_roundcube = false;
  144. 144 :
  145. 145 : return phoneNumber;
  146. 146 : }
  147. 147 :
  148. 148 : /**
  149. 149 : * Récupère les données téléphonique de la visio
  150. 150 : * @param {string} webconf
  151. 151 : * @returns {Promise<{number:string, pin:string, room:string}>}
  152. 152 : * @async
  153. 153 : */
  154. 154 : async getWebconfPhone(webconf) {
  155. 155 : const [number, pin] = await Promise.allSettled([
  156. 156 : this.getWebconfPhoneNumber(webconf),
  157. 157 : this.getWebconfPhonePin(webconf),
  158. 158 : ]);
  159. 159 : return { number: number.value, pin: pin.value, room: webconf };
  160. 160 : }
  161. 161 :
  162. 162 : /**
  163. 163 : * Lance une visio
  164. 164 : * @param {Object} [options={}]
  165. 165 : * @param {?string} [options.key=null] Room de la visio. Si null, ouvre la page de choix de la room.
  166. 166 : * @param {?string} [options.wsp=null] Espace de travail rattaché à la visio.
  167. 167 : * @param {?string} [options.locks = null] Elements à lock
  168. 168 : * @param {?string} [options.pass=null] Mot de passe de la visio
  169. 169 : * @param {?string} [options.extra=null] Modes en plus
  170. 170 : * @return {void}
  171. 171 : */
  172. 172 : start({
  173. 173 : key = null,
  174. 174 : wsp = null,
  175. 175 : locks = null,
  176. 176 : pass = null,
  177. 177 : extra = null,
  178. 178 : } = {}) {
  179. 179 : let config = {};
  180. 180 :
  181. 181 : if (key) {
  182. 182 : if (key === '¤random¤') key = VisioFunctions.generateWebconfRoomName();
  183. 183 : config._key = key;
  184. 184 : }
  185. 185 : if (wsp) config._wsp = wsp;
  186. 186 : if (locks) config._locks = locks;
  187. 187 : if (pass) config._pass = pass;
  188. 188 : if (extra) config._need_config = extra === 'need_config';
  189. 189 :
  190. 190 : // FramesManager.Instance.start_mode(
  191. 191 : // 'visio',
  192. 192 : // !key || config._need_config ? null : 'visio',
  193. 193 : // config,
  194. 194 : // );
  195. 195 : this.startVisioMode({
  196. 196 : page: !key || config._need_config ? null : 'visio',
  197. 197 : params: config,
  198. 198 : });
  199. 199 : }
  200. 200 :
  201. 201 : async startVisioMode({ page = 'index', params = {} } = {}) {
  202. 202 : if (!page) {
  203. 203 : if (params) params._page = 'index';
  204. 204 :
  205. 205 : await FramesManager.Instance.switch_frame('webconf', {
  206. 206 : args: params ?? { _page: 'index' },
  207. 207 : });
  208. 208 : } else if (page !== 'index') {
  209. 209 : params._page = page || 'init';
  210. 210 : FramesManager.Instance.close_except_selected()
  211. 211 : .disable_manual_multiframe()
  212. 212 : .start_custom_multi_frame()
  213. 213 : .get_window()
  214. 214 : .hide();
  215. 215 : window.current_visio = await FramesManager.Instance.open_another_window(
  216. 216 : 'webconf',
  217. 217 : params,
  218. 218 : );
  219. 219 : FramesManager.Instance.get_window()
  220. 220 : .set_cannot_be_select()
  221. 221 : //.set_remove_on_change()
  222. 222 : .add_tag('dispo-visio');
  223. 223 : FramesManager.Instance.select_window(0);
  224. 224 : }
  225. 225 : }
  226. 226 :
  227. 227 : stopVisio() {
  228. 228 : FramesManager.Instance.enable_manual_multiframe().stop_custom_multi_frame();
  229. 229 : return this;
  230. 230 : }
  231. 231 :
  232. 232 : reinitVisio() {
  233. 233 : FramesManager.Instance.close_except_selected().get_window().show();
  234. 234 : return this.stopVisio().startVisioMode();
  235. 235 : }
  236. 236 :
  237. 237 : /**
  238. 238 : * Initialise l'helper
  239. 239 : * @returns {BnumVisio} Chaînage
  240. 240 : */
  241. 241 : startInstance() {
  242. 242 : return this;
  243. 243 : }
  244. 244 : }
  245. 245 :
  246. 246 : /**
  247. 247 : * Donne des fonctions utile pour appeler ou utiliser la visio
  248. 248 : * @type {WrapperObject<BnumVisio>}
  249. 249 : * @constant
  250. 250 : * @frommodule Visio/Helper {@linkto BnumVisio}
  251. 251 : */
  252. 252 : export const VisioHelper = new WrapperObject(BnumVisio);
  253. 253 :
  254. 254 : VisioHelper.Instance.startInstance();