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.

API.js 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /* global APP, getConfigParamsFromUrl */
  2. import postisInit from 'postis';
  3. import * as JitsiMeetConferenceEvents from '../../ConferenceEvents';
  4. /**
  5. * List of the available commands.
  6. * @type {{
  7. * displayName: inputDisplayNameHandler,
  8. * toggleAudio: toggleAudio,
  9. * toggleVideo: toggleVideo,
  10. * toggleFilmStrip: toggleFilmStrip,
  11. * toggleChat: toggleChat,
  12. * toggleContactList: toggleContactList
  13. * }}
  14. */
  15. let commands = {};
  16. const hashParams = getConfigParamsFromUrl();
  17. /**
  18. * JitsiMeetExternalAPI id - unique for a webpage.
  19. */
  20. const jitsiMeetExternalApiId = hashParams.jitsi_meet_external_api_id;
  21. /**
  22. * Object that will execute sendMessage
  23. */
  24. const target = window.opener ? window.opener : window.parent;
  25. /**
  26. * Postis instance. Used to communicate with the external application.
  27. */
  28. let postis;
  29. /**
  30. * Current status (enabled/disabled) of API.
  31. */
  32. let enabled = false;
  33. /**
  34. * The state of screen sharing(started/stopped) before the screen sharing is
  35. * enabled and initialized.
  36. * NOTE: This flag help us to cache the state and use it if toggle-share-screen
  37. * was received before the initialization.
  38. */
  39. let initialScreenSharingState = false;
  40. /**
  41. * Executes on toggle-share-screen command.
  42. */
  43. function toggleScreenSharing() {
  44. if(!APP.conference.isDesktopSharingEnabled) {
  45. initialScreenSharingState = !initialScreenSharingState;
  46. } else {
  47. APP.conference.toggleScreenSharing();
  48. }
  49. }
  50. /**
  51. * Initializes supported commands.
  52. *
  53. * @returns {void}
  54. */
  55. function initCommands() {
  56. commands = {
  57. 'display-name':
  58. APP.conference.changeLocalDisplayName.bind(APP.conference),
  59. 'toggle-audio': APP.conference.toggleAudioMuted.bind(APP.conference),
  60. 'toggle-video': APP.conference.toggleVideoMuted.bind(APP.conference),
  61. 'toggle-film-strip': APP.UI.toggleFilmstrip,
  62. 'toggle-chat': APP.UI.toggleChat,
  63. 'toggle-contact-list': APP.UI.toggleContactList,
  64. 'toggle-share-screen': toggleScreenSharing,
  65. 'video-hangup': () => APP.conference.hangup(),
  66. 'email': APP.conference.changeLocalEmail,
  67. 'avatar-url': APP.conference.changeLocalAvatarUrl,
  68. 'remote-control-event':
  69. event => APP.remoteControl.onRemoteControlAPIEvent(event)
  70. };
  71. Object.keys(commands).forEach(
  72. key => postis.listen(key, args => commands[key](...args)));
  73. }
  74. /**
  75. * Sends message to the external application.
  76. *
  77. * @param {Object} message - The message to be sent.
  78. * @returns {void}
  79. */
  80. function sendMessage(message) {
  81. if (enabled) {
  82. postis.send(message);
  83. }
  84. }
  85. /**
  86. * Check whether the API should be enabled or not.
  87. *
  88. * @returns {boolean}
  89. */
  90. function shouldBeEnabled() {
  91. return typeof jitsiMeetExternalApiId === 'number';
  92. }
  93. /**
  94. * Sends event object to the external application that has been subscribed
  95. * for that event.
  96. *
  97. * @param {string} name - The name event.
  98. * @param {Object} object - Data associated with the event.
  99. * @returns {void}
  100. */
  101. function triggerEvent(name, object) {
  102. if (enabled) {
  103. sendMessage({ method: name,
  104. params: object });
  105. }
  106. }
  107. /**
  108. * Listens for screen sharing enabled events and toggles the screen sharing if
  109. * needed.
  110. *
  111. * @param {boolean} enabled - Current screen sharing enabled status.
  112. * @returns {void}
  113. */
  114. function onScreenSharingEnable(enabled = false) {
  115. if(enabled && initialScreenSharingState) {
  116. toggleScreenSharing();
  117. }
  118. }
  119. /**
  120. * Implements API class that communicates with external api class
  121. * and provides interface to access Jitsi Meet features by external
  122. * applications that embed Jitsi Meet
  123. */
  124. class API {
  125. /**
  126. * Initializes the APIConnector. Setups message event listeners that will
  127. * receive information from external applications that embed Jitsi Meet.
  128. * It also sends a message to the external application that APIConnector
  129. * is initialized.
  130. *
  131. * @param {Object} options - Optional parameters.
  132. * @param {boolean} options.forceEnable - If true the module will be
  133. * enabled.
  134. * @returns {void}
  135. */
  136. init(options = {}) {
  137. if (!shouldBeEnabled() && !options.forceEnable) {
  138. return;
  139. }
  140. if(!enabled) {
  141. APP.conference.addListener(
  142. JitsiMeetConferenceEvents.DESKTOP_SHARING_ENABLED_CHANGED,
  143. onScreenSharingEnable);
  144. enabled = true;
  145. }
  146. if (!postis) {
  147. this._initPostis();
  148. }
  149. }
  150. /**
  151. * Initializes postis library.
  152. *
  153. * @returns {void}
  154. *
  155. * @private
  156. */
  157. _initPostis() {
  158. const postisOptions = {
  159. window: target
  160. };
  161. if (typeof jitsiMeetExternalApiId === 'number') {
  162. postisOptions.scope
  163. = `jitsi_meet_external_api_${jitsiMeetExternalApiId}`;
  164. }
  165. postis = postisInit(postisOptions);
  166. initCommands();
  167. }
  168. /**
  169. * Notify external application (if API is enabled) that message was sent.
  170. *
  171. * @param {string} body - Message body.
  172. * @returns {void}
  173. */
  174. notifySendingChatMessage(body) {
  175. triggerEvent('outgoing-message', { 'message': body });
  176. }
  177. /**
  178. * Notify external application (if API is enabled) that
  179. * message was received.
  180. *
  181. * @param {Object} options - Object with the message properties.
  182. * @returns {void}
  183. */
  184. notifyReceivedChatMessage(options = {}) {
  185. const { id, nick, body, ts } = options;
  186. if (APP.conference.isLocalId(id)) {
  187. return;
  188. }
  189. triggerEvent(
  190. 'incoming-message',
  191. { 'from': id,
  192. 'nick': nick,
  193. 'message': body,
  194. 'stamp': ts }
  195. );
  196. }
  197. /**
  198. * Notify external application (if API is enabled) that
  199. * user joined the conference.
  200. *
  201. * @param {string} id - User id.
  202. * @returns {void}
  203. */
  204. notifyUserJoined(id) {
  205. triggerEvent('participant-joined', { id });
  206. }
  207. /**
  208. * Notify external application (if API is enabled) that
  209. * user left the conference.
  210. *
  211. * @param {string} id - User id.
  212. * @returns {void}
  213. */
  214. notifyUserLeft(id) {
  215. triggerEvent('participant-left', { id });
  216. }
  217. /**
  218. * Notify external application (if API is enabled) that
  219. * user changed their nickname.
  220. *
  221. * @param {string} id - User id.
  222. * @param {string} displayName - User nickname.
  223. * @returns {void}
  224. */
  225. notifyDisplayNameChanged(id, displayName) {
  226. triggerEvent('display-name-change', { id,
  227. displayname: displayName });
  228. }
  229. /**
  230. * Notify external application (if API is enabled) that
  231. * the conference has been joined.
  232. *
  233. * @param {string} room - The room name.
  234. * @returns {void}
  235. */
  236. notifyConferenceJoined(room) {
  237. triggerEvent('video-conference-joined', { roomName: room });
  238. }
  239. /**
  240. * Notify external application (if API is enabled) that
  241. * user changed their nickname.
  242. *
  243. * @param {string} room - User id.
  244. * @param {string} displayName - User nickname.
  245. * @returns {void}
  246. */
  247. notifyConferenceLeft(room) {
  248. triggerEvent('video-conference-left', { roomName: room });
  249. }
  250. /**
  251. * Notify external application (if API is enabled) that
  252. * we are ready to be closed.
  253. *
  254. * @returns {void}
  255. */
  256. notifyReadyToClose() {
  257. triggerEvent('video-ready-to-close', {});
  258. }
  259. /**
  260. * Sends remote control event.
  261. *
  262. * @param {RemoteControlEvent} event - The remote control event.
  263. * @returns {void}
  264. */
  265. sendRemoteControlEvent(event) {
  266. sendMessage({ method: 'remote-control-event',
  267. params: event });
  268. }
  269. /**
  270. * Removes the listeners.
  271. *
  272. * @returns {void}
  273. */
  274. dispose() {
  275. if (enabled) {
  276. postis.destroy();
  277. APP.conference.removeListener(
  278. JitsiMeetConferenceEvents.DESKTOP_SHARING_ENABLED_CHANGED,
  279. onScreenSharingEnable);
  280. }
  281. }
  282. }
  283. export default new API();