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.

defaultToolbarButtons.web.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /* @flow */
  2. import React from 'react';
  3. import { ParticipantCounter } from '../contact-list';
  4. import { openDeviceSelectionDialog } from '../device-selection';
  5. import { openDialOutDialog } from '../dial-out';
  6. import { openAddPeopleDialog, openInviteDialog } from '../invite';
  7. import UIEvents from '../../../service/UI/UIEvents';
  8. import { VideoQualityButton } from '../video-quality';
  9. import ProfileButton from './components/ProfileButton';
  10. declare var APP: Object;
  11. declare var interfaceConfig: Object;
  12. declare var JitsiMeetJS: Object;
  13. /**
  14. * All toolbar buttons' descriptors.
  15. */
  16. const buttons: Object = {
  17. addtocall: {
  18. classNames: [ 'button', 'icon-add' ],
  19. enabled: true,
  20. id: 'toolbar_button_add',
  21. isDisplayed: () => !APP.store.getState()['features/jwt'].isGuest,
  22. onClick(dispatch) {
  23. JitsiMeetJS.analytics.sendEvent('toolbar.add.clicked');
  24. dispatch(openAddPeopleDialog());
  25. },
  26. tooltipKey: 'toolbar.addPeople'
  27. },
  28. /**
  29. * The descriptor of the camera toolbar button.
  30. */
  31. camera: {
  32. classNames: [ 'button', 'icon-camera' ],
  33. enabled: true,
  34. isDisplayed: () => true,
  35. id: 'toolbar_button_camera',
  36. onClick() {
  37. const newVideoMutedState = !APP.conference.isLocalVideoMuted();
  38. if (newVideoMutedState) {
  39. JitsiMeetJS.analytics.sendEvent('toolbar.video.enabled');
  40. } else {
  41. JitsiMeetJS.analytics.sendEvent('toolbar.video.disabled');
  42. }
  43. APP.UI.emitEvent(UIEvents.VIDEO_MUTED, newVideoMutedState);
  44. },
  45. popups: [
  46. {
  47. dataAttr: 'audioOnly.featureToggleDisabled',
  48. dataInterpolate: { feature: 'video mute' },
  49. id: 'unmuteWhileAudioOnly'
  50. }
  51. ],
  52. shortcut: 'V',
  53. shortcutAttr: 'toggleVideoPopover',
  54. shortcutFunc() {
  55. if (APP.conference.isAudioOnly()) {
  56. APP.UI.emitEvent(UIEvents.VIDEO_UNMUTING_WHILE_AUDIO_ONLY);
  57. return;
  58. }
  59. JitsiMeetJS.analytics.sendEvent('shortcut.videomute.toggled');
  60. APP.conference.toggleVideoMuted();
  61. },
  62. shortcutDescription: 'keyboardShortcuts.videoMute',
  63. tooltipKey: 'toolbar.videomute'
  64. },
  65. /**
  66. * The descriptor of the chat toolbar button.
  67. */
  68. chat: {
  69. classNames: [ 'button', 'icon-chat' ],
  70. enabled: true,
  71. html: <span className = 'badge-round'>
  72. <span id = 'unreadMessages' />
  73. </span>,
  74. id: 'toolbar_button_chat',
  75. onClick() {
  76. JitsiMeetJS.analytics.sendEvent('toolbar.chat.toggled');
  77. APP.UI.emitEvent(UIEvents.TOGGLE_CHAT);
  78. },
  79. shortcut: 'C',
  80. shortcutAttr: 'toggleChatPopover',
  81. shortcutFunc() {
  82. JitsiMeetJS.analytics.sendEvent('shortcut.chat.toggled');
  83. APP.UI.toggleChat();
  84. },
  85. shortcutDescription: 'keyboardShortcuts.toggleChat',
  86. sideContainerId: 'chat_container',
  87. tooltipKey: 'toolbar.chat'
  88. },
  89. /**
  90. * The descriptor of the contact list toolbar button.
  91. */
  92. contacts: {
  93. childComponent: ParticipantCounter,
  94. classNames: [ 'button', 'icon-contactList' ],
  95. enabled: true,
  96. id: 'toolbar_contact_list',
  97. onClick() {
  98. JitsiMeetJS.analytics.sendEvent(
  99. 'toolbar.contacts.toggled');
  100. APP.UI.emitEvent(UIEvents.TOGGLE_CONTACT_LIST);
  101. },
  102. sideContainerId: 'contacts_container',
  103. tooltipKey: 'bottomtoolbar.contactlist'
  104. },
  105. /**
  106. * The descriptor of the desktop sharing toolbar button.
  107. */
  108. desktop: {
  109. classNames: [ 'button', 'icon-share-desktop' ],
  110. enabled: true,
  111. id: 'toolbar_button_desktopsharing',
  112. onClick() {
  113. if (APP.conference.isSharingScreen) {
  114. JitsiMeetJS.analytics.sendEvent('toolbar.screen.disabled');
  115. } else {
  116. JitsiMeetJS.analytics.sendEvent('toolbar.screen.enabled');
  117. }
  118. APP.UI.emitEvent(UIEvents.TOGGLE_SCREENSHARING);
  119. },
  120. popups: [
  121. {
  122. dataAttr: 'audioOnly.featureToggleDisabled',
  123. dataInterpolate: { feature: 'screen sharing' },
  124. id: 'screenshareWhileAudioOnly'
  125. }
  126. ],
  127. shortcut: 'D',
  128. shortcutAttr: 'toggleDesktopSharingPopover',
  129. shortcutFunc() {
  130. JitsiMeetJS.analytics.sendEvent('shortcut.screen.toggled');
  131. // eslint-disable-next-line no-empty-function
  132. APP.conference.toggleScreenSharing().catch(() => {});
  133. },
  134. shortcutDescription: 'keyboardShortcuts.toggleScreensharing',
  135. tooltipKey: 'toolbar.sharescreen'
  136. },
  137. /**
  138. * The descriptor of the dial out toolbar button.
  139. */
  140. dialout: {
  141. classNames: [ 'button', 'icon-telephone' ],
  142. enabled: true,
  143. // Will be displayed once the SIP calls functionality is detected.
  144. hidden: true,
  145. id: 'toolbar_button_dial_out',
  146. onClick(dispatch) {
  147. JitsiMeetJS.analytics.sendEvent('toolbar.sip.clicked');
  148. dispatch(openDialOutDialog());
  149. },
  150. tooltipKey: 'dialOut.dialOut'
  151. },
  152. /**
  153. * The descriptor of the device selection toolbar button.
  154. */
  155. fodeviceselection: {
  156. classNames: [ 'button', 'icon-settings' ],
  157. enabled: true,
  158. isDisplayed() {
  159. return interfaceConfig.filmStripOnly;
  160. },
  161. id: 'toolbar_button_fodeviceselection',
  162. onClick(dispatch) {
  163. JitsiMeetJS.analytics.sendEvent(
  164. 'toolbar.fodeviceselection.toggled');
  165. dispatch(openDeviceSelectionDialog());
  166. },
  167. sideContainerId: 'settings_container',
  168. tooltipKey: 'toolbar.Settings'
  169. },
  170. /**
  171. * The descriptor of the dialpad toolbar button.
  172. */
  173. dialpad: {
  174. classNames: [ 'button', 'icon-dialpad' ],
  175. enabled: true,
  176. // TODO: remove it after UI.updateDTMFSupport fix
  177. hidden: true,
  178. id: 'toolbar_button_dialpad',
  179. onClick() {
  180. JitsiMeetJS.analytics.sendEvent('toolbar.sip.dialpad.clicked');
  181. },
  182. tooltipKey: 'toolbar.dialpad'
  183. },
  184. /**
  185. * The descriptor of the etherpad toolbar button.
  186. */
  187. etherpad: {
  188. classNames: [ 'button', 'icon-share-doc' ],
  189. enabled: true,
  190. hidden: true,
  191. id: 'toolbar_button_etherpad',
  192. onClick() {
  193. JitsiMeetJS.analytics.sendEvent('toolbar.etherpad.clicked');
  194. APP.UI.emitEvent(UIEvents.ETHERPAD_CLICKED);
  195. },
  196. tooltipKey: 'toolbar.etherpad'
  197. },
  198. /**
  199. * The descriptor of the toolbar button which toggles full-screen mode.
  200. */
  201. fullscreen: {
  202. classNames: [ 'button', 'icon-full-screen' ],
  203. enabled: true,
  204. id: 'toolbar_button_fullScreen',
  205. onClick() {
  206. JitsiMeetJS.analytics.sendEvent('toolbar.fullscreen.enabled');
  207. APP.UI.emitEvent(UIEvents.TOGGLE_FULLSCREEN);
  208. },
  209. shortcut: 'S',
  210. shortcutAttr: 'toggleFullscreenPopover',
  211. shortcutDescription: 'keyboardShortcuts.fullScreen',
  212. shortcutFunc() {
  213. JitsiMeetJS.analytics.sendEvent('shortcut.fullscreen.toggled');
  214. APP.UI.toggleFullScreen();
  215. },
  216. tooltipKey: 'toolbar.fullscreen'
  217. },
  218. /**
  219. * The descriptor of the toolbar button which hangs up the call/conference.
  220. */
  221. hangup: {
  222. classNames: [ 'button', 'icon-hangup', 'button_hangup' ],
  223. enabled: true,
  224. isDisplayed: () => true,
  225. id: 'toolbar_button_hangup',
  226. onClick() {
  227. JitsiMeetJS.analytics.sendEvent('toolbar.hangup');
  228. APP.UI.emitEvent(UIEvents.HANGUP);
  229. },
  230. tooltipKey: 'toolbar.hangup'
  231. },
  232. /**
  233. * The descriptor of the toolbar button which shows the invite user dialog.
  234. */
  235. invite: {
  236. classNames: [ 'button', 'icon-link' ],
  237. enabled: true,
  238. id: 'toolbar_button_link',
  239. onClick(dispatch) {
  240. JitsiMeetJS.analytics.sendEvent('toolbar.invite.clicked');
  241. dispatch(openInviteDialog());
  242. },
  243. tooltipKey: 'toolbar.invite'
  244. },
  245. /**
  246. * The descriptor of the microphone toolbar button.
  247. */
  248. microphone: {
  249. classNames: [ 'button', 'icon-microphone' ],
  250. enabled: true,
  251. isDisplayed: () => true,
  252. id: 'toolbar_button_mute',
  253. onClick() {
  254. const sharedVideoManager = APP.UI.getSharedVideoManager();
  255. if (APP.conference.isLocalAudioMuted()) {
  256. // If there's a shared video with the volume "on" and we aren't
  257. // the video owner, we warn the user
  258. // that currently it's not possible to unmute.
  259. if (sharedVideoManager
  260. && sharedVideoManager.isSharedVideoVolumeOn()
  261. && !sharedVideoManager.isSharedVideoOwner()) {
  262. APP.UI.showCustomToolbarPopup(
  263. '#unableToUnmutePopup', true, 5000);
  264. } else {
  265. JitsiMeetJS.analytics.sendEvent('toolbar.audio.unmuted');
  266. APP.UI.emitEvent(UIEvents.AUDIO_MUTED, false, true);
  267. }
  268. } else {
  269. JitsiMeetJS.analytics.sendEvent('toolbar.audio.muted');
  270. APP.UI.emitEvent(UIEvents.AUDIO_MUTED, true, true);
  271. }
  272. },
  273. popups: [
  274. {
  275. dataAttr: 'toolbar.micMutedPopup',
  276. id: 'micMutedPopup'
  277. },
  278. {
  279. dataAttr: 'toolbar.unableToUnmutePopup',
  280. id: 'unableToUnmutePopup'
  281. },
  282. {
  283. dataAttr: 'toolbar.talkWhileMutedPopup',
  284. id: 'talkWhileMutedPopup'
  285. }
  286. ],
  287. shortcut: 'M',
  288. shortcutAttr: 'mutePopover',
  289. shortcutFunc() {
  290. JitsiMeetJS.analytics.sendEvent('shortcut.audiomute.toggled');
  291. APP.conference.toggleAudioMuted();
  292. },
  293. shortcutDescription: 'keyboardShortcuts.mute',
  294. tooltipKey: 'toolbar.mute'
  295. },
  296. /**
  297. * The descriptor of the profile toolbar button.
  298. */
  299. profile: {
  300. component: ProfileButton,
  301. sideContainerId: 'profile_container'
  302. },
  303. /**
  304. * The descriptor of the "Raise hand" toolbar button.
  305. */
  306. raisehand: {
  307. classNames: [ 'button', 'icon-raised-hand' ],
  308. enabled: true,
  309. id: 'toolbar_button_raisehand',
  310. onClick() {
  311. JitsiMeetJS.analytics.sendEvent('toolbar.raiseHand.clicked');
  312. APP.conference.maybeToggleRaisedHand();
  313. },
  314. shortcut: 'R',
  315. shortcutAttr: 'raiseHandPopover',
  316. shortcutDescription: 'keyboardShortcuts.raiseHand',
  317. shortcutFunc() {
  318. JitsiMeetJS.analytics.sendEvent('shortcut.raisehand.clicked');
  319. APP.conference.maybeToggleRaisedHand();
  320. },
  321. tooltipKey: 'toolbar.raiseHand'
  322. },
  323. /**
  324. * The descriptor of the recording toolbar button. Requires additional
  325. * initialization in the recording module.
  326. */
  327. recording: {
  328. classNames: [ 'button' ],
  329. enabled: true,
  330. // will be displayed once the recording functionality is detected
  331. hidden: true,
  332. id: 'toolbar_button_record',
  333. tooltipKey: 'liveStreaming.buttonTooltip'
  334. },
  335. /**
  336. * The descriptor of the settings toolbar button.
  337. */
  338. settings: {
  339. classNames: [ 'button', 'icon-settings' ],
  340. enabled: true,
  341. id: 'toolbar_button_settings',
  342. onClick() {
  343. JitsiMeetJS.analytics.sendEvent('toolbar.settings.toggled');
  344. APP.UI.emitEvent(UIEvents.TOGGLE_SETTINGS);
  345. },
  346. sideContainerId: 'settings_container',
  347. tooltipKey: 'toolbar.Settings'
  348. },
  349. /**
  350. * The descriptor of the "Share YouTube video" toolbar button.
  351. */
  352. sharedvideo: {
  353. classNames: [ 'button', 'icon-shared-video' ],
  354. enabled: true,
  355. id: 'toolbar_button_sharedvideo',
  356. onClick() {
  357. JitsiMeetJS.analytics.sendEvent('toolbar.sharedvideo.clicked');
  358. APP.UI.emitEvent(UIEvents.SHARED_VIDEO_CLICKED);
  359. },
  360. popups: [
  361. {
  362. dataAttr: 'toolbar.sharedVideoMutedPopup',
  363. id: 'sharedVideoMutedPopup'
  364. }
  365. ],
  366. tooltipKey: 'toolbar.sharedvideo'
  367. },
  368. videoquality: {
  369. component: VideoQualityButton
  370. }
  371. };
  372. Object.keys(buttons).forEach(name => {
  373. const button = buttons[name];
  374. if (!button.isDisplayed) {
  375. button.isDisplayed = () => !interfaceConfig.filmStripOnly;
  376. }
  377. });
  378. export default buttons;