您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

index.tsx 5.3KB

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