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.

WelcomePage.native.js 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import React from 'react';
  2. import {
  3. Keyboard,
  4. SafeAreaView,
  5. Switch,
  6. TextInput,
  7. TouchableHighlight,
  8. TouchableOpacity,
  9. View
  10. } from 'react-native';
  11. import { connect } from 'react-redux';
  12. import { AppSettings } from '../../app-settings';
  13. import { translate } from '../../base/i18n';
  14. import { Icon } from '../../base/font-icons';
  15. import { MEDIA_TYPE } from '../../base/media';
  16. import { updateProfile } from '../../base/profile';
  17. import {
  18. LoadingIndicator,
  19. Header,
  20. Text
  21. } from '../../base/react';
  22. import { ColorPalette, PlatformElements } from '../../base/styles';
  23. import {
  24. createDesiredLocalTracks,
  25. destroyLocalTracks
  26. } from '../../base/tracks';
  27. import { RecentList } from '../../recent-list';
  28. import { setSideBarVisibility } from '../actions';
  29. import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
  30. import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
  31. import styles, {
  32. PLACEHOLDER_TEXT_COLOR,
  33. SWITCH_THUMB_COLOR,
  34. SWITCH_UNDER_COLOR
  35. } from './styles';
  36. import WelcomePageSideBar from './WelcomePageSideBar';
  37. /**
  38. * The native container rendering the welcome page.
  39. *
  40. * @extends AbstractWelcomePage
  41. */
  42. class WelcomePage extends AbstractWelcomePage {
  43. /**
  44. * WelcomePage component's property types.
  45. *
  46. * @static
  47. */
  48. static propTypes = AbstractWelcomePage.propTypes;
  49. /**
  50. * Constructor of the Component.
  51. *
  52. * @inheritdoc
  53. */
  54. constructor(props) {
  55. super(props);
  56. this._onShowSideBar = this._onShowSideBar.bind(this);
  57. this._onStartAudioOnlyChange = this._onStartAudioOnlyChange.bind(this);
  58. }
  59. /**
  60. * Implements React's {@link Component#componentWillMount()}. Invoked
  61. * immediately before mounting occurs. Creates a local video track if none
  62. * is available.
  63. *
  64. * @inheritdoc
  65. * @returns {void}
  66. */
  67. componentWillMount() {
  68. super.componentWillMount();
  69. const { dispatch } = this.props;
  70. if (this.props._profile.startAudioOnly) {
  71. dispatch(destroyLocalTracks());
  72. } else {
  73. dispatch(createDesiredLocalTracks(MEDIA_TYPE.VIDEO));
  74. }
  75. }
  76. /**
  77. * Implements React's {@link Component#render()}. Renders a prompt for
  78. * entering a room name.
  79. *
  80. * @inheritdoc
  81. * @returns {ReactElement}
  82. */
  83. render() {
  84. const { t, _profile } = this.props;
  85. return (
  86. <LocalVideoTrackUnderlay style = { styles.welcomePage }>
  87. <View style = { PlatformElements.page }>
  88. <Header style = { styles.header }>
  89. <TouchableOpacity onPress = { this._onShowSideBar } >
  90. <Icon
  91. name = 'menu'
  92. style = { PlatformElements.headerButton } />
  93. </TouchableOpacity>
  94. <View style = { styles.audioVideoSwitchContainer }>
  95. <Text style = { PlatformElements.headerText } >
  96. { t('welcomepage.videoEnabledLabel') }
  97. </Text>
  98. <Switch
  99. onTintColor = { SWITCH_UNDER_COLOR }
  100. onValueChange = { this._onStartAudioOnlyChange }
  101. style = { styles.audioVideoSwitch }
  102. thumbTintColor = { SWITCH_THUMB_COLOR }
  103. value = { _profile.startAudioOnly } />
  104. <Text style = { PlatformElements.headerText } >
  105. { t('welcomepage.audioOnlyLabel') }
  106. </Text>
  107. </View>
  108. </Header>
  109. <SafeAreaView style = { styles.roomContainer } >
  110. <TextInput
  111. accessibilityLabel = { 'Input room name.' }
  112. autoCapitalize = 'none'
  113. autoComplete = { false }
  114. autoCorrect = { false }
  115. autoFocus = { false }
  116. onChangeText = { this._onRoomChange }
  117. onSubmitEditing = { this._onJoin }
  118. placeholder = { t('welcomepage.roomname') }
  119. placeholderTextColor = { PLACEHOLDER_TEXT_COLOR }
  120. returnKeyType = { 'go' }
  121. style = { styles.textInput }
  122. underlineColorAndroid = 'transparent'
  123. value = { this.state.room } />
  124. {
  125. this._renderJoinButton()
  126. }
  127. <RecentList />
  128. </SafeAreaView>
  129. <AppSettings />
  130. </View>
  131. <WelcomePageSideBar />
  132. </LocalVideoTrackUnderlay>
  133. );
  134. }
  135. /**
  136. * Toggles the side bar.
  137. *
  138. * @private
  139. * @returns {void}
  140. */
  141. _onShowSideBar() {
  142. Keyboard.dismiss();
  143. this.props.dispatch(setSideBarVisibility(true));
  144. }
  145. /**
  146. * Handles the audio-video switch changes.
  147. *
  148. * @private
  149. * @param {boolean} startAudioOnly - The new startAudioOnly value.
  150. * @returns {void}
  151. */
  152. _onStartAudioOnlyChange(startAudioOnly) {
  153. const { dispatch } = this.props;
  154. dispatch(updateProfile({
  155. ...this.props._profile,
  156. startAudioOnly
  157. }));
  158. }
  159. /**
  160. * Renders the join button.
  161. *
  162. * @private
  163. * @returns {ReactElement}
  164. */
  165. _renderJoinButton() {
  166. let children;
  167. /* eslint-disable no-extra-parens */
  168. if (this.state.joining) {
  169. // TouchableHighlight is picky about what its children can be, so
  170. // wrap it in a native component, i.e. View to avoid having to
  171. // modify non-native children.
  172. children = (
  173. <View>
  174. <LoadingIndicator color = { styles.buttonText.color } />
  175. </View>
  176. );
  177. } else {
  178. children = (
  179. <Text style = { styles.buttonText }>
  180. { this.props.t('welcomepage.join') }
  181. </Text>
  182. );
  183. }
  184. /* eslint-enable no-extra-parens */
  185. return (
  186. <TouchableHighlight
  187. accessibilityLabel = { 'Tap to Join.' }
  188. disabled = { this._isJoinDisabled() }
  189. onPress = { this._onJoin }
  190. style = { styles.button }
  191. underlayColor = { ColorPalette.white }>
  192. {
  193. children
  194. }
  195. </TouchableHighlight>
  196. );
  197. }
  198. }
  199. export default translate(connect(_mapStateToProps)(WelcomePage));