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.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. // AVATAR URL CHANGED
  71. function updateAvatarUrl () {
  72. emitter.emit(UIEvents.AVATAR_URL_CHANGED, $('#setAvatarUrl').val());
  73. }
  74. $('#setEmail')
  75. .val(Settings.getEmail())
  76. .keyup(function (event) {
  77. if (event.keyCode === 13) { // enter
  78. updateEmail();
  79. }
  80. }).focusout(updateEmail);
  81. $('#setAvatarUrl')
  82. .val(Settings.getAvatarUrl())
  83. .keyup(function (event) {
  84. if (event.keyCode === 13) { // enter
  85. updateAvatarUrl();
  86. }
  87. }).focusout(updateAvatarUrl);
  88. // START MUTED
  89. $("#startMutedOptions").change(function () {
  90. let startAudioMuted = $("#startAudioMuted").is(":checked");
  91. let startVideoMuted = $("#startVideoMuted").is(":checked");
  92. emitter.emit(
  93. UIEvents.START_MUTED_CHANGED,
  94. startAudioMuted,
  95. startVideoMuted
  96. );
  97. });
  98. // FOLLOW ME
  99. $("#followMeOptions").change(function () {
  100. let isFollowMeEnabled = $("#followMeCheckBox").is(":checked");
  101. emitter.emit(
  102. UIEvents.FOLLOW_ME_ENABLED,
  103. isFollowMeEnabled
  104. );
  105. });
  106. // LANGUAGES BOX
  107. let languagesBox = $("#languages_selectbox");
  108. languagesBox.html(generateLanguagesOptions(
  109. languages.getLanguages(),
  110. APP.translation.getCurrentLanguage()
  111. ));
  112. APP.translation.translateElement(languagesBox);
  113. languagesBox.change(function () {
  114. emitter.emit(UIEvents.LANG_CHANGED, languagesBox.val());
  115. });
  116. // DEVICES LIST
  117. JitsiMeetJS.mediaDevices.isDeviceListAvailable()
  118. .then((isDeviceListAvailable) => {
  119. if (isDeviceListAvailable &&
  120. JitsiMeetJS.mediaDevices.isDeviceChangeAvailable()) {
  121. this._initializeDeviceSelectionSettings(emitter);
  122. }
  123. });
  124. },
  125. _initializeDeviceSelectionSettings(emitter) {
  126. this.changeDevicesList([]);
  127. $('#selectCamera').change(function () {
  128. let cameraDeviceId = $(this).val();
  129. if (cameraDeviceId !== Settings.getCameraDeviceId()) {
  130. emitter.emit(UIEvents.VIDEO_DEVICE_CHANGED, cameraDeviceId);
  131. }
  132. });
  133. $('#selectMic').change(function () {
  134. let micDeviceId = $(this).val();
  135. if (micDeviceId !== Settings.getMicDeviceId()) {
  136. emitter.emit(UIEvents.AUDIO_DEVICE_CHANGED, micDeviceId);
  137. }
  138. });
  139. $('#selectAudioOutput').change(function () {
  140. let audioOutputDeviceId = $(this).val();
  141. if (audioOutputDeviceId !== Settings.getAudioOutputDeviceId()) {
  142. emitter.emit(
  143. UIEvents.AUDIO_OUTPUT_DEVICE_CHANGED, audioOutputDeviceId);
  144. }
  145. });
  146. },
  147. /**
  148. * If start audio muted/start video muted options should be visible or not.
  149. * @param {boolean} show
  150. */
  151. showStartMutedOptions (show) {
  152. if (show) {
  153. $("#startMutedOptions").css("display", "block");
  154. } else {
  155. $("#startMutedOptions").css("display", "none");
  156. }
  157. },
  158. updateStartMutedBox (startAudioMuted, startVideoMuted) {
  159. $("#startAudioMuted").attr("checked", startAudioMuted);
  160. $("#startVideoMuted").attr("checked", startVideoMuted);
  161. },
  162. /**
  163. * Shows/hides the follow me options in the settings dialog.
  164. *
  165. * @param {boolean} show {true} to show those options, {false} to hide them
  166. */
  167. showFollowMeOptions (show) {
  168. if (show) {
  169. $("#followMeOptions").css("display", "block");
  170. } else {
  171. $("#followMeOptions").css("display", "none");
  172. }
  173. },
  174. /**
  175. * Check if settings menu is visible or not.
  176. * @returns {boolean}
  177. */
  178. isVisible () {
  179. return UIUtil.isVisible(document.getElementById("settingsmenu"));
  180. },
  181. /**
  182. * Change user display name in the settings menu.
  183. * @param {string} newDisplayName
  184. */
  185. changeDisplayName (newDisplayName) {
  186. $('#setDisplayName').val(newDisplayName);
  187. },
  188. /**
  189. * Change user avatar in the settings menu.
  190. * @param {string} avatarUrl url of the new avatar
  191. */
  192. changeAvatar (avatarUrl) {
  193. $('#avatar').attr('src', avatarUrl);
  194. },
  195. /**
  196. * Sets microphone's <select> element to select microphone ID from settings.
  197. */
  198. setSelectedMicFromSettings () {
  199. $('#selectMic').val(Settings.getMicDeviceId());
  200. },
  201. /**
  202. * Sets camera's <select> element to select camera ID from settings.
  203. */
  204. setSelectedCameraFromSettings () {
  205. $('#selectCamera').val(Settings.getCameraDeviceId());
  206. },
  207. /**
  208. * Sets audio outputs's <select> element to select audio output ID from
  209. * settings.
  210. */
  211. setSelectedAudioOutputFromSettings () {
  212. $('#selectAudioOutput').val(Settings.getAudioOutputDeviceId());
  213. },
  214. /**
  215. * Change available cameras/microphones or hide selects completely if
  216. * no devices available.
  217. * @param {{ deviceId, label, kind }[]} devices list of available devices
  218. */
  219. changeDevicesList (devices) {
  220. let $selectCamera= $('#selectCamera'),
  221. $selectMic = $('#selectMic'),
  222. $selectAudioOutput = $('#selectAudioOutput'),
  223. $selectAudioOutputParent = $selectAudioOutput.parent();
  224. let audio = devices.filter(device => device.kind === 'audioinput'),
  225. video = devices.filter(device => device.kind === 'videoinput'),
  226. audioOutput = devices
  227. .filter(device => device.kind === 'audiooutput'),
  228. selectedAudioDevice = audio.find(
  229. d => d.deviceId === Settings.getMicDeviceId()) || audio[0],
  230. selectedVideoDevice = video.find(
  231. d => d.deviceId === Settings.getCameraDeviceId()) || video[0],
  232. selectedAudioOutputDevice = audioOutput.find(
  233. d => d.deviceId === Settings.getAudioOutputDeviceId()),
  234. videoPermissionGranted =
  235. JitsiMeetJS.mediaDevices.isDevicePermissionGranted('video'),
  236. audioPermissionGranted =
  237. JitsiMeetJS.mediaDevices.isDevicePermissionGranted('audio');
  238. $selectCamera
  239. .html(generateDevicesOptions(
  240. video,
  241. selectedVideoDevice ? selectedVideoDevice.deviceId : '',
  242. videoPermissionGranted))
  243. .prop('disabled', !video.length || !videoPermissionGranted);
  244. $selectMic
  245. .html(generateDevicesOptions(
  246. audio,
  247. selectedAudioDevice ? selectedAudioDevice.deviceId : '',
  248. audioPermissionGranted))
  249. .prop('disabled', !audio.length || !audioPermissionGranted);
  250. if (JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output')) {
  251. $selectAudioOutput
  252. .html(generateDevicesOptions(
  253. audioOutput,
  254. selectedAudioOutputDevice
  255. ? selectedAudioOutputDevice.deviceId
  256. : 'default',
  257. videoPermissionGranted || audioPermissionGranted))
  258. .prop('disabled', !audioOutput.length ||
  259. (!videoPermissionGranted && !audioPermissionGranted));
  260. $selectAudioOutputParent.show();
  261. } else {
  262. $selectAudioOutputParent.hide();
  263. }
  264. $('#devicesOptions').show();
  265. APP.translation.translateElement($('#settingsmenu option'));
  266. }
  267. };