Forked from GollyJer/react-native-gifted-chat+0.9.11.patch
Created
January 3, 2020 08:50
-
-
Save xcarpentier/b4c4ab8570857702e15b33567fffb4fc to your computer and use it in GitHub Desktop.
Patch react-native-gifted-chat to eliminate need for sizing code. Allows the chat data to stay cached.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/node_modules/react-native-gifted-chat/lib/GiftedChat.js b/node_modules/react-native-gifted-chat/lib/GiftedChat.js | |
index 7f3f4b5..78ea7a1 100644 | |
--- a/node_modules/react-native-gifted-chat/lib/GiftedChat.js | |
+++ b/node_modules/react-native-gifted-chat/lib/GiftedChat.js | |
@@ -1,6 +1,13 @@ | |
import PropTypes from 'prop-types'; | |
import React from 'react'; | |
-import { Animated, Platform, StyleSheet, View, SafeAreaView, } from 'react-native'; | |
+import { | |
+ Animated, | |
+ Platform, | |
+ StyleSheet, | |
+ View, | |
+ KeyboardAvoidingView, | |
+ SafeAreaView, | |
+} from 'react-native'; | |
import ActionSheet from '@expo/react-native-action-sheet'; | |
import moment from 'moment'; | |
import uuid from 'uuid'; | |
@@ -21,520 +28,626 @@ import MessageContainer from './MessageContainer'; | |
import Send from './Send'; | |
import Time from './Time'; | |
import GiftedAvatar from './GiftedAvatar'; | |
-import { MIN_COMPOSER_HEIGHT, MAX_COMPOSER_HEIGHT, DEFAULT_PLACEHOLDER, TIME_FORMAT, DATE_FORMAT, } from './Constant'; | |
+import { | |
+ MIN_COMPOSER_HEIGHT, | |
+ MAX_COMPOSER_HEIGHT, | |
+ DEFAULT_PLACEHOLDER, | |
+ TIME_FORMAT, | |
+ DATE_FORMAT, | |
+} from './Constant'; | |
+ | |
const GiftedActionSheet = ActionSheet; | |
class GiftedChat extends React.Component { | |
- constructor(props) { | |
- super(props); | |
- this._isMounted = false; | |
- this._keyboardHeight = 0; | |
- this._bottomOffset = 0; | |
- this._maxHeight = undefined; | |
- this._isFirstLayout = true; | |
- this._locale = 'en'; | |
- this._messages = []; | |
- this.invertibleScrollViewProps = undefined; | |
- this._actionSheetRef = undefined; | |
- this._messageContainerRef = React.createRef(); | |
- this.state = { | |
- isInitialized: false, | |
- composerHeight: this.props.minComposerHeight, | |
- messagesContainerHeight: undefined, | |
- typingDisabled: false, | |
- text: undefined, | |
- }; | |
- this.getLocale = () => this._locale; | |
- this.safeAreaIphoneX = (bottomOffset) => { | |
- if (isIphoneX()) { | |
- return bottomOffset === this._bottomOffset ? 33 : bottomOffset; | |
- } | |
- return bottomOffset; | |
- }; | |
- this.onKeyboardWillShow = (e) => { | |
- this.setIsTypingDisabled(true); | |
- this.setKeyboardHeight(e.endCoordinates ? e.endCoordinates.height : e.end.height); | |
- this.setBottomOffset(this.safeAreaIphoneX(this.props.bottomOffset)); | |
- const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard(); | |
- if (this.props.isAnimated === true) { | |
- Animated.timing(this.state.messagesContainerHeight, { | |
- toValue: newMessagesContainerHeight, | |
- duration: 210, | |
- }).start(); | |
- } | |
- else { | |
- this.setState({ | |
- messagesContainerHeight: newMessagesContainerHeight, | |
- }); | |
- } | |
- }; | |
- this.onKeyboardWillHide = (_e) => { | |
- this.setIsTypingDisabled(true); | |
- this.setKeyboardHeight(0); | |
- this.setBottomOffset(0); | |
- const newMessagesContainerHeight = this.getBasicMessagesContainerHeight(); | |
- if (this.props.isAnimated === true) { | |
- Animated.timing(this.state.messagesContainerHeight, { | |
- toValue: newMessagesContainerHeight, | |
- duration: 210, | |
- }).start(); | |
- } | |
- else { | |
- this.setState({ | |
- messagesContainerHeight: newMessagesContainerHeight, | |
- }); | |
- } | |
- }; | |
- this.onKeyboardDidShow = (e) => { | |
- if (Platform.OS === 'android') { | |
- this.onKeyboardWillShow(e); | |
- } | |
- this.setIsTypingDisabled(false); | |
- }; | |
- this.onKeyboardDidHide = (e) => { | |
- if (Platform.OS === 'android') { | |
- this.onKeyboardWillHide(e); | |
- } | |
- this.setIsTypingDisabled(false); | |
- }; | |
- this.onSend = (messages = [], shouldResetInputToolbar = false) => { | |
- if (!Array.isArray(messages)) { | |
- messages = [messages]; | |
- } | |
- const newMessages = messages.map(message => { | |
- return { | |
- ...message, | |
- user: this.props.user, | |
- createdAt: new Date(), | |
- _id: this.props.messageIdGenerator && this.props.messageIdGenerator(), | |
- }; | |
- }); | |
- if (shouldResetInputToolbar === true) { | |
- this.setIsTypingDisabled(true); | |
- this.resetInputToolbar(); | |
- } | |
- if (this.props.onSend) { | |
- this.props.onSend(newMessages); | |
- } | |
- this.scrollToBottom(); | |
- if (shouldResetInputToolbar === true) { | |
- setTimeout(() => { | |
- if (this.getIsMounted() === true) { | |
- this.setIsTypingDisabled(false); | |
- } | |
- }, 100); | |
- } | |
- }; | |
- this.onInputSizeChanged = (size) => { | |
- const newComposerHeight = Math.max(this.props.minComposerHeight, Math.min(this.props.maxComposerHeight, size.height)); | |
- const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard(newComposerHeight); | |
- this.setState({ | |
- composerHeight: newComposerHeight, | |
- messagesContainerHeight: this.prepareMessagesContainerHeight(newMessagesContainerHeight), | |
- }); | |
- }; | |
- this.onInputTextChanged = (text) => { | |
- if (this.getIsTypingDisabled()) { | |
- return; | |
- } | |
- if (this.props.onInputTextChanged) { | |
- this.props.onInputTextChanged(text); | |
- } | |
- // Only set state if it's not being overridden by a prop. | |
- if (this.props.text === undefined) { | |
- this.setState({ text }); | |
- } | |
- }; | |
- this.onInitialLayoutViewLayout = (e) => { | |
- const { layout } = e.nativeEvent; | |
- if (layout.height <= 0) { | |
- return; | |
- } | |
- this.notifyInputTextReset(); | |
- this.setMaxHeight(layout.height); | |
- const newComposerHeight = this.props.minComposerHeight; | |
- const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard(newComposerHeight); | |
- const initialText = this.props.initialText || ''; | |
- this.setState({ | |
- isInitialized: true, | |
- text: this.getTextFromProp(initialText), | |
- composerHeight: newComposerHeight, | |
- messagesContainerHeight: this.prepareMessagesContainerHeight(newMessagesContainerHeight), | |
- }); | |
- }; | |
- this.onMainViewLayout = (e) => { | |
- // fix an issue when keyboard is dismissing during the initialization | |
- const { layout } = e.nativeEvent; | |
- if (this.getMaxHeight() !== layout.height || | |
- this.getIsFirstLayout() === true) { | |
- this.setMaxHeight(layout.height); | |
- this.setState({ | |
- messagesContainerHeight: this.prepareMessagesContainerHeight(this.getBasicMessagesContainerHeight()), | |
- }); | |
- } | |
- if (this.getIsFirstLayout() === true) { | |
- this.setIsFirstLayout(false); | |
- } | |
- }; | |
- this.invertibleScrollViewProps = { | |
- inverted: this.props.inverted, | |
- keyboardShouldPersistTaps: this.props.keyboardShouldPersistTaps, | |
- onKeyboardWillShow: this.onKeyboardWillShow, | |
- onKeyboardWillHide: this.onKeyboardWillHide, | |
- onKeyboardDidShow: this.onKeyboardDidShow, | |
- onKeyboardDidHide: this.onKeyboardDidHide, | |
- }; | |
- } | |
- static append(currentMessages = [], messages, inverted = true) { | |
- if (!Array.isArray(messages)) { | |
- messages = [messages]; | |
- } | |
- return inverted | |
- ? messages.concat(currentMessages) | |
- : currentMessages.concat(messages); | |
- } | |
- static prepend(currentMessages = [], messages, inverted = true) { | |
- if (!Array.isArray(messages)) { | |
- messages = [messages]; | |
- } | |
- return inverted | |
- ? currentMessages.concat(messages) | |
- : messages.concat(currentMessages); | |
- } | |
- getChildContext() { | |
- return { | |
- actionSheet: () => this._actionSheetRef, | |
- getLocale: this.getLocale, | |
- }; | |
- } | |
- componentWillMount() { | |
- const { messages, text } = this.props; | |
- this.setIsMounted(true); | |
- this.initLocale(); | |
- this.setMessages(messages || []); | |
- this.setTextFromProp(text); | |
- } | |
- componentWillUnmount() { | |
- this.setIsMounted(false); | |
- } | |
- componentWillReceiveProps(nextProps = {}) { | |
- const { messages, text } = nextProps; | |
- this.setMessages(messages || []); | |
- this.setTextFromProp(text); | |
- } | |
- initLocale() { | |
- if (this.props.locale === null || | |
- moment.locales().indexOf(this.props.locale || 'en') === -1) { | |
- this.setLocale('en'); | |
- } | |
- else { | |
- this.setLocale(this.props.locale || 'en'); | |
- } | |
- } | |
- setLocale(locale) { | |
- this._locale = locale; | |
- } | |
- setTextFromProp(textProp) { | |
- // Text prop takes precedence over state. | |
- if (textProp !== undefined && textProp !== this.state.text) { | |
- this.setState({ text: textProp }); | |
- } | |
- } | |
- getTextFromProp(fallback) { | |
- if (this.props.text === undefined) { | |
- return fallback; | |
- } | |
- return this.props.text; | |
- } | |
- setMessages(messages) { | |
- this._messages = messages; | |
- } | |
- getMessages() { | |
- return this._messages; | |
- } | |
- setMaxHeight(height) { | |
- this._maxHeight = height; | |
- } | |
- getMaxHeight() { | |
- return this._maxHeight; | |
- } | |
- setKeyboardHeight(height) { | |
- this._keyboardHeight = height; | |
- } | |
- getKeyboardHeight() { | |
- if (Platform.OS === 'android' && !this.props.forceGetKeyboardHeight) { | |
- // For android: on-screen keyboard resized main container and has own height. | |
- // @see https://developer.android.com/training/keyboard-input/visibility.html | |
- // So for calculate the messages container height ignore keyboard height. | |
- return 0; | |
- } | |
- return this._keyboardHeight; | |
- } | |
- setBottomOffset(value) { | |
- this._bottomOffset = value; | |
- } | |
- getBottomOffset() { | |
- return this._bottomOffset; | |
- } | |
- setIsFirstLayout(value) { | |
- this._isFirstLayout = value; | |
- } | |
- getIsFirstLayout() { | |
- return this._isFirstLayout; | |
- } | |
- setIsTypingDisabled(value) { | |
+ constructor(props) { | |
+ super(props); | |
+ this._isMounted = false; | |
+ this._keyboardHeight = 0; | |
+ this._bottomOffset = 0; | |
+ this._maxHeight = undefined; | |
+ this._isFirstLayout = true; | |
+ this._locale = 'en'; | |
+ this._messages = []; | |
+ this.invertibleScrollViewProps = undefined; | |
+ this._actionSheetRef = undefined; | |
+ this._messageContainerRef = React.createRef(); | |
+ this.state = { | |
+ isInitialized: false, | |
+ composerHeight: this.props.minComposerHeight, | |
+ messagesContainerHeight: undefined, | |
+ typingDisabled: false, | |
+ text: undefined, | |
+ }; | |
+ this.getLocale = () => this._locale; | |
+ this.safeAreaIphoneX = (bottomOffset) => { | |
+ if (isIphoneX()) { | |
+ return bottomOffset === this._bottomOffset ? 33 : bottomOffset; | |
+ } | |
+ return bottomOffset; | |
+ }; | |
+ this.onKeyboardWillShow = (e) => { | |
+ this.setIsTypingDisabled(true); | |
+ this.setKeyboardHeight( | |
+ e.endCoordinates ? e.endCoordinates.height : e.end.height, | |
+ ); | |
+ this.setBottomOffset(this.safeAreaIphoneX(this.props.bottomOffset)); | |
+ const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard(); | |
+ if (this.props.isAnimated === true) { | |
+ Animated.timing(this.state.messagesContainerHeight, { | |
+ toValue: newMessagesContainerHeight, | |
+ duration: 210, | |
+ }).start(); | |
+ } else { | |
this.setState({ | |
- typingDisabled: value, | |
+ messagesContainerHeight: newMessagesContainerHeight, | |
}); | |
- } | |
- getIsTypingDisabled() { | |
- return this.state.typingDisabled; | |
- } | |
- setIsMounted(value) { | |
- this._isMounted = value; | |
- } | |
- getIsMounted() { | |
- return this._isMounted; | |
- } | |
- getMinInputToolbarHeight() { | |
- return this.props.renderAccessory | |
- ? this.props.minInputToolbarHeight * 2 | |
- : this.props.minInputToolbarHeight; | |
- } | |
- calculateInputToolbarHeight(composerHeight) { | |
- return (composerHeight + | |
- (this.getMinInputToolbarHeight() - this.props.minComposerHeight)); | |
- } | |
- /** | |
- * Returns the height, based on current window size, without taking the keyboard into account. | |
- */ | |
- getBasicMessagesContainerHeight(composerHeight = this.state.composerHeight) { | |
- return (this.getMaxHeight() - this.calculateInputToolbarHeight(composerHeight)); | |
- } | |
- /** | |
- * Returns the height, based on current window size, taking the keyboard into account. | |
- */ | |
- getMessagesContainerHeightWithKeyboard(composerHeight = this.state.composerHeight) { | |
- return (this.getBasicMessagesContainerHeight(composerHeight) - | |
- this.getKeyboardHeight() + | |
- this.getBottomOffset()); | |
- } | |
- prepareMessagesContainerHeight(value) { | |
- if (this.props.isAnimated === true) { | |
- return new Animated.Value(value); | |
- } | |
- return value; | |
- } | |
- scrollToBottom(animated = true) { | |
- if (this._messageContainerRef && this._messageContainerRef.current) { | |
- this._messageContainerRef.current.scrollTo({ offset: 0, animated }); | |
- } | |
- } | |
- renderMessages() { | |
- const AnimatedView = this.props.isAnimated === true ? Animated.View : View; | |
- return (<AnimatedView style={{ | |
- height: this.state.messagesContainerHeight, | |
- }}> | |
- <MessageContainer {...this.props} invertibleScrollViewProps={this.invertibleScrollViewProps} messages={this.getMessages()} ref={this._messageContainerRef}/> | |
- {this.renderChatFooter()} | |
- </AnimatedView>); | |
- } | |
- resetInputToolbar() { | |
- if (this.textInput) { | |
- this.textInput.clear(); | |
- } | |
- this.notifyInputTextReset(); | |
- const newComposerHeight = this.props.minComposerHeight; | |
- const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard(newComposerHeight); | |
+ } | |
+ }; | |
+ this.onKeyboardWillHide = (_e) => { | |
+ this.setIsTypingDisabled(true); | |
+ this.setKeyboardHeight(0); | |
+ this.setBottomOffset(0); | |
+ const newMessagesContainerHeight = this.getBasicMessagesContainerHeight(); | |
+ if (this.props.isAnimated === true) { | |
+ Animated.timing(this.state.messagesContainerHeight, { | |
+ toValue: newMessagesContainerHeight, | |
+ duration: 210, | |
+ }).start(); | |
+ } else { | |
this.setState({ | |
- text: this.getTextFromProp(''), | |
- composerHeight: newComposerHeight, | |
- messagesContainerHeight: this.prepareMessagesContainerHeight(newMessagesContainerHeight), | |
+ messagesContainerHeight: newMessagesContainerHeight, | |
}); | |
- } | |
- focusTextInput() { | |
- if (this.textInput) { | |
- this.textInput.focus(); | |
- } | |
- } | |
- notifyInputTextReset() { | |
- if (this.props.onInputTextChanged) { | |
- this.props.onInputTextChanged(''); | |
- } | |
- } | |
- renderInputToolbar() { | |
- const inputToolbarProps = { | |
- ...this.props, | |
- text: this.getTextFromProp(this.state.text), | |
- composerHeight: Math.max(this.props.minComposerHeight, this.state.composerHeight), | |
- onSend: this.onSend, | |
- onInputSizeChanged: this.onInputSizeChanged, | |
- onTextChanged: this.onInputTextChanged, | |
- textInputProps: { | |
- ...this.props.textInputProps, | |
- ref: (textInput) => (this.textInput = textInput), | |
- maxLength: this.getIsTypingDisabled() ? 0 : this.props.maxInputLength, | |
- }, | |
- }; | |
- if (this.props.renderInputToolbar) { | |
- return this.props.renderInputToolbar(inputToolbarProps); | |
- } | |
- return <InputToolbar {...inputToolbarProps}/>; | |
- } | |
- renderChatFooter() { | |
- if (this.props.renderChatFooter) { | |
- return this.props.renderChatFooter(); | |
- } | |
- return null; | |
- } | |
- renderLoading() { | |
- if (this.props.renderLoading) { | |
- return this.props.renderLoading(); | |
- } | |
- return null; | |
- } | |
- render() { | |
- if (this.state.isInitialized === true) { | |
- return (<SafeAreaView style={styles.safeArea}> | |
- <GiftedActionSheet ref={(component) => (this._actionSheetRef = component)}> | |
- <View style={styles.container} onLayout={this.onMainViewLayout}> | |
- {this.renderMessages()} | |
- {this.renderInputToolbar()} | |
- </View> | |
- </GiftedActionSheet> | |
- </SafeAreaView>); | |
- } | |
- return (<View style={styles.container} onLayout={this.onInitialLayoutViewLayout}> | |
- {this.renderLoading()} | |
- </View>); | |
- } | |
+ } | |
+ }; | |
+ this.onKeyboardDidShow = (e) => { | |
+ if (Platform.OS === 'android') { | |
+ this.onKeyboardWillShow(e); | |
+ } | |
+ this.setIsTypingDisabled(false); | |
+ }; | |
+ this.onKeyboardDidHide = (e) => { | |
+ if (Platform.OS === 'android') { | |
+ this.onKeyboardWillHide(e); | |
+ } | |
+ this.setIsTypingDisabled(false); | |
+ }; | |
+ this.onSend = (messages = [], shouldResetInputToolbar = false) => { | |
+ if (!Array.isArray(messages)) { | |
+ messages = [messages]; | |
+ } | |
+ const newMessages = messages.map(message => ({ | |
+ ...message, | |
+ user: this.props.user, | |
+ createdAt: new Date(), | |
+ _id: this.props.messageIdGenerator && this.props.messageIdGenerator(), | |
+ })); | |
+ if (shouldResetInputToolbar === true) { | |
+ this.setIsTypingDisabled(true); | |
+ this.resetInputToolbar(); | |
+ } | |
+ if (this.props.onSend) { | |
+ this.props.onSend(newMessages); | |
+ } | |
+ this.scrollToBottom(); | |
+ if (shouldResetInputToolbar === true) { | |
+ setTimeout(() => { | |
+ if (this.getIsMounted() === true) { | |
+ this.setIsTypingDisabled(false); | |
+ } | |
+ }, 100); | |
+ } | |
+ }; | |
+ this.onInputSizeChanged = (size) => { | |
+ const newComposerHeight = Math.max( | |
+ this.props.minComposerHeight, | |
+ Math.min(this.props.maxComposerHeight, size.height), | |
+ ); | |
+ const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard( | |
+ newComposerHeight, | |
+ ); | |
+ this.setState({ | |
+ composerHeight: newComposerHeight, | |
+ messagesContainerHeight: this.prepareMessagesContainerHeight( | |
+ newMessagesContainerHeight, | |
+ ), | |
+ }); | |
+ }; | |
+ this.onInputTextChanged = (text) => { | |
+ if (this.getIsTypingDisabled()) { | |
+ return; | |
+ } | |
+ if (this.props.onInputTextChanged) { | |
+ this.props.onInputTextChanged(text); | |
+ } | |
+ // Only set state if it's not being overridden by a prop. | |
+ if (this.props.text === undefined) { | |
+ this.setState({ text }); | |
+ } | |
+ }; | |
+ this.onInitialLayoutViewLayout = (e) => { | |
+ const { layout } = e.nativeEvent; | |
+ if (layout.height <= 0) { | |
+ return; | |
+ } | |
+ this.notifyInputTextReset(); | |
+ this.setMaxHeight(layout.height); | |
+ const newComposerHeight = this.props.minComposerHeight; | |
+ const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard( | |
+ newComposerHeight, | |
+ ); | |
+ const initialText = this.props.initialText || ''; | |
+ this.setState({ | |
+ isInitialized: true, | |
+ text: this.getTextFromProp(initialText), | |
+ composerHeight: newComposerHeight, | |
+ messagesContainerHeight: this.prepareMessagesContainerHeight( | |
+ newMessagesContainerHeight, | |
+ ), | |
+ }); | |
+ }; | |
+ this.onMainViewLayout = (e) => { | |
+ // fix an issue when keyboard is dismissing during the initialization | |
+ const { layout } = e.nativeEvent; | |
+ if ( | |
+ this.getMaxHeight() !== layout.height | |
+ || this.getIsFirstLayout() === true | |
+ ) { | |
+ this.setMaxHeight(layout.height); | |
+ this.setState({ | |
+ messagesContainerHeight: this.prepareMessagesContainerHeight( | |
+ this.getBasicMessagesContainerHeight(), | |
+ ), | |
+ }); | |
+ } | |
+ if (this.getIsFirstLayout() === true) { | |
+ this.setIsFirstLayout(false); | |
+ } | |
+ }; | |
+ this.invertibleScrollViewProps = { | |
+ inverted: this.props.inverted, | |
+ keyboardShouldPersistTaps: this.props.keyboardShouldPersistTaps, | |
+ onKeyboardWillShow: this.onKeyboardWillShow, | |
+ onKeyboardWillHide: this.onKeyboardWillHide, | |
+ onKeyboardDidShow: this.onKeyboardDidShow, | |
+ onKeyboardDidHide: this.onKeyboardDidHide, | |
+ }; | |
+ } | |
+ | |
+ static append(currentMessages = [], messages, inverted = true) { | |
+ if (!Array.isArray(messages)) { | |
+ messages = [messages]; | |
+ } | |
+ return inverted | |
+ ? messages.concat(currentMessages) | |
+ : currentMessages.concat(messages); | |
+ } | |
+ | |
+ static prepend(currentMessages = [], messages, inverted = true) { | |
+ if (!Array.isArray(messages)) { | |
+ messages = [messages]; | |
+ } | |
+ return inverted | |
+ ? currentMessages.concat(messages) | |
+ : messages.concat(currentMessages); | |
+ } | |
+ | |
+ getChildContext() { | |
+ return { | |
+ actionSheet: () => this._actionSheetRef, | |
+ getLocale: this.getLocale, | |
+ }; | |
+ } | |
+ | |
+ componentWillMount() { | |
+ const { messages, text } = this.props; | |
+ this.setIsMounted(true); | |
+ this.initLocale(); | |
+ this.setMessages(messages || []); | |
+ this.setTextFromProp(text); | |
+ } | |
+ | |
+ componentWillUnmount() { | |
+ this.setIsMounted(false); | |
+ } | |
+ | |
+ componentWillReceiveProps(nextProps = {}) { | |
+ const { messages, text } = nextProps; | |
+ this.setMessages(messages || []); | |
+ this.setTextFromProp(text); | |
+ } | |
+ | |
+ initLocale() { | |
+ if ( | |
+ this.props.locale === null | |
+ || moment.locales().indexOf(this.props.locale || 'en') === -1 | |
+ ) { | |
+ this.setLocale('en'); | |
+ } else { | |
+ this.setLocale(this.props.locale || 'en'); | |
+ } | |
+ } | |
+ | |
+ setLocale(locale) { | |
+ this._locale = locale; | |
+ } | |
+ | |
+ setTextFromProp(textProp) { | |
+ // Text prop takes precedence over state. | |
+ if (textProp !== undefined && textProp !== this.state.text) { | |
+ this.setState({ text: textProp }); | |
+ } | |
+ } | |
+ | |
+ getTextFromProp(fallback) { | |
+ if (this.props.text === undefined) { | |
+ return fallback; | |
+ } | |
+ return this.props.text; | |
+ } | |
+ | |
+ setMessages(messages) { | |
+ this._messages = messages; | |
+ } | |
+ | |
+ getMessages() { | |
+ return this._messages; | |
+ } | |
+ | |
+ setMaxHeight(height) { | |
+ this._maxHeight = height; | |
+ } | |
+ | |
+ getMaxHeight() { | |
+ return this._maxHeight; | |
+ } | |
+ | |
+ setKeyboardHeight(height) { | |
+ this._keyboardHeight = height; | |
+ } | |
+ | |
+ getKeyboardHeight() { | |
+ if (Platform.OS === 'android' && !this.props.forceGetKeyboardHeight) { | |
+ // For android: on-screen keyboard resized main container and has own height. | |
+ // @see https://developer.android.com/training/keyboard-input/visibility.html | |
+ // So for calculate the messages container height ignore keyboard height. | |
+ return 0; | |
+ } | |
+ return this._keyboardHeight; | |
+ } | |
+ | |
+ setBottomOffset(value) { | |
+ this._bottomOffset = value; | |
+ } | |
+ | |
+ getBottomOffset() { | |
+ return this._bottomOffset; | |
+ } | |
+ | |
+ setIsFirstLayout(value) { | |
+ this._isFirstLayout = value; | |
+ } | |
+ | |
+ getIsFirstLayout() { | |
+ return this._isFirstLayout; | |
+ } | |
+ | |
+ setIsTypingDisabled(value) { | |
+ this.setState({ | |
+ typingDisabled: value, | |
+ }); | |
+ } | |
+ | |
+ getIsTypingDisabled() { | |
+ return this.state.typingDisabled; | |
+ } | |
+ | |
+ setIsMounted(value) { | |
+ this._isMounted = value; | |
+ } | |
+ | |
+ getIsMounted() { | |
+ return this._isMounted; | |
+ } | |
+ | |
+ getMinInputToolbarHeight() { | |
+ return this.props.renderAccessory | |
+ ? this.props.minInputToolbarHeight * 2 | |
+ : this.props.minInputToolbarHeight; | |
+ } | |
+ | |
+ calculateInputToolbarHeight(composerHeight) { | |
+ return ( | |
+ composerHeight | |
+ + (this.getMinInputToolbarHeight() - this.props.minComposerHeight) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Returns the height, based on current window size, without taking the keyboard into account. | |
+ */ | |
+ getBasicMessagesContainerHeight(composerHeight = this.state.composerHeight) { | |
+ return ( | |
+ this.getMaxHeight() - this.calculateInputToolbarHeight(composerHeight) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Returns the height, based on current window size, taking the keyboard into account. | |
+ */ | |
+ getMessagesContainerHeightWithKeyboard( | |
+ composerHeight = this.state.composerHeight, | |
+ ) { | |
+ return ( | |
+ this.getBasicMessagesContainerHeight(composerHeight) | |
+ - this.getKeyboardHeight() | |
+ + this.getBottomOffset() | |
+ ); | |
+ } | |
+ | |
+ prepareMessagesContainerHeight(value) { | |
+ if (this.props.isAnimated === true) { | |
+ return new Animated.Value(value); | |
+ } | |
+ return value; | |
+ } | |
+ | |
+ scrollToBottom(animated = true) { | |
+ if (this._messageContainerRef && this._messageContainerRef.current) { | |
+ this._messageContainerRef.current.scrollTo({ offset: 0, animated }); | |
+ } | |
+ } | |
+ | |
+ renderMessages() { | |
+ const AnimatedView = this.props.isAnimated === true ? Animated.View : View; | |
+ return ( | |
+ <AnimatedView | |
+ style={{ | |
+ flex: 1, | |
+ // height: this.state.messagesContainerHeight, | |
+ }} | |
+ > | |
+ <MessageContainer | |
+ {...this.props} | |
+ invertibleScrollViewProps={this.invertibleScrollViewProps} | |
+ messages={this.getMessages()} | |
+ ref={this._messageContainerRef} | |
+ /> | |
+ {this.renderChatFooter()} | |
+ </AnimatedView> | |
+ ); | |
+ } | |
+ | |
+ resetInputToolbar() { | |
+ if (this.textInput) { | |
+ this.textInput.clear(); | |
+ } | |
+ this.notifyInputTextReset(); | |
+ const newComposerHeight = this.props.minComposerHeight; | |
+ const newMessagesContainerHeight = this.getMessagesContainerHeightWithKeyboard( | |
+ newComposerHeight, | |
+ ); | |
+ this.setState({ | |
+ text: this.getTextFromProp(''), | |
+ composerHeight: newComposerHeight, | |
+ messagesContainerHeight: this.prepareMessagesContainerHeight( | |
+ newMessagesContainerHeight, | |
+ ), | |
+ }); | |
+ } | |
+ | |
+ focusTextInput() { | |
+ if (this.textInput) { | |
+ this.textInput.focus(); | |
+ } | |
+ } | |
+ | |
+ notifyInputTextReset() { | |
+ if (this.props.onInputTextChanged) { | |
+ this.props.onInputTextChanged(''); | |
+ } | |
+ } | |
+ | |
+ renderInputToolbar() { | |
+ const inputToolbarProps = { | |
+ ...this.props, | |
+ text: this.getTextFromProp(this.state.text), | |
+ composerHeight: Math.max( | |
+ this.props.minComposerHeight, | |
+ this.state.composerHeight, | |
+ ), | |
+ onSend: this.onSend, | |
+ onInputSizeChanged: this.onInputSizeChanged, | |
+ onTextChanged: this.onInputTextChanged, | |
+ textInputProps: { | |
+ ...this.props.textInputProps, | |
+ ref: textInput => (this.textInput = textInput), | |
+ maxLength: this.getIsTypingDisabled() ? 0 : this.props.maxInputLength, | |
+ }, | |
+ }; | |
+ if (this.props.renderInputToolbar) { | |
+ return this.props.renderInputToolbar(inputToolbarProps); | |
+ } | |
+ return <InputToolbar {...inputToolbarProps} />; | |
+ } | |
+ | |
+ renderChatFooter() { | |
+ if (this.props.renderChatFooter) { | |
+ return this.props.renderChatFooter(); | |
+ } | |
+ return null; | |
+ } | |
+ | |
+ renderLoading() { | |
+ if (this.props.renderLoading) { | |
+ return this.props.renderLoading(); | |
+ } | |
+ return null; | |
+ } | |
+ | |
+ render() { | |
+ // if (this.state.isInitialized === true) { | |
+ return ( | |
+ // <SafeAreaView style={styles.safeArea}> | |
+ <GiftedActionSheet ref={component => (this._actionSheetRef = component)}> | |
+ <View style={styles.container}> | |
+ {this.renderMessages()} | |
+ {this.renderInputToolbar()} | |
+ </View> | |
+ </GiftedActionSheet> | |
+ // </SafeAreaView> | |
+ ); | |
+ // } | |
+ // return ( | |
+ // <View style={styles.container} onLayout={this.onInitialLayoutViewLayout}> | |
+ // {this.renderLoading()} | |
+ // </View> | |
+ // ); | |
+ } | |
} | |
GiftedChat.childContextTypes = { | |
- actionSheet: PropTypes.func, | |
- getLocale: PropTypes.func, | |
+ actionSheet: PropTypes.func, | |
+ getLocale: PropTypes.func, | |
}; | |
GiftedChat.defaultProps = { | |
- messages: [], | |
- text: undefined, | |
- placeholder: DEFAULT_PLACEHOLDER, | |
- messageIdGenerator: () => uuid.v4(), | |
- user: {}, | |
- onSend: () => { }, | |
- locale: null, | |
- timeFormat: TIME_FORMAT, | |
- dateFormat: DATE_FORMAT, | |
- isAnimated: Platform.select({ | |
- ios: true, | |
- android: false, | |
- }), | |
- loadEarlier: false, | |
- onLoadEarlier: () => { }, | |
- isLoadingEarlier: false, | |
- renderLoading: null, | |
- renderLoadEarlier: null, | |
- renderAvatar: undefined, | |
- showUserAvatar: false, | |
- onPressAvatar: null, | |
- renderUsernameOnMessage: false, | |
- renderAvatarOnTop: false, | |
- renderBubble: null, | |
- renderSystemMessage: null, | |
- onLongPress: null, | |
- renderMessage: null, | |
- renderMessageText: null, | |
- renderMessageImage: null, | |
- imageProps: {}, | |
- videoProps: {}, | |
- lightboxProps: {}, | |
- textInputProps: {}, | |
- listViewProps: {}, | |
- renderCustomView: null, | |
- renderDay: null, | |
- renderTime: null, | |
- renderFooter: null, | |
- renderChatFooter: null, | |
- renderInputToolbar: null, | |
- renderComposer: null, | |
- renderActions: null, | |
- renderSend: null, | |
- renderAccessory: null, | |
- onPressActionButton: null, | |
- bottomOffset: 0, | |
- minInputToolbarHeight: 44, | |
- keyboardShouldPersistTaps: Platform.select({ | |
- ios: 'never', | |
- android: 'always', | |
- }), | |
- onInputTextChanged: null, | |
- maxInputLength: null, | |
- forceGetKeyboardHeight: false, | |
- inverted: true, | |
- extraData: null, | |
- minComposerHeight: MIN_COMPOSER_HEIGHT, | |
- maxComposerHeight: MAX_COMPOSER_HEIGHT, | |
+ messages: [], | |
+ text: undefined, | |
+ placeholder: DEFAULT_PLACEHOLDER, | |
+ messageIdGenerator: () => uuid.v4(), | |
+ user: {}, | |
+ onSend: () => {}, | |
+ locale: null, | |
+ timeFormat: TIME_FORMAT, | |
+ dateFormat: DATE_FORMAT, | |
+ isAnimated: Platform.select({ | |
+ ios: true, | |
+ android: false, | |
+ }), | |
+ loadEarlier: false, | |
+ onLoadEarlier: () => {}, | |
+ isLoadingEarlier: false, | |
+ renderLoading: null, | |
+ renderLoadEarlier: null, | |
+ renderAvatar: undefined, | |
+ showUserAvatar: false, | |
+ onPressAvatar: null, | |
+ renderUsernameOnMessage: false, | |
+ renderAvatarOnTop: false, | |
+ renderBubble: null, | |
+ renderSystemMessage: null, | |
+ onLongPress: null, | |
+ renderMessage: null, | |
+ renderMessageText: null, | |
+ renderMessageImage: null, | |
+ imageProps: {}, | |
+ videoProps: {}, | |
+ lightboxProps: {}, | |
+ textInputProps: {}, | |
+ listViewProps: {}, | |
+ renderCustomView: null, | |
+ renderDay: null, | |
+ renderTime: null, | |
+ renderFooter: null, | |
+ renderChatFooter: null, | |
+ renderInputToolbar: null, | |
+ renderComposer: null, | |
+ renderActions: null, | |
+ renderSend: null, | |
+ renderAccessory: null, | |
+ onPressActionButton: null, | |
+ bottomOffset: 0, | |
+ minInputToolbarHeight: 44, | |
+ keyboardShouldPersistTaps: Platform.select({ | |
+ ios: 'never', | |
+ android: 'always', | |
+ }), | |
+ onInputTextChanged: null, | |
+ maxInputLength: null, | |
+ forceGetKeyboardHeight: false, | |
+ inverted: true, | |
+ extraData: null, | |
+ minComposerHeight: MIN_COMPOSER_HEIGHT, | |
+ maxComposerHeight: MAX_COMPOSER_HEIGHT, | |
}; | |
GiftedChat.propTypes = { | |
- messages: PropTypes.arrayOf(PropTypes.object), | |
- text: PropTypes.string, | |
- initialText: PropTypes.string, | |
- placeholder: PropTypes.string, | |
- messageIdGenerator: PropTypes.func, | |
- user: PropTypes.object, | |
- onSend: PropTypes.func, | |
- locale: PropTypes.string, | |
- timeFormat: PropTypes.string, | |
- dateFormat: PropTypes.string, | |
- isAnimated: PropTypes.bool, | |
- loadEarlier: PropTypes.bool, | |
- onLoadEarlier: PropTypes.func, | |
- isLoadingEarlier: PropTypes.bool, | |
- renderLoading: PropTypes.func, | |
- renderLoadEarlier: PropTypes.func, | |
- renderAvatar: PropTypes.func, | |
- showUserAvatar: PropTypes.bool, | |
- onPressAvatar: PropTypes.func, | |
- renderUsernameOnMessage: PropTypes.bool, | |
- renderAvatarOnTop: PropTypes.bool, | |
- renderBubble: PropTypes.func, | |
- renderSystemMessage: PropTypes.func, | |
- onLongPress: PropTypes.func, | |
- renderMessage: PropTypes.func, | |
- renderMessageText: PropTypes.func, | |
- renderMessageImage: PropTypes.func, | |
- imageProps: PropTypes.object, | |
- videoProps: PropTypes.object, | |
- lightboxProps: PropTypes.object, | |
- renderCustomView: PropTypes.func, | |
- renderDay: PropTypes.func, | |
- renderTime: PropTypes.func, | |
- renderFooter: PropTypes.func, | |
- renderChatFooter: PropTypes.func, | |
- renderInputToolbar: PropTypes.func, | |
- renderComposer: PropTypes.func, | |
- renderActions: PropTypes.func, | |
- renderSend: PropTypes.func, | |
- renderAccessory: PropTypes.func, | |
- onPressActionButton: PropTypes.func, | |
- bottomOffset: PropTypes.number, | |
- minInputToolbarHeight: PropTypes.number, | |
- listViewProps: PropTypes.object, | |
- keyboardShouldPersistTaps: PropTypes.oneOf(['always', 'never', 'handled']), | |
- onInputTextChanged: PropTypes.func, | |
- maxInputLength: PropTypes.number, | |
- forceGetKeyboardHeight: PropTypes.bool, | |
- inverted: PropTypes.bool, | |
- textInputProps: PropTypes.object, | |
- extraData: PropTypes.object, | |
- minComposerHeight: PropTypes.number, | |
- maxComposerHeight: PropTypes.number, | |
- alignTop: PropTypes.bool, | |
+ messages: PropTypes.arrayOf(PropTypes.object), | |
+ text: PropTypes.string, | |
+ initialText: PropTypes.string, | |
+ placeholder: PropTypes.string, | |
+ messageIdGenerator: PropTypes.func, | |
+ user: PropTypes.object, | |
+ onSend: PropTypes.func, | |
+ locale: PropTypes.string, | |
+ timeFormat: PropTypes.string, | |
+ dateFormat: PropTypes.string, | |
+ isAnimated: PropTypes.bool, | |
+ loadEarlier: PropTypes.bool, | |
+ onLoadEarlier: PropTypes.func, | |
+ isLoadingEarlier: PropTypes.bool, | |
+ renderLoading: PropTypes.func, | |
+ renderLoadEarlier: PropTypes.func, | |
+ renderAvatar: PropTypes.func, | |
+ showUserAvatar: PropTypes.bool, | |
+ onPressAvatar: PropTypes.func, | |
+ renderUsernameOnMessage: PropTypes.bool, | |
+ renderAvatarOnTop: PropTypes.bool, | |
+ renderBubble: PropTypes.func, | |
+ renderSystemMessage: PropTypes.func, | |
+ onLongPress: PropTypes.func, | |
+ renderMessage: PropTypes.func, | |
+ renderMessageText: PropTypes.func, | |
+ renderMessageImage: PropTypes.func, | |
+ imageProps: PropTypes.object, | |
+ videoProps: PropTypes.object, | |
+ lightboxProps: PropTypes.object, | |
+ renderCustomView: PropTypes.func, | |
+ renderDay: PropTypes.func, | |
+ renderTime: PropTypes.func, | |
+ renderFooter: PropTypes.func, | |
+ renderChatFooter: PropTypes.func, | |
+ renderInputToolbar: PropTypes.func, | |
+ renderComposer: PropTypes.func, | |
+ renderActions: PropTypes.func, | |
+ renderSend: PropTypes.func, | |
+ renderAccessory: PropTypes.func, | |
+ onPressActionButton: PropTypes.func, | |
+ bottomOffset: PropTypes.number, | |
+ minInputToolbarHeight: PropTypes.number, | |
+ listViewProps: PropTypes.object, | |
+ keyboardShouldPersistTaps: PropTypes.oneOf(['always', 'never', 'handled']), | |
+ onInputTextChanged: PropTypes.func, | |
+ maxInputLength: PropTypes.number, | |
+ forceGetKeyboardHeight: PropTypes.bool, | |
+ inverted: PropTypes.bool, | |
+ textInputProps: PropTypes.object, | |
+ extraData: PropTypes.object, | |
+ minComposerHeight: PropTypes.number, | |
+ maxComposerHeight: PropTypes.number, | |
+ alignTop: PropTypes.bool, | |
}; | |
const styles = StyleSheet.create({ | |
- container: { | |
- flex: 1, | |
- }, | |
- safeArea: { | |
- flex: 1, | |
- }, | |
+ container: { | |
+ flex: 1, | |
+ }, | |
+ safeArea: { | |
+ flex: 1, | |
+ }, | |
}); | |
-export { GiftedChat, Actions, Avatar, Bubble, SystemMessage, MessageImage, MessageText, Composer, Day, InputToolbar, LoadEarlier, Message, MessageContainer, Send, Time, GiftedAvatar, utils, }; | |
-//# sourceMappingURL=GiftedChat.js.map | |
\ No newline at end of file | |
+export { | |
+ GiftedChat, | |
+ Actions, | |
+ Avatar, | |
+ Bubble, | |
+ SystemMessage, | |
+ MessageImage, | |
+ MessageText, | |
+ Composer, | |
+ Day, | |
+ InputToolbar, | |
+ LoadEarlier, | |
+ Message, | |
+ MessageContainer, | |
+ Send, | |
+ Time, | |
+ GiftedAvatar, | |
+ utils, | |
+}; | |
+// # sourceMappingURL=GiftedChat.js.map | |
diff --git a/node_modules/react-native-gifted-chat/lib/InputToolbar.js b/node_modules/react-native-gifted-chat/lib/InputToolbar.js | |
index d3f75d3..36a6611 100644 | |
--- a/node_modules/react-native-gifted-chat/lib/InputToolbar.js | |
+++ b/node_modules/react-native-gifted-chat/lib/InputToolbar.js | |
@@ -23,28 +23,28 @@ const styles = StyleSheet.create({ | |
}, | |
}); | |
export default class InputToolbar extends React.Component { | |
- constructor() { | |
- super(...arguments); | |
- this.state = { | |
- position: 'absolute', | |
- }; | |
- this.keyboardWillShowListener = undefined; | |
- this.keyboardWillHideListener = undefined; | |
- this.keyboardWillShow = () => { | |
- if (this.state.position !== 'relative') { | |
- this.setState({ | |
- position: 'relative', | |
- }); | |
- } | |
- }; | |
- this.keyboardWillHide = () => { | |
- if (this.state.position !== 'absolute') { | |
- this.setState({ | |
- position: 'absolute', | |
- }); | |
- } | |
- }; | |
- } | |
+ // constructor() { | |
+ // super(...arguments); | |
+ // this.state = { | |
+ // position: 'absolute', | |
+ // }; | |
+ // this.keyboardWillShowListener = undefined; | |
+ // this.keyboardWillHideListener = undefined; | |
+ // this.keyboardWillShow = () => { | |
+ // if (this.state.position !== 'relative') { | |
+ // this.setState({ | |
+ // position: 'relative', | |
+ // }); | |
+ // } | |
+ // }; | |
+ // this.keyboardWillHide = () => { | |
+ // if (this.state.position !== 'absolute') { | |
+ // this.setState({ | |
+ // position: 'absolute', | |
+ // }); | |
+ // } | |
+ // }; | |
+ // } | |
componentWillMount() { | |
this.keyboardWillShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); | |
this.keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide); | |
@@ -91,7 +91,7 @@ export default class InputToolbar extends React.Component { | |
return (<View style={[ | |
styles.container, | |
this.props.containerStyle, | |
- { position: this.state.position }, | |
+ // { position: this.state.position }, | |
]}> | |
<View style={[styles.primary, this.props.primaryStyle]}> | |
{this.renderActions()} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment