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

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