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.

index.tsx 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* eslint-disable lines-around-comment, no-undef, no-unused-vars */
  2. // NB: This import must always come first.
  3. import './react/bootstrap.native';
  4. import React, {
  5. forwardRef,
  6. useEffect,
  7. useImperativeHandle,
  8. useLayoutEffect,
  9. useRef,
  10. useState
  11. } from 'react';
  12. import { View, ViewStyle } from 'react-native';
  13. import type { IRoomsInfo } from '../react/features/breakout-rooms/types';
  14. import { appNavigate } from './react/features/app/actions.native';
  15. import { App } from './react/features/app/components/App.native';
  16. import { setAudioMuted, setVideoMuted } from './react/features/base/media/actions';
  17. import { getRoomsInfo } from './react/features/breakout-rooms/functions';
  18. interface IEventListeners {
  19. onAudioMutedChanged?: Function;
  20. onVideoMutedChanged?: Function;
  21. onConferenceBlurred?: Function;
  22. onConferenceFocused?: Function;
  23. onConferenceJoined?: Function;
  24. onConferenceLeft?: Function;
  25. onConferenceWillJoin?: Function;
  26. onEnterPictureInPicture?: Function;
  27. onParticipantJoined?: Function;
  28. onParticipantLeft?: ({ id }: { id: string }) => void;
  29. onReadyToClose?: Function;
  30. }
  31. interface IUserInfo {
  32. avatarURL: string;
  33. displayName: string;
  34. email: string;
  35. }
  36. interface IAppProps {
  37. config: object;
  38. eventListeners?: IEventListeners;
  39. flags?: object;
  40. room: string;
  41. serverURL?: string;
  42. style?: Object;
  43. token?: string;
  44. userInfo?: IUserInfo;
  45. }
  46. export interface JitsiRefProps {
  47. close: Function;
  48. setAudioMuted?: (muted: boolean) => void;
  49. setVideoMuted?: (muted: boolean) => void;
  50. getRoomsInfo?: () => IRoomsInfo;
  51. }
  52. /**
  53. * Main React Native SDK component that displays a Jitsi Meet conference and gets all required params as props
  54. */
  55. export const JitsiMeeting = forwardRef<JitsiRefProps, IAppProps>((props, ref) => {
  56. const [ appProps, setAppProps ] = useState({});
  57. const app = useRef(null);
  58. const {
  59. config,
  60. eventListeners,
  61. flags,
  62. room,
  63. serverURL,
  64. style,
  65. token,
  66. userInfo
  67. } = props;
  68. // eslint-disable-next-line arrow-body-style
  69. useImperativeHandle(ref, () => ({
  70. close: () => {
  71. const dispatch = app.current.state.store.dispatch;
  72. dispatch(appNavigate(undefined));
  73. },
  74. setAudioMuted: muted => {
  75. const dispatch = app.current.state.store.dispatch;
  76. dispatch(setAudioMuted(muted));
  77. },
  78. setVideoMuted: muted => {
  79. const dispatch = app.current.state.store.dispatch;
  80. dispatch(setVideoMuted(muted));
  81. },
  82. getRoomsInfo: () => {
  83. const state = app.current.state.store.getState();
  84. return getRoomsInfo(state);
  85. }
  86. }));
  87. useEffect(
  88. () => {
  89. const urlObj = {
  90. config,
  91. jwt: token
  92. };
  93. let urlProps;
  94. if (room.includes('://')) {
  95. urlProps = {
  96. ...urlObj,
  97. url: room
  98. };
  99. } else {
  100. urlProps = {
  101. ...urlObj,
  102. room,
  103. serverURL
  104. };
  105. }
  106. setAppProps({
  107. 'flags': flags,
  108. 'rnSdkHandlers': {
  109. onAudioMutedChanged: eventListeners?.onAudioMutedChanged,
  110. onVideoMutedChanged: eventListeners?.onVideoMutedChanged,
  111. onConferenceBlurred: eventListeners?.onConferenceBlurred,
  112. onConferenceFocused: eventListeners?.onConferenceFocused,
  113. onConferenceJoined: eventListeners?.onConferenceJoined,
  114. onConferenceWillJoin: eventListeners?.onConferenceWillJoin,
  115. onConferenceLeft: eventListeners?.onConferenceLeft,
  116. onEnterPictureInPicture: eventListeners?.onEnterPictureInPicture,
  117. onParticipantJoined: eventListeners?.onParticipantJoined,
  118. onParticipantLeft: eventListeners?.onParticipantLeft,
  119. onReadyToClose: eventListeners?.onReadyToClose
  120. },
  121. 'url': urlProps,
  122. 'userInfo': userInfo
  123. });
  124. }, []
  125. );
  126. // eslint-disable-next-line arrow-body-style
  127. useLayoutEffect(() => {
  128. /**
  129. * When you close the component you need to reset it.
  130. * In some cases it needs to be added as the parent component may have been destroyed.
  131. * Without this change the call remains active without having the jitsi screen.
  132. */
  133. return () => {
  134. const dispatch = app.current?.state?.store?.dispatch;
  135. dispatch && dispatch(appNavigate(undefined));
  136. };
  137. }, []);
  138. return (
  139. <View style = { style as ViewStyle }>
  140. <App
  141. { ...appProps }
  142. ref = { app } />
  143. </View>
  144. );
  145. });