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.

ChatInputBar.js 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { TextInput, TouchableOpacity, View } from 'react-native';
  4. import { Icon } from '../../../base/font-icons';
  5. import { Platform } from '../../../base/react';
  6. import styles from './styles';
  7. type Props = {
  8. /**
  9. * Callback to invoke on message send.
  10. */
  11. onSend: Function
  12. };
  13. type State = {
  14. /**
  15. * Boolean to show if an extra padding needs to be added to the bar.
  16. */
  17. addPadding: boolean,
  18. /**
  19. * The value of the input field.
  20. */
  21. message: string,
  22. /**
  23. * Boolean to show or hide the send button.
  24. */
  25. showSend: boolean
  26. };
  27. /**
  28. * Implements the chat input bar with text field and action(s).
  29. */
  30. export default class ChatInputBar extends Component<Props, State> {
  31. /**
  32. * Instantiates a new instance of the component.
  33. *
  34. * @inheritdoc
  35. */
  36. constructor(props: Props) {
  37. super(props);
  38. this.state = {
  39. addPadding: false,
  40. message: '',
  41. showSend: false
  42. };
  43. this._onChangeText = this._onChangeText.bind(this);
  44. this._onFocused = this._onFocused.bind(this);
  45. this._onSubmit = this._onSubmit.bind(this);
  46. }
  47. /**
  48. * Implements {@code Component#render}.
  49. *
  50. * @inheritdoc
  51. */
  52. render() {
  53. return (
  54. <View
  55. style = { [
  56. styles.inputBar,
  57. this.state.addPadding ? styles.extraBarPadding : null
  58. ] }>
  59. <TextInput
  60. blurOnSubmit = { false }
  61. multiline = { false }
  62. onBlur = { this._onFocused(false) }
  63. onChangeText = { this._onChangeText }
  64. onFocus = { this._onFocused(true) }
  65. onSubmitEditing = { this._onSubmit }
  66. returnKeyType = 'send'
  67. style = { styles.inputField }
  68. value = { this.state.message } />
  69. {
  70. this.state.showSend && <TouchableOpacity onPress = { this._onSubmit }>
  71. <Icon
  72. name = 'send'
  73. style = { styles.sendButtonIcon } />
  74. </TouchableOpacity>
  75. }
  76. </View>
  77. );
  78. }
  79. _onChangeText: string => void;
  80. /**
  81. * Callback to handle the change of the value of the text field.
  82. *
  83. * @param {string} text - The current value of the field.
  84. * @returns {void}
  85. */
  86. _onChangeText(text) {
  87. this.setState({
  88. message: text,
  89. showSend: Boolean(text)
  90. });
  91. }
  92. _onFocused: boolean => Function;
  93. /**
  94. * Constructs a callback to be used to update the padding of the field if necessary.
  95. *
  96. * @param {boolean} focused - True of the field is focused.
  97. * @returns {Function}
  98. */
  99. _onFocused(focused) {
  100. return () => {
  101. Platform.OS === 'android' && this.setState({
  102. addPadding: focused
  103. });
  104. };
  105. }
  106. _onSubmit: () => void;
  107. /**
  108. * Callback to handle the submit event of the text field.
  109. *
  110. * @returns {void}
  111. */
  112. _onSubmit() {
  113. const message = this.state.message.trim();
  114. message && this.props.onSend(message);
  115. this.setState({
  116. message: '',
  117. showSend: false
  118. });
  119. }
  120. }