You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SettingsMenu.js 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /* global APP, $, JitsiMeetJS */
  2. import UIUtil from "../../util/UIUtil";
  3. import UIEvents from "../../../../service/UI/UIEvents";
  4. import languages from "../../../../service/translation/languages";
  5. import Settings from '../../../settings/Settings';
  6. /**
  7. * Generate html select options for available languages.
  8. * @param {string[]} items available languages
  9. * @param {string} [currentLang] current language
  10. * @returns {string}
  11. */
  12. function generateLanguagesOptions(items, currentLang) {
  13. return items.map(function (lang) {
  14. let attrs = {
  15. value: lang,
  16. 'data-i18n': `languages:${lang}`
  17. };
  18. if (lang === currentLang) {
  19. attrs.selected = 'selected';
  20. }
  21. let attrsStr = UIUtil.attrsToString(attrs);
  22. return `<option ${attrsStr}></option>`;
  23. }).join('\n');
  24. }
  25. /**
  26. * Generate html select options for available physical devices.
  27. * @param {{ deviceId, label }[]} items available devices
  28. * @param {string} [selectedId] id of selected device
  29. * @param {boolean} permissionGranted if permission to use selected device type
  30. * is granted
  31. * @returns {string}
  32. */
  33. function generateDevicesOptions(items, selectedId, permissionGranted) {
  34. if (!permissionGranted && items.length) {
  35. return '<option data-i18n="settings.noPermission"></option>';
  36. }
  37. var options = items.map(function (item) {
  38. let attrs = {
  39. value: item.deviceId
  40. };
  41. if (item.deviceId === selectedId) {
  42. attrs.selected = 'selected';
  43. }
  44. let attrsStr = UIUtil.attrsToString(attrs);
  45. return `<option ${attrsStr}>${item.label}</option>`;
  46. });
  47. if (!items.length) {
  48. options.unshift('<option data-i18n="settings.noDevice"></option>');
  49. }
  50. return options.join('');
  51. }
  52. export default {
  53. init (emitter) {
  54. // DISPLAY NAME
  55. function updateDisplayName () {
  56. emitter.emit(UIEvents.NICKNAME_CHANGED, $('#setDisplayName').val());
  57. }
  58. $('#setDisplayName')
  59. .val(Settings.getDisplayName())
  60. .keyup(function (event) {
  61. if (event.keyCode === 13) { // enter
  62. updateDisplayName();
  63. }
  64. })
  65. .focusout(updateDisplayName);
  66. // EMAIL
  67. function updateEmail () {
  68. emitter.emit(UIEvents.EMAIL_CHANGED, $('#setEmail').val());
  69. }
  70. $('#setEmail')
  71. .val(Settings.getEmail())
  72. .keyup(function (event) {
  73. if (event.keyCode === 13) { // enter
  74. updateEmail();
  75. }
  76. }).focusout(updateEmail);
  77. // START MUTED
  78. $("#startMutedOptions").change(function () {
  79. let startAudioMuted = $("#startAudioMuted").is(":checked");
  80. let startVideoMuted = $("#startVideoMuted").is(":checked");
  81. emitter.emit(
  82. UIEvents.START_MUTED_CHANGED,
  83. startAudioMuted,
  84. startVideoMuted
  85. );
  86. });
  87. // FOLLOW ME
  88. $("#followMeOptions").change(function () {
  89. let isFollowMeEnabled = $("#followMeCheckBox").is(":checked");
  90. emitter.emit(
  91. UIEvents.FOLLOW_ME_ENABLED,
  92. isFollowMeEnabled
  93. );
  94. });
  95. // LANGUAGES BOX
  96. let languagesBox = $("#languages_selectbox");
  97. languagesBox.html(generateLanguagesOptions(
  98. languages.getLanguages(),
  99. APP.translation.getCurrentLanguage()
  100. ));
  101. APP.translation.translateElement(languagesBox);
  102. languagesBox.change(function () {
  103. emitter.emit(UIEvents.LANG_CHANGED, languagesBox.val());
  104. });
  105. // DEVICES LIST
  106. JitsiMeetJS.mediaDevices.isDeviceListAvailable()
  107. .then((isDeviceListAvailable) => {
  108. if (isDeviceListAvailable &&
  109. JitsiMeetJS.mediaDevices.isDeviceChangeAvailable()) {
  110. this._initializeDeviceSelectionSettings(emitter);
  111. }
  112. });
  113. },
  114. _initializeDeviceSelectionSettings(emitter) {
  115. this.changeDevicesList([]);
  116. $('#selectCamera').change(function () {
  117. let cameraDeviceId = $(this).val();
  118. if (cameraDeviceId !== Settings.getCameraDeviceId()) {
  119. emitter.emit(UIEvents.VIDEO_DEVICE_CHANGED, cameraDeviceId);
  120. }
  121. });
  122. $('#selectMic').change(function () {
  123. let micDeviceId = $(this).val();
  124. if (micDeviceId !== Settings.getMicDeviceId()) {
  125. emitter.emit(UIEvents.AUDIO_DEVICE_CHANGED, micDeviceId);
  126. }
  127. });
  128. $('#selectAudioOutput').change(function () {
  129. let audioOutputDeviceId = $(this).val();
  130. if (audioOutputDeviceId !== Settings.getAudioOutputDeviceId()) {
  131. emitter.emit(
  132. UIEvents.AUDIO_OUTPUT_DEVICE_CHANGED, audioOutputDeviceId);
  133. }
  134. });
  135. },
  136. /**
  137. * If start audio muted/start video muted options should be visible or not.
  138. * @param {boolean} show
  139. */
  140. showStartMutedOptions (show) {
  141. if (show) {
  142. $("#startMutedOptions").css("display", "block");
  143. } else {
  144. $("#startMutedOptions").css("display", "none");
  145. }
  146. },
  147. updateStartMutedBox (startAudioMuted, startVideoMuted) {
  148. $("#startAudioMuted").attr("checked", startAudioMuted);
  149. $("#startVideoMuted").attr("checked", startVideoMuted);
  150. },
  151. /**
  152. * Shows/hides the follow me options in the settings dialog.
  153. *
  154. * @param {boolean} show {true} to show those options, {false} to hide them
  155. */
  156. showFollowMeOptions (show) {
  157. if (show) {
  158. $("#followMeOptions").css("display", "block");
  159. } else {
  160. $("#followMeOptions").css("display", "none");
  161. }
  162. },
  163. /**
  164. * Check if settings menu is visible or not.
  165. * @returns {boolean}
  166. */
  167. isVisible () {
  168. return UIUtil.isVisible(document.getElementById("settingsmenu"));
  169. },
  170. /**
  171. * Change user display name in the settings menu.
  172. * @param {string} newDisplayName
  173. */
  174. changeDisplayName (newDisplayName) {
  175. $('#setDisplayName').val(newDisplayName);
  176. },
  177. /**
  178. * Change user avatar in the settings menu.
  179. * @param {string} avatarUrl url of the new avatar
  180. */
  181. changeAvatar (avatarUrl) {
  182. $('#avatar').attr('src', avatarUrl);
  183. },
  184. /**
  185. * Sets microphone's <select> element to select microphone ID from settings.
  186. */
  187. setSelectedMicFromSettings () {
  188. $('#selectMic').val(Settings.getMicDeviceId());
  189. },
  190. /**
  191. * Sets camera's <select> element to select camera ID from settings.
  192. */
  193. setSelectedCameraFromSettings () {
  194. $('#selectCamera').val(Settings.getCameraDeviceId());
  195. },
  196. /**
  197. * Sets audio outputs's <select> element to select audio output ID from
  198. * settings.
  199. */
  200. setSelectedAudioOutputFromSettings () {
  201. $('#selectAudioOutput').val(Settings.getAudioOutputDeviceId());
  202. },
  203. /**
  204. * Change available cameras/microphones or hide selects completely if
  205. * no devices available.
  206. * @param {{ deviceId, label, kind }[]} devices list of available devices
  207. */
  208. changeDevicesList (devices) {
  209. let $selectCamera= $('#selectCamera'),
  210. $selectMic = $('#selectMic'),
  211. $selectAudioOutput = $('#selectAudioOutput'),
  212. $selectAudioOutputParent = $selectAudioOutput.parent();
  213. let audio = devices.filter(device => device.kind === 'audioinput'),
  214. video = devices.filter(device => device.kind === 'videoinput'),
  215. audioOutput = devices
  216. .filter(device => device.kind === 'audiooutput'),
  217. selectedAudioDevice = audio.find(
  218. d => d.deviceId === Settings.getMicDeviceId()) || audio[0],
  219. selectedVideoDevice = video.find(
  220. d => d.deviceId === Settings.getCameraDeviceId()) || video[0],
  221. selectedAudioOutputDevice = audioOutput.find(
  222. d => d.deviceId === Settings.getAudioOutputDeviceId()),
  223. videoPermissionGranted =
  224. JitsiMeetJS.mediaDevices.isDevicePermissionGranted('video'),
  225. audioPermissionGranted =
  226. JitsiMeetJS.mediaDevices.isDevicePermissionGranted('audio');
  227. $selectCamera
  228. .html(generateDevicesOptions(
  229. video,
  230. selectedVideoDevice ? selectedVideoDevice.deviceId : '',
  231. videoPermissionGranted))
  232. .prop('disabled', !video.length || !videoPermissionGranted);
  233. $selectMic
  234. .html(generateDevicesOptions(
  235. audio,
  236. selectedAudioDevice ? selectedAudioDevice.deviceId : '',
  237. audioPermissionGranted))
  238. .prop('disabled', !audio.length || !audioPermissionGranted);
  239. if (JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output')) {
  240. $selectAudioOutput
  241. .html(generateDevicesOptions(
  242. audioOutput,
  243. selectedAudioOutputDevice
  244. ? selectedAudioOutputDevice.deviceId
  245. : 'default',
  246. videoPermissionGranted || audioPermissionGranted))
  247. .prop('disabled', !audioOutput.length ||
  248. (!videoPermissionGranted && !audioPermissionGranted));
  249. $selectAudioOutputParent.show();
  250. } else {
  251. $selectAudioOutputParent.hide();
  252. }
  253. $('#devicesOptions').show();
  254. APP.translation.translateElement($('#settingsmenu option'));
  255. }
  256. };