Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

actions.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /* global interfaceConfig */
  2. import throttle from 'lodash/throttle';
  3. import { showNotification } from '../../notifications';
  4. import {
  5. DOMINANT_SPEAKER_CHANGED,
  6. KICK_PARTICIPANT,
  7. MUTE_REMOTE_PARTICIPANT,
  8. PARTICIPANT_DISPLAY_NAME_CHANGED,
  9. PARTICIPANT_ID_CHANGED,
  10. PARTICIPANT_JOINED,
  11. PARTICIPANT_LEFT,
  12. PARTICIPANT_UPDATED,
  13. PIN_PARTICIPANT
  14. } from './actionTypes';
  15. import { MAX_DISPLAY_NAME_LENGTH } from './constants';
  16. import { getLocalParticipant } from './functions';
  17. /**
  18. * Create an action for when dominant speaker changes.
  19. *
  20. * @param {string} id - Participant's ID.
  21. * @returns {{
  22. * type: DOMINANT_SPEAKER_CHANGED,
  23. * participant: {
  24. * id: string
  25. * }
  26. * }}
  27. */
  28. export function dominantSpeakerChanged(id) {
  29. return {
  30. type: DOMINANT_SPEAKER_CHANGED,
  31. participant: {
  32. id
  33. }
  34. };
  35. }
  36. /**
  37. * Create an action for removing a participant from the conference.
  38. *
  39. * @param {string} id - Participant's ID.
  40. * @returns {{
  41. * type: KICK_PARTICIPANT,
  42. * id: string
  43. * }}
  44. */
  45. export function kickParticipant(id) {
  46. return {
  47. type: KICK_PARTICIPANT,
  48. id
  49. };
  50. }
  51. /**
  52. * Creates an action to signal the connection status of the local participant
  53. * has changed.
  54. *
  55. * @param {string} connectionStatus - The current connection status of the local
  56. * participant, as enumerated by the library's participantConnectionStatus
  57. * constants.
  58. * @returns {Function}
  59. */
  60. export function localParticipantConnectionStatusChanged(connectionStatus) {
  61. return (dispatch, getState) => {
  62. const participant = getLocalParticipant(getState);
  63. if (participant) {
  64. return dispatch(participantConnectionStatusChanged(
  65. participant.id,
  66. connectionStatus));
  67. }
  68. };
  69. }
  70. /**
  71. * Action to signal that the ID of local participant has changed. It happens
  72. * when the local participant joins a new conference or leaves an existing
  73. * conference.
  74. *
  75. * @param {string} id - New ID for local participant.
  76. * @returns {Function}
  77. */
  78. export function localParticipantIdChanged(id) {
  79. return (dispatch, getState) => {
  80. const participant = getLocalParticipant(getState);
  81. if (participant) {
  82. return dispatch({
  83. type: PARTICIPANT_ID_CHANGED,
  84. newValue: id,
  85. oldValue: participant.id
  86. });
  87. }
  88. };
  89. }
  90. /**
  91. * Action to signal that a local participant has joined.
  92. *
  93. * @param {Participant} participant={} - Information about participant.
  94. * @returns {{
  95. * type: PARTICIPANT_JOINED,
  96. * participant: Participant
  97. * }}
  98. */
  99. export function localParticipantJoined(participant = {}) {
  100. return participantJoined({
  101. ...participant,
  102. local: true
  103. });
  104. }
  105. /**
  106. * Action to remove a local participant.
  107. *
  108. * @returns {Function}
  109. */
  110. export function localParticipantLeft() {
  111. return (dispatch, getState) => {
  112. const participant = getLocalParticipant(getState);
  113. if (participant) {
  114. return (
  115. dispatch(
  116. participantLeft(
  117. participant.id,
  118. // XXX Only the local participant is allowed to leave
  119. // without stating the JitsiConference instance because
  120. // the local participant is uniquely identified by the
  121. // very fact that there is only one local participant
  122. // (and the fact that the local participant "joins" at
  123. // the beginning of the app and "leaves" at the end of
  124. // the app).
  125. undefined)));
  126. }
  127. };
  128. }
  129. /**
  130. * Action to signal the role of the local participant has changed. It can happen
  131. * when the participant has joined a conference, even before a non-default local
  132. * id has been set, or after a moderator leaves.
  133. *
  134. * @param {string} role - The new role of the local participant.
  135. * @returns {Function}
  136. */
  137. export function localParticipantRoleChanged(role) {
  138. return (dispatch, getState) => {
  139. const participant = getLocalParticipant(getState);
  140. if (participant) {
  141. return dispatch(participantRoleChanged(participant.id, role));
  142. }
  143. };
  144. }
  145. /**
  146. * Create an action for muting another participant in the conference.
  147. *
  148. * @param {string} id - Participant's ID.
  149. * @returns {{
  150. * type: MUTE_REMOTE_PARTICIPANT,
  151. * id: string
  152. * }}
  153. */
  154. export function muteRemoteParticipant(id) {
  155. return {
  156. type: MUTE_REMOTE_PARTICIPANT,
  157. id
  158. };
  159. }
  160. /**
  161. * Action to update a participant's connection status.
  162. *
  163. * @param {string} id - Participant's ID.
  164. * @param {string} connectionStatus - The new connection status of the
  165. * participant.
  166. * @returns {{
  167. * type: PARTICIPANT_UPDATED,
  168. * participant: {
  169. * connectionStatus: string,
  170. * id: string
  171. * }
  172. * }}
  173. */
  174. export function participantConnectionStatusChanged(id, connectionStatus) {
  175. return {
  176. type: PARTICIPANT_UPDATED,
  177. participant: {
  178. connectionStatus,
  179. id
  180. }
  181. };
  182. }
  183. /**
  184. * Action to signal that a participant's display name has changed.
  185. *
  186. * @param {string} id - The id of the participant being changed.
  187. * @param {string} displayName - The new display name.
  188. * @returns {{
  189. * type: PARTICIPANT_DISPLAY_NAME_CHANGED,
  190. * id: string,
  191. * name: string
  192. * }}
  193. */
  194. export function participantDisplayNameChanged(id, displayName = '') {
  195. // FIXME Do not use this action over participantUpdated. This action exists
  196. // as a a bridge for local name updates. Once other components responsible
  197. // for updating the local user's display name are in react/redux, this
  198. // action should be replaceable with the participantUpdated action.
  199. return {
  200. type: PARTICIPANT_DISPLAY_NAME_CHANGED,
  201. id,
  202. name: displayName.substr(0, MAX_DISPLAY_NAME_LENGTH)
  203. };
  204. }
  205. /**
  206. * Action to signal that a participant has joined.
  207. *
  208. * @param {Participant} participant - Information about participant.
  209. * @returns {{
  210. * type: PARTICIPANT_JOINED,
  211. * participant: Participant
  212. * }}
  213. */
  214. export function participantJoined(participant) {
  215. if (!participant.local && !participant.conference) {
  216. throw Error(
  217. 'A remote participant must be associated with a JitsiConference!');
  218. }
  219. return {
  220. type: PARTICIPANT_JOINED,
  221. participant
  222. };
  223. }
  224. /**
  225. * Action to signal that a participant has left.
  226. *
  227. * @param {string} id - Participant's ID.
  228. * @param {JitsiConference} conference - The {@code JitsiConference} associated
  229. * with the participant identified by the specified {@code id}. Only the local
  230. * participant is allowed to not specify an associated {@code JitsiConference}
  231. * instance.
  232. * @returns {{
  233. * type: PARTICIPANT_LEFT,
  234. * participant: {
  235. * conference: JitsiConference,
  236. * id: string
  237. * }
  238. * }}
  239. */
  240. export function participantLeft(id, conference) {
  241. return {
  242. type: PARTICIPANT_LEFT,
  243. participant: {
  244. conference,
  245. id
  246. }
  247. };
  248. }
  249. /**
  250. * Action to signal that a participant's presence status has changed.
  251. *
  252. * @param {string} id - Participant's ID.
  253. * @param {string} presence - Participant's new presence status.
  254. * @returns {{
  255. * type: PARTICIPANT_UPDATED,
  256. * participant: {
  257. * id: string,
  258. * presence: string
  259. * }
  260. * }}
  261. */
  262. export function participantPresenceChanged(id, presence) {
  263. return participantUpdated({
  264. id,
  265. presence
  266. });
  267. }
  268. /**
  269. * Action to signal that a participant's role has changed.
  270. *
  271. * @param {string} id - Participant's ID.
  272. * @param {PARTICIPANT_ROLE} role - Participant's new role.
  273. * @returns {{
  274. * type: PARTICIPANT_UPDATED,
  275. * participant: {
  276. * id: string,
  277. * role: PARTICIPANT_ROLE
  278. * }
  279. * }}
  280. */
  281. export function participantRoleChanged(id, role) {
  282. return participantUpdated({
  283. id,
  284. role
  285. });
  286. }
  287. /**
  288. * Action to signal that some of participant properties has been changed.
  289. *
  290. * @param {Participant} participant={} - Information about participant. To
  291. * identify the participant the object should contain either property id with
  292. * value the id of the participant or property local with value true (if the
  293. * local participant hasn't joined the conference yet).
  294. * @returns {{
  295. * type: PARTICIPANT_UPDATED,
  296. * participant: Participant
  297. * }}
  298. */
  299. export function participantUpdated(participant = {}) {
  300. return {
  301. type: PARTICIPANT_UPDATED,
  302. participant
  303. };
  304. }
  305. /**
  306. * Create an action which pins a conference participant.
  307. *
  308. * @param {string|null} id - The ID of the conference participant to pin or null
  309. * if none of the conference's participants are to be pinned.
  310. * @returns {{
  311. * type: PIN_PARTICIPANT,
  312. * participant: {
  313. * id: string
  314. * }
  315. * }}
  316. */
  317. export function pinParticipant(id) {
  318. return {
  319. type: PIN_PARTICIPANT,
  320. participant: {
  321. id
  322. }
  323. };
  324. }
  325. /**
  326. * An array of names of participants that have joined the conference. The array
  327. * is replaced with an empty array as notifications are displayed.
  328. *
  329. * @private
  330. * @type {string[]}
  331. */
  332. let joinedParticipantsNames = [];
  333. /**
  334. * A throttled internal function that takes the internal list of participant
  335. * names, {@code joinedParticipantsNames}, and triggers the display of a
  336. * notification informing of their joining.
  337. *
  338. * @private
  339. * @type {Function}
  340. */
  341. const _throttledNotifyParticipantConnected = throttle(dispatch => {
  342. const joinedParticipantsCount = joinedParticipantsNames.length;
  343. let notificationProps;
  344. if (joinedParticipantsCount >= 3) {
  345. notificationProps = {
  346. titleArguments: {
  347. name: joinedParticipantsNames[0],
  348. count: joinedParticipantsCount - 1
  349. },
  350. titleKey: 'notify.connectedThreePlusMembers'
  351. };
  352. } else if (joinedParticipantsCount === 2) {
  353. notificationProps = {
  354. titleArguments: {
  355. first: joinedParticipantsNames[0],
  356. second: joinedParticipantsNames[1]
  357. },
  358. titleKey: 'notify.connectedTwoMembers'
  359. };
  360. } else if (joinedParticipantsCount) {
  361. notificationProps = {
  362. titleArguments: {
  363. name: joinedParticipantsNames[0]
  364. },
  365. titleKey: 'notify.connectedOneMember'
  366. };
  367. }
  368. if (notificationProps) {
  369. dispatch(
  370. showNotification(notificationProps, 2500));
  371. }
  372. joinedParticipantsNames = [];
  373. }, 500, { leading: false });
  374. /**
  375. * Queues the display of a notification of a participant having connected to
  376. * the meeting. The notifications are batched so that quick consecutive
  377. * connection events are shown in one notification.
  378. *
  379. * @param {string} displayName - The name of the participant that connected.
  380. * @returns {Function}
  381. */
  382. export function showParticipantJoinedNotification(displayName) {
  383. joinedParticipantsNames.push(
  384. displayName || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME);
  385. return dispatch => _throttledNotifyParticipantConnected(dispatch);
  386. }