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.

Prejoin.native.tsx 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* eslint-disable lines-around-comment */
  2. import { useIsFocused } from '@react-navigation/native';
  3. import React, { useCallback, useEffect, useLayoutEffect, useState } from 'react';
  4. import { useTranslation } from 'react-i18next';
  5. import {
  6. BackHandler,
  7. Platform,
  8. StyleProp,
  9. Text,
  10. TextInput,
  11. TextStyle,
  12. View,
  13. ViewStyle
  14. } from 'react-native';
  15. import { useDispatch, useSelector } from 'react-redux';
  16. // @ts-ignore
  17. import { appNavigate } from '../../app/actions.native';
  18. import { IState } from '../../app/types';
  19. // @ts-ignore
  20. import { setAudioOnly } from '../../base/audio-only/actions';
  21. // @ts-ignore
  22. import { getConferenceName } from '../../base/conference/functions';
  23. // @ts-ignore
  24. import { connect } from '../../base/connection/actions.native';
  25. import { IconClose } from '../../base/icons/svg';
  26. // @ts-ignore
  27. import JitsiScreen from '../../base/modal/components/JitsiScreen';
  28. import { getLocalParticipant } from '../../base/participants/functions';
  29. // @ts-ignore
  30. import { getFieldValue } from '../../base/react';
  31. import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui/constants';
  32. // @ts-ignore
  33. import { updateSettings } from '../../base/settings';
  34. import BaseTheme from '../../base/ui/components/BaseTheme.native';
  35. import Button from '../../base/ui/components/native/Button';
  36. import { BUTTON_TYPES } from '../../base/ui/constants';
  37. import { BrandingImageBackground } from '../../dynamic-branding';
  38. // @ts-ignore
  39. import { LargeVideo } from '../../large-video/components';
  40. // @ts-ignore
  41. import HeaderNavigationButton from '../../mobile/navigation/components/HeaderNavigationButton';
  42. // @ts-ignore
  43. import { navigateRoot } from '../../mobile/navigation/rootNavigationContainerRef';
  44. // @ts-ignore
  45. import { screen } from '../../mobile/navigation/routes';
  46. // @ts-ignore
  47. import AudioMuteButton from '../../toolbox/components/AudioMuteButton';
  48. // @ts-ignore
  49. import VideoMuteButton from '../../toolbox/components/VideoMuteButton';
  50. // @ts-ignore
  51. import { isDisplayNameRequired } from '../functions';
  52. import { PrejoinProps } from '../types';
  53. // @ts-ignore
  54. import styles from './styles';
  55. const Prejoin: React.FC<PrejoinProps> = ({ navigation }: PrejoinProps) => {
  56. const dispatch = useDispatch();
  57. const isFocused = useIsFocused();
  58. const { t } = useTranslation();
  59. const aspectRatio = useSelector(
  60. (state: IState) => state['features/base/responsive-ui']?.aspectRatio
  61. );
  62. const localParticipant = useSelector((state: IState) => getLocalParticipant(state));
  63. const isDisplayNameMandatory = useSelector(state => isDisplayNameRequired(state));
  64. const roomName = useSelector((state: IState) => getConferenceName(state));
  65. const participantName = localParticipant?.name;
  66. const [ displayName, setDisplayName ]
  67. = useState(participantName || '');
  68. const onChangeDisplayName = useCallback(event => {
  69. const fieldValue = getFieldValue(event);
  70. setDisplayName(fieldValue);
  71. dispatch(updateSettings({
  72. displayName: fieldValue
  73. }));
  74. }, [ displayName ]);
  75. const onJoin = useCallback(() => {
  76. dispatch(connect());
  77. navigateRoot(screen.conference.root);
  78. }, [ dispatch ]);
  79. const onJoinLowBandwidth = useCallback(() => {
  80. dispatch(setAudioOnly(true));
  81. onJoin();
  82. }, [ dispatch ]);
  83. const goBack = useCallback(() => {
  84. dispatch(appNavigate(undefined));
  85. return true;
  86. }, [ dispatch ]);
  87. const headerLeft = useCallback(() => {
  88. if (Platform.OS === 'ios') {
  89. return (
  90. <HeaderNavigationButton
  91. label = { t('dialog.close') }
  92. onPress = { goBack } />
  93. );
  94. }
  95. return (
  96. <HeaderNavigationButton
  97. onPress = { goBack }
  98. src = { IconClose } />
  99. );
  100. }, []);
  101. const { PRIMARY, SECONDARY } = BUTTON_TYPES;
  102. const joinButtonDisabled = !displayName && isDisplayNameMandatory;
  103. useEffect(() => {
  104. BackHandler.addEventListener('hardwareBackPress', goBack);
  105. return () => BackHandler.removeEventListener('hardwareBackPress', goBack);
  106. }, []);
  107. useLayoutEffect(() => {
  108. navigation.setOptions({
  109. headerLeft
  110. });
  111. }, [ navigation ]);
  112. let contentWrapperStyles;
  113. let contentContainerStyles;
  114. let largeVideoContainerStyles;
  115. let toolboxContainerStyles;
  116. if (aspectRatio === ASPECT_RATIO_NARROW) {
  117. contentWrapperStyles = styles.contentWrapper;
  118. contentContainerStyles = styles.contentContainer;
  119. largeVideoContainerStyles = styles.largeVideoContainer;
  120. toolboxContainerStyles = styles.toolboxContainer;
  121. } else {
  122. contentWrapperStyles = styles.contentWrapperWide;
  123. contentContainerStyles = styles.contentContainerWide;
  124. largeVideoContainerStyles = styles.largeVideoContainerWide;
  125. toolboxContainerStyles = styles.toolboxContainerWide;
  126. }
  127. return (
  128. <JitsiScreen
  129. safeAreaInsets = { [ 'left' ] }
  130. style = { contentWrapperStyles }>
  131. <BrandingImageBackground />
  132. {
  133. isFocused
  134. && <View style = { largeVideoContainerStyles }>
  135. <LargeVideo />
  136. </View>
  137. }
  138. <View style = { contentContainerStyles }>
  139. <View style = { styles.formWrapper as StyleProp<ViewStyle> }>
  140. <Text style = { styles.preJoinTitle as StyleProp<TextStyle> }>
  141. { t('prejoin.joinMeeting') }
  142. </Text>
  143. <Text
  144. numberOfLines = { 1 }
  145. style = { styles.preJoinRoomName as StyleProp<TextStyle> }>
  146. { roomName }
  147. </Text>
  148. <TextInput
  149. onChangeText = { onChangeDisplayName }
  150. placeholder = { t('dialog.enterDisplayName') }
  151. placeholderTextColor = { BaseTheme.palette.text03 }
  152. style = { styles.field as StyleProp<TextStyle> }
  153. value = { displayName } />
  154. <Button
  155. accessibilityLabel = 'prejoin.joinMeeting'
  156. disabled = { joinButtonDisabled }
  157. labelKey = 'prejoin.joinMeeting'
  158. onClick = { onJoin }
  159. style = { styles.prejoinButton }
  160. type = { PRIMARY } />
  161. <Button
  162. accessibilityLabel = 'prejoin.joinMeetingInLowBandwidthMode'
  163. labelKey = 'prejoin.joinMeetingInLowBandwidthMode'
  164. onClick = { onJoinLowBandwidth }
  165. style = { styles.prejoinButton }
  166. type = { SECONDARY } />
  167. </View>
  168. <View style = { toolboxContainerStyles }>
  169. <AudioMuteButton
  170. styles = { styles.buttonStylesBorderless } />
  171. <VideoMuteButton
  172. styles = { styles.buttonStylesBorderless } />
  173. </View>
  174. </View>
  175. </JitsiScreen>
  176. );
  177. };
  178. export default Prejoin;