mirror of
https://github.com/zhigang1992/react-native-gifted-chat.git
synced 2026-01-12 17:42:27 +08:00
Improve perf (#1076)
* feat component perf with scu * fix type on readme * perf remove purecomponent
This commit is contained in:
committed by
GitHub
parent
f872d670bc
commit
502bae7c64
184
README.md
184
README.md
@@ -14,12 +14,11 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/react-native-gifted-chat">
|
||||
<img alt="npm dowloads" src="https://img.shields.io/npm/dm/react-native-gifted-chat.svg"/></a>
|
||||
<img alt="npm downloads" src="https://img.shields.io/npm/dm/react-native-gifted-chat.svg"/></a>
|
||||
<a href="https://www.npmjs.com/package/react-native-gifted-chat"><img alt="npm version" src="https://badge.fury.io/js/react-native-gifted-chat.svg"/></a>
|
||||
<a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/FaridSafi/react-native-gifted-chat.svg" alt="build"></a>
|
||||
<a href="https://reactnative.gallery/FaridSafi/gifted-chat"><img src="https://img.shields.io/badge/reactnative.gallery-%F0%9F%8E%AC-green.svg"/></a>
|
||||
|
||||
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://circleci.com/gh/FaridSafi/react-native-gifted-chat"><img src="https://circleci.com/gh/FaridSafi/react-native-gifted-chat.svg?style=shield" alt="build"></a>
|
||||
@@ -47,33 +46,33 @@
|
||||
|
||||
## Features
|
||||
|
||||
* Fully customizable components
|
||||
* Composer actions (to attach photos, etc.)
|
||||
* Load earlier messages
|
||||
* Copy messages to clipboard
|
||||
* Touchable links using [react-native-parsed-text](https://github.com/taskrabbit/react-native-parsed-text)
|
||||
* Avatar as user's initials
|
||||
* Localized dates
|
||||
* Multiline TextInput
|
||||
* InputToolbar avoiding keyboard
|
||||
* Redux support
|
||||
* System message
|
||||
- Fully customizable components
|
||||
- Composer actions (to attach photos, etc.)
|
||||
- Load earlier messages
|
||||
- Copy messages to clipboard
|
||||
- Touchable links using [react-native-parsed-text](https://github.com/taskrabbit/react-native-parsed-text)
|
||||
- Avatar as user's initials
|
||||
- Localized dates
|
||||
- Multi-line TextInput
|
||||
- InputToolbar avoiding keyboard
|
||||
- Redux support
|
||||
- System message
|
||||
|
||||
## Dependency
|
||||
|
||||
* Use version `0.2.x` for RN `>= 0.44.0`
|
||||
* Use version `0.1.x` for RN `>= 0.40.0`
|
||||
* Use version `0.0.10` for RN `< 0.40.0`
|
||||
- Use version `0.2.x` for RN `>= 0.44.0`
|
||||
- Use version `0.1.x` for RN `>= 0.40.0`
|
||||
- Use version `0.0.10` for RN `< 0.40.0`
|
||||
|
||||
## Installation
|
||||
|
||||
* Using [npm](https://www.npmjs.com/#getting-started): `npm install react-native-gifted-chat --save`
|
||||
* Using [Yarn](https://yarnpkg.com/): `yarn add react-native-gifted-chat`
|
||||
- Using [npm](https://www.npmjs.com/#getting-started): `npm install react-native-gifted-chat --save`
|
||||
- Using [Yarn](https://yarnpkg.com/): `yarn add react-native-gifted-chat`
|
||||
|
||||
## Example
|
||||
|
||||
```jsx
|
||||
import React from 'react';
|
||||
import React from 'react'
|
||||
import { GiftedChat } from 'react-native-gifted-chat'
|
||||
|
||||
class Example extends React.Component {
|
||||
@@ -159,58 +158,58 @@ e.g. System Message
|
||||
|
||||
## Props
|
||||
|
||||
* **`messages`** _(Array)_ - Messages to display
|
||||
* **`text`** _(String)_ - Input text; default is `undefined`, but if specified, it will override GiftedChat's internal state (e.g. for redux; [see notes below](#notes-for-redux))
|
||||
* **`placeholder`** _(String)_ - Placeholder when `text` is empty; default is `'Type a message...'`
|
||||
* **`messageIdGenerator`** _(Function)_ - Generate an id for new messages. Defaults to UUID v4, generated by [uuid](https://github.com/kelektiv/node-uuid)
|
||||
* **`user`** _(Object)_ - User sending the messages: `{ _id, name, avatar }`
|
||||
* **`onSend`** _(Function)_ - Callback when sending a message
|
||||
* **`locale`** _(String)_ - Locale to localize the dates
|
||||
* **`timeFormat`** _(String)_ - Format to use for rendering times; default is `'LT'`
|
||||
* **`dateFormat`** _(String)_ - Format to use for rendering dates; default is `'ll'`
|
||||
* **`isAnimated`** _(Bool)_ - Animates the view when the keyboard appears
|
||||
* **`loadEarlier`** _(Bool)_ - Enables the "Load earlier messages" button
|
||||
* **`onLoadEarlier`** _(Function)_ - Callback when loading earlier messages
|
||||
* **`isLoadingEarlier`** _(Bool)_ - Display an `ActivityIndicator` when loading earlier messages
|
||||
* **`renderLoading`** _(Function)_ - Render a loading view when initializing
|
||||
* **`renderLoadEarlier`** _(Function)_ - Custom "Load earlier messages" button
|
||||
* **`renderAvatar`** _(Function)_ - Custom message avatar; set to `null` to not render any avatar for the message
|
||||
* **`showUserAvatar`** _(Bool)_ - Whether to render an avatar for the current user; default is `false`, only show avatars for other users
|
||||
* **`showAvatarForEveryMessage`** _(Bool)_ - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is `false`
|
||||
* **`onPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is tapped
|
||||
* **`renderAvatarOnTop`** _(Bool)_ - Render the message avatar at the top of consecutive messages, rather than the bottom; default is `false`
|
||||
* **`renderBubble`** _(Function)_ - Custom message bubble
|
||||
* **`renderSystemMessage`** _(Function)_ - Custom system message
|
||||
* **`onLongPress`** _(Function(`context`, `message`))_ - Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see [example using `showActionSheetWithOptions()`](https://github.com/FaridSafi/react-native-gifted-chat/blob/master@%7B2017-09-25%7D/src/Bubble.js#L96-L119))
|
||||
* **`inverted`** _(Bool)_ - Reverses display order of `messages`; default is `true`
|
||||
* **`renderMessage`** _(Function)_ - Custom message container
|
||||
* **`renderMessageText`** _(Function)_ - Custom message text
|
||||
* **`renderMessageImage`** _(Function)_ - Custom message image
|
||||
* **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://facebook.github.io/react-native/docs/image.html) component created by the default `renderMessageImage`
|
||||
* **`videoProps`** _(Object)_ - Extra props to be passed to the [`<Video>`](https://github.com/react-native-community/react-native-video) component created by the default `renderMessageVideo`
|
||||
* **`lightboxProps`** _(Object)_ - Extra props to be passed to the `MessageImage`'s [Lightbox](https://github.com/oblador/react-native-lightbox)
|
||||
* **`renderCustomView`** _(Function)_ - Custom view inside the bubble
|
||||
* **`renderDay`** _(Function)_ - Custom day above a message
|
||||
* **`renderTime`** _(Function)_ - Custom time inside a message
|
||||
* **`renderFooter`** _(Function)_ - Custom footer component on the ListView, e.g. `'User is typing...'`; see [example/App.js](example/App.js) for an example
|
||||
* **`renderChatFooter`** _(Function)_ - Custom component to render below the MessageContainer (separate from the ListView)
|
||||
* **`renderInputToolbar`** _(Function)_ - Custom message composer container
|
||||
* **`renderComposer`** _(Function)_ - Custom text input message composer
|
||||
* **`renderActions`** _(Function)_ - Custom action button on the left of the message composer
|
||||
* **`renderSend`** _(Function)_ - Custom send button; you can pass children to the original `Send` component quite easily, for example to use a custom icon ([example](https://github.com/FaridSafi/react-native-gifted-chat/pull/487))
|
||||
* **`renderAccessory`** _(Function)_ - Custom second line of actions below the message composer
|
||||
* **`onPressActionButton`** _(Function)_ - Callback when the Action button is pressed (if set, the default `actionSheet` will not be used)
|
||||
* **`bottomOffset`** _(Integer)_ - Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar)
|
||||
* **`minInputToolbarHeight`** _(Integer)_ - Minimum height of the input toolbar; default is `44`
|
||||
* **`listViewProps`** _(Object)_ - Extra props to be passed to the messages [`<ListView>`](https://facebook.github.io/react-native/docs/listview.html); some props can't be overridden, see the code in `MessageContainer.render()` for details
|
||||
* **`textInputProps`** _(Object)_ - Extra props to be passed to the [`<TextInput>`](https://facebook.github.io/react-native/docs/textinput.html)
|
||||
* **`keyboardShouldPersistTaps`** _(Enum)_ - Determines whether the keyboard should stay visible after a tap; see [`<ScrollView>`](https://facebook.github.io/react-native/docs/scrollview.html) docs
|
||||
* **`onInputTextChanged`** _(Function)_ - Callback when the input text changes
|
||||
* **`maxInputLength`** _(Integer)_ - Max message composer TextInput length
|
||||
* **`parsePatterns`** _(Function)_ - Custom parse patterns for [react-native-parsed-text](https://github.com/taskrabbit/react-native-parsed-text) used to linkify message content (like URLs and phone numbers), e.g.:
|
||||
* **`extraData`** _(Object)_ - Extra props for re-rendering flatlist on demand. This will be useful for rendering footer etc.
|
||||
* **`minComposerHeight`** _(Object)_ - Custom min height of the composer.
|
||||
* **`maxComposerHeight`** _(Object)_ - Custom max height of the composer.
|
||||
- **`messages`** _(Array)_ - Messages to display
|
||||
- **`text`** _(String)_ - Input text; default is `undefined`, but if specified, it will override GiftedChat's internal state (e.g. for redux; [see notes below](#notes-for-redux))
|
||||
- **`placeholder`** _(String)_ - Placeholder when `text` is empty; default is `'Type a message...'`
|
||||
- **`messageIdGenerator`** _(Function)_ - Generate an id for new messages. Defaults to UUID v4, generated by [uuid](https://github.com/kelektiv/node-uuid)
|
||||
- **`user`** _(Object)_ - User sending the messages: `{ _id, name, avatar }`
|
||||
- **`onSend`** _(Function)_ - Callback when sending a message
|
||||
- **`locale`** _(String)_ - Locale to localize the dates
|
||||
- **`timeFormat`** _(String)_ - Format to use for rendering times; default is `'LT'`
|
||||
- **`dateFormat`** _(String)_ - Format to use for rendering dates; default is `'ll'`
|
||||
- **`isAnimated`** _(Bool)_ - Animates the view when the keyboard appears
|
||||
- **`loadEarlier`** _(Bool)_ - Enables the "Load earlier messages" button
|
||||
- **`onLoadEarlier`** _(Function)_ - Callback when loading earlier messages
|
||||
- **`isLoadingEarlier`** _(Bool)_ - Display an `ActivityIndicator` when loading earlier messages
|
||||
- **`renderLoading`** _(Function)_ - Render a loading view when initializing
|
||||
- **`renderLoadEarlier`** _(Function)_ - Custom "Load earlier messages" button
|
||||
- **`renderAvatar`** _(Function)_ - Custom message avatar; set to `null` to not render any avatar for the message
|
||||
- **`showUserAvatar`** _(Bool)_ - Whether to render an avatar for the current user; default is `false`, only show avatars for other users
|
||||
- **`showAvatarForEveryMessage`** _(Bool)_ - When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is `false`
|
||||
- **`onPressAvatar`** _(Function(`user`))_ - Callback when a message avatar is tapped
|
||||
- **`renderAvatarOnTop`** _(Bool)_ - Render the message avatar at the top of consecutive messages, rather than the bottom; default is `false`
|
||||
- **`renderBubble`** _(Function)_ - Custom message bubble
|
||||
- **`renderSystemMessage`** _(Function)_ - Custom system message
|
||||
- **`onLongPress`** _(Function(`context`, `message`))_ - Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see [example using `showActionSheetWithOptions()`](https://github.com/FaridSafi/react-native-gifted-chat/blob/master@%7B2017-09-25%7D/src/Bubble.js#L96-L119))
|
||||
- **`inverted`** _(Bool)_ - Reverses display order of `messages`; default is `true`
|
||||
- **`renderMessage`** _(Function)_ - Custom message container
|
||||
- **`renderMessageText`** _(Function)_ - Custom message text
|
||||
- **`renderMessageImage`** _(Function)_ - Custom message image
|
||||
- **`imageProps`** _(Object)_ - Extra props to be passed to the [`<Image>`](https://facebook.github.io/react-native/docs/image.html) component created by the default `renderMessageImage`
|
||||
- **`videoProps`** _(Object)_ - Extra props to be passed to the [`<Video>`](https://github.com/react-native-community/react-native-video) component created by the default `renderMessageVideo`
|
||||
- **`lightboxProps`** _(Object)_ - Extra props to be passed to the `MessageImage`'s [Lightbox](https://github.com/oblador/react-native-lightbox)
|
||||
- **`renderCustomView`** _(Function)_ - Custom view inside the bubble
|
||||
- **`renderDay`** _(Function)_ - Custom day above a message
|
||||
- **`renderTime`** _(Function)_ - Custom time inside a message
|
||||
- **`renderFooter`** _(Function)_ - Custom footer component on the ListView, e.g. `'User is typing...'`; see [example/App.js](example/App.js) for an example
|
||||
- **`renderChatFooter`** _(Function)_ - Custom component to render below the MessageContainer (separate from the ListView)
|
||||
- **`renderInputToolbar`** _(Function)_ - Custom message composer container
|
||||
- **`renderComposer`** _(Function)_ - Custom text input message composer
|
||||
- **`renderActions`** _(Function)_ - Custom action button on the left of the message composer
|
||||
- **`renderSend`** _(Function)_ - Custom send button; you can pass children to the original `Send` component quite easily, for example to use a custom icon ([example](https://github.com/FaridSafi/react-native-gifted-chat/pull/487))
|
||||
- **`renderAccessory`** _(Function)_ - Custom second line of actions below the message composer
|
||||
- **`onPressActionButton`** _(Function)_ - Callback when the Action button is pressed (if set, the default `actionSheet` will not be used)
|
||||
- **`bottomOffset`** _(Integer)_ - Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar)
|
||||
- **`minInputToolbarHeight`** _(Integer)_ - Minimum height of the input toolbar; default is `44`
|
||||
- **`listViewProps`** _(Object)_ - Extra props to be passed to the messages [`<ListView>`](https://facebook.github.io/react-native/docs/listview.html); some props can't be overridden, see the code in `MessageContainer.render()` for details
|
||||
- **`textInputProps`** _(Object)_ - Extra props to be passed to the [`<TextInput>`](https://facebook.github.io/react-native/docs/textinput.html)
|
||||
- **`keyboardShouldPersistTaps`** _(Enum)_ - Determines whether the keyboard should stay visible after a tap; see [`<ScrollView>`](https://facebook.github.io/react-native/docs/scrollview.html) docs
|
||||
- **`onInputTextChanged`** _(Function)_ - Callback when the input text changes
|
||||
- **`maxInputLength`** _(Integer)_ - Max message composer TextInput length
|
||||
- **`parsePatterns`** _(Function)_ - Custom parse patterns for [react-native-parsed-text](https://github.com/taskrabbit/react-native-parsed-text) used to linkify message content (like URLs and phone numbers), e.g.:
|
||||
- **`extraData`** _(Object)_ - Extra props for re-rendering FlatList on demand. This will be useful for rendering footer etc.
|
||||
- **`minComposerHeight`** _(Object)_ - Custom min height of the composer.
|
||||
- **`maxComposerHeight`** _(Object)_ - Custom max height of the composer.
|
||||
|
||||
```js
|
||||
<GiftedChat
|
||||
@@ -223,7 +222,7 @@ e.g. System Message
|
||||
|
||||
## Imperative methods
|
||||
|
||||
* `focusTextInput()` - Open the keyboard and focus the text input box
|
||||
- `focusTextInput()` - Open the keyboard and focus the text input box
|
||||
|
||||
## Notes for [Redux](https://github.com/reactjs/redux)
|
||||
|
||||
@@ -245,7 +244,7 @@ simply implement `onInputTextChanged` to receive typing events and reset events
|
||||
|
||||
If you are using Create React Native App / Expo, no Android specific installation steps are required -- you can skip this section. Otherwise we recommend modifying your project configuration as follows.
|
||||
|
||||
* Make sure you have `android:windowSoftInputMode="adjustResize"` in your `AndroidManifest.xml`:
|
||||
- Make sure you have `android:windowSoftInputMode="adjustResize"` in your `AndroidManifest.xml`:
|
||||
|
||||
```xml
|
||||
<activity
|
||||
@@ -254,11 +253,14 @@ If you are using Create React Native App / Expo, no Android specific installatio
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
```
|
||||
* For **Expo**, there are almost 2 solutions to fix it:
|
||||
* adding KeyboardAvoidingView after GiftedChat [see this comment](https://github.com/FaridSafi/react-native-gifted-chat/issues/461#issuecomment-314858092)
|
||||
* adding an opaque background status bar on app.json https://docs.expo.io/versions/latest/guides/configuration.html#androidstatusbar
|
||||
|
||||
* If you plan to use `GiftedChat` inside a `Modal`, see [#200](https://github.com/FaridSafi/react-native-gifted-chat/issues/200).
|
||||
- For **Expo**, there are almost 2 solutions to fix it:
|
||||
|
||||
- adding KeyboardAvoidingView after GiftedChat [see this comment](https://github.com/FaridSafi/react-native-gifted-chat/issues/461#issuecomment-314858092)
|
||||
- adding an opaque background status bar on app.json https://docs.expo.io/versions/latest/guides/configuration.html#androidstatusbar
|
||||
|
||||
- If you plan to use `GiftedChat` inside a `Modal`, see [#200](https://github.com/FaridSafi/react-native-gifted-chat/issues/200).
|
||||
|
||||
## Notes for local development
|
||||
|
||||
You can use [`wml`](https://github.com/wix/wml) to keep the example app in sync
|
||||
@@ -275,19 +277,19 @@ If you have any issues, you can clear your watches using `watchman watch-del-all
|
||||
|
||||
## Questions
|
||||
|
||||
* [How can I set Bubble color for each user?](https://github.com/FaridSafi/react-native-gifted-chat/issues/672)
|
||||
* [How can I pass style props to InputToolbar design and customize it's color and other styles properties?](https://github.com/FaridSafi/react-native-gifted-chat/issues/662)
|
||||
* [How can I change the color of the message box?](https://github.com/FaridSafi/react-native-gifted-chat/issues/640)
|
||||
* [Is there a way to manually dismiss the keyboard?](https://github.com/FaridSafi/react-native-gifted-chat/issues/647)
|
||||
* [I want to implement a popover that pops right after clicking on a specific avatar,
|
||||
- [How can I set Bubble color for each user?](https://github.com/FaridSafi/react-native-gifted-chat/issues/672)
|
||||
- [How can I pass style props to InputToolbar design and customize it's color and other styles properties?](https://github.com/FaridSafi/react-native-gifted-chat/issues/662)
|
||||
- [How can I change the color of the message box?](https://github.com/FaridSafi/react-native-gifted-chat/issues/640)
|
||||
- [Is there a way to manually dismiss the keyboard?](https://github.com/FaridSafi/react-native-gifted-chat/issues/647)
|
||||
- [I want to implement a popover that pops right after clicking on a specific avatar,
|
||||
what is the best implementation in this case and how?](https://github.com/FaridSafi/react-native-gifted-chat/issues/660)
|
||||
* [Why Textinput is hidden on Android?](https://github.com/FaridSafi/react-native-gifted-chat/issues/680#issuecomment-359699364)
|
||||
* [How to use renderLoading?](https://github.com/FaridSafi/react-native-gifted-chat/issues/298)
|
||||
* [Can I use MySql to save the message?](https://github.com/FaridSafi/react-native-gifted-chat/issues/738)
|
||||
- [Why TextInput is hidden on Android?](https://github.com/FaridSafi/react-native-gifted-chat/issues/680#issuecomment-359699364)
|
||||
- [How to use renderLoading?](https://github.com/FaridSafi/react-native-gifted-chat/issues/298)
|
||||
- [Can I use MySql to save the message?](https://github.com/FaridSafi/react-native-gifted-chat/issues/738)
|
||||
|
||||
## License
|
||||
|
||||
* [MIT](LICENSE)
|
||||
- [MIT](LICENSE)
|
||||
|
||||
## Author
|
||||
|
||||
@@ -295,10 +297,10 @@ Feel free to ask me questions on Twitter [@FaridSafi](https://www.twitter.com/Fa
|
||||
|
||||
## Contributors
|
||||
|
||||
* Kevin Cooper [cooperka](https://github.com/cooperka)
|
||||
* Kfir Golan [kfiroo](https://github.com/kfiroo)
|
||||
* Bruno Cascio [brunocascio](https://github.com/brunocascio)
|
||||
* Xavier Carpentier [xcarpentier](https://github.com/xcarpentier)
|
||||
* [more](https://github.com/FaridSafi/react-native-gifted-chat/graphs/contributors)
|
||||
- Kevin Cooper [cooperka](https://github.com/cooperka)
|
||||
- Kfir Golan [kfiroo](https://github.com/kfiroo)
|
||||
- Bruno Cascio [brunocascio](https://github.com/brunocascio)
|
||||
- Xavier Carpentier [xcarpentier](https://github.com/xcarpentier)
|
||||
- [more](https://github.com/FaridSafi/react-native-gifted-chat/graphs/contributors)
|
||||
|
||||
<img src="https://api.keen.io/3.0/projects/5ae31b61c9e77c0001cc2093/events/pageviews?api_key=55301C3E5BAB217E90A5867113C02506CE20385CD6F4C9C1CCDD4671B1A9DE374C3DF9DEF70C0BB3F5A9C5CA4CB1CCCFAF25FC3ED9CF63FB83102456A6881EFBAECD1C7D9718EE5402752DD8F6FA2DEC4D844BCB17FE6262570DB447D9A8CED2&data=eyJ0aXRsZSI6ICJnYyJ9" />
|
||||
|
||||
@@ -35,7 +35,7 @@ const styles = {
|
||||
}),
|
||||
};
|
||||
|
||||
export default class Avatar extends React.PureComponent {
|
||||
export default class Avatar extends React.Component {
|
||||
|
||||
renderAvatar() {
|
||||
if (this.props.renderAvatar) {
|
||||
|
||||
@@ -6,20 +6,16 @@ import { Text, Clipboard, StyleSheet, TouchableWithoutFeedback, View, ViewPropTy
|
||||
|
||||
import MessageText from './MessageText';
|
||||
import MessageImage from './MessageImage';
|
||||
import MessageVideo from './MessageVideo';
|
||||
|
||||
import Time from './Time';
|
||||
import Color from './Color';
|
||||
|
||||
import { isSameUser, isSameDay } from './utils';
|
||||
import MessageVideo from './MessageVideo';
|
||||
|
||||
export default class Bubble extends React.PureComponent {
|
||||
export default class Bubble extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onLongPress = this.onLongPress.bind(this);
|
||||
}
|
||||
|
||||
onLongPress() {
|
||||
onLongPress = () => {
|
||||
if (this.props.onLongPress) {
|
||||
this.props.onLongPress(this.context, this.props.currentMessage);
|
||||
} else if (this.props.currentMessage.text) {
|
||||
@@ -41,7 +37,7 @@ export default class Bubble extends React.PureComponent {
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleBubbleToNext() {
|
||||
if (
|
||||
@@ -141,9 +137,7 @@ export default class Bubble extends React.PureComponent {
|
||||
}
|
||||
return (
|
||||
<View style={styles.usernameView}>
|
||||
<Text style={[styles.username, this.props.usernameStyle]}>
|
||||
~ {currentMessage.user.name}
|
||||
</Text>
|
||||
<Text style={[styles.username, this.props.usernameStyle]}>~ {currentMessage.user.name}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,8 @@ import { Image, Text, TouchableOpacity, View } from 'react-native';
|
||||
import Color from './Color';
|
||||
|
||||
const { carrot, emerald, peterRiver, wisteria, alizarin, turquoise, midnightBlue } = Color;
|
||||
// TODO
|
||||
// 3 words name initials
|
||||
// handle only alpha numeric chars
|
||||
|
||||
export default class GiftedAvatar extends React.PureComponent {
|
||||
export default class GiftedAvatar extends React.Component {
|
||||
setAvatarColor() {
|
||||
const userName = this.props.user.name || '';
|
||||
const name = userName.toUpperCase().split(' ');
|
||||
@@ -38,19 +35,9 @@ export default class GiftedAvatar extends React.PureComponent {
|
||||
if (typeof this.props.user.avatar === 'function') {
|
||||
return this.props.user.avatar();
|
||||
} else if (typeof this.props.user.avatar === 'string') {
|
||||
return (
|
||||
<Image
|
||||
source={{ uri: this.props.user.avatar }}
|
||||
style={[styles.avatarStyle, this.props.avatarStyle]}
|
||||
/>
|
||||
);
|
||||
return <Image source={{ uri: this.props.user.avatar }} style={[styles.avatarStyle, this.props.avatarStyle]} />;
|
||||
} else if (typeof this.props.user.avatar === 'number') {
|
||||
return (
|
||||
<Image
|
||||
source={this.props.user.avatar}
|
||||
style={[styles.avatarStyle, this.props.avatarStyle]}
|
||||
/>
|
||||
);
|
||||
return <Image source={this.props.user.avatar} style={[styles.avatarStyle, this.props.avatarStyle]} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -32,16 +32,30 @@ const styles = {
|
||||
}),
|
||||
};
|
||||
|
||||
export default class Message extends React.PureComponent {
|
||||
export default class Message extends React.Component {
|
||||
|
||||
getInnerComponentProps() {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const next = nextProps.currentMessage;
|
||||
const current = this.props.currentMessage;
|
||||
return (
|
||||
next.send !== current.send ||
|
||||
next.received !== current.received ||
|
||||
next.pending !== current.pending ||
|
||||
next.createdAt !== current.createdAt ||
|
||||
next.text !== current.text ||
|
||||
next.image !== current.image ||
|
||||
next.video !== current.video
|
||||
);
|
||||
}
|
||||
|
||||
getInnerComponentProps = () => {
|
||||
const { containerStyle, ...props } = this.props;
|
||||
return {
|
||||
...props,
|
||||
isSameUser,
|
||||
isSameDay,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
renderDay() {
|
||||
if (this.props.currentMessage.createdAt) {
|
||||
|
||||
@@ -15,46 +15,47 @@ import { FlatList, View, StyleSheet, Keyboard } from 'react-native';
|
||||
import LoadEarlier from './LoadEarlier';
|
||||
import Message from './Message';
|
||||
|
||||
export default class MessageContainer extends React.PureComponent {
|
||||
export default class MessageContainer extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.renderRow = this.renderRow.bind(this);
|
||||
this.renderFooter = this.renderFooter.bind(this);
|
||||
this.renderLoadEarlier = this.renderLoadEarlier.bind(this);
|
||||
this.renderHeaderWrapper = this.renderHeaderWrapper.bind(this);
|
||||
this.attachKeyboardListeners = this.attachKeyboardListeners.bind(this);
|
||||
this.detatchKeyboardListeners = this.detatchKeyboardListeners.bind(this);
|
||||
|
||||
if (props.messages.length === 0) {
|
||||
this.attachKeyboardListeners(props);
|
||||
componentDidMount() {
|
||||
if (this.props.messages.length === 0) {
|
||||
this.attachKeyboardListeners();
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const next = nextProps.messages;
|
||||
const current = this.props.messages;
|
||||
return (
|
||||
next.length !== current.length || next.extraData !== current.extraData || next.loadEarlier !== current.loadEarlier
|
||||
);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.messages.length === 0 && nextProps.messages.length > 0) {
|
||||
this.detatchKeyboardListeners();
|
||||
this.detachKeyboardListeners();
|
||||
} else if (this.props.messages.length > 0 && nextProps.messages.length === 0) {
|
||||
this.attachKeyboardListeners(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
attachKeyboardListeners(props) {
|
||||
Keyboard.addListener('keyboardWillShow', props.invertibleScrollViewProps.onKeyboardWillShow);
|
||||
Keyboard.addListener('keyboardDidShow', props.invertibleScrollViewProps.onKeyboardDidShow);
|
||||
Keyboard.addListener('keyboardWillHide', props.invertibleScrollViewProps.onKeyboardWillHide);
|
||||
Keyboard.addListener('keyboardDidHide', props.invertibleScrollViewProps.onKeyboardDidHide);
|
||||
}
|
||||
attachKeyboardListeners = () => {
|
||||
const { invertibleScrollViewProps: invertibleProps } = this.props;
|
||||
Keyboard.addListener('keyboardWillShow', invertibleProps.onKeyboardWillShow);
|
||||
Keyboard.addListener('keyboardDidShow', invertibleProps.onKeyboardDidShow);
|
||||
Keyboard.addListener('keyboardWillHide', invertibleProps.onKeyboardWillHide);
|
||||
Keyboard.addListener('keyboardDidHide', invertibleProps.onKeyboardDidHide);
|
||||
};
|
||||
|
||||
detatchKeyboardListeners() {
|
||||
Keyboard.removeListener('keyboardWillShow', this.props.invertibleScrollViewProps.onKeyboardWillShow);
|
||||
Keyboard.removeListener('keyboardDidShow', this.props.invertibleScrollViewProps.onKeyboardDidShow);
|
||||
Keyboard.removeListener('keyboardWillHide', this.props.invertibleScrollViewProps.onKeyboardWillHide);
|
||||
Keyboard.removeListener('keyboardDidHide', this.props.invertibleScrollViewProps.onKeyboardDidHide);
|
||||
}
|
||||
detachKeyboardListeners = () => {
|
||||
const { invertibleScrollViewProps: invertibleProps } = this.props;
|
||||
Keyboard.removeListener('keyboardWillShow', invertibleProps.onKeyboardWillShow);
|
||||
Keyboard.removeListener('keyboardDidShow', invertibleProps.onKeyboardDidShow);
|
||||
Keyboard.removeListener('keyboardWillHide', invertibleProps.onKeyboardWillHide);
|
||||
Keyboard.removeListener('keyboardDidHide', invertibleProps.onKeyboardDidHide);
|
||||
};
|
||||
|
||||
renderFooter() {
|
||||
renderFooter = () => {
|
||||
if (this.props.renderFooter) {
|
||||
const footerProps = {
|
||||
...this.props,
|
||||
@@ -62,9 +63,9 @@ export default class MessageContainer extends React.PureComponent {
|
||||
return this.props.renderFooter(footerProps);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
renderLoadEarlier() {
|
||||
renderLoadEarlier = () => {
|
||||
if (this.props.loadEarlier === true) {
|
||||
const loadEarlierProps = {
|
||||
...this.props,
|
||||
@@ -75,15 +76,15 @@ export default class MessageContainer extends React.PureComponent {
|
||||
return <LoadEarlier {...loadEarlierProps} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
scrollTo(options) {
|
||||
if (this.flatListRef) {
|
||||
if (this.flatListRef && options) {
|
||||
this.flatListRef.scrollToOffset(options);
|
||||
}
|
||||
}
|
||||
|
||||
renderRow({ item, index }) {
|
||||
renderRow = ({ item, index }) => {
|
||||
if (!item._id && item._id !== 0) {
|
||||
console.warn('GiftedChat: `_id` is missing for message', JSON.stringify(item));
|
||||
}
|
||||
@@ -110,13 +111,11 @@ export default class MessageContainer extends React.PureComponent {
|
||||
return this.props.renderMessage(messageProps);
|
||||
}
|
||||
return <Message {...messageProps} />;
|
||||
}
|
||||
};
|
||||
|
||||
renderHeaderWrapper() {
|
||||
return <View style={styles.headerWrapper}>{this.renderLoadEarlier()}</View>;
|
||||
}
|
||||
renderHeaderWrapper = () => <View style={styles.headerWrapper}>{this.renderLoadEarlier()}</View>;
|
||||
|
||||
keyExtractor = (item) => `${item._id}`
|
||||
keyExtractor = (item) => `${item._id}`;
|
||||
|
||||
render() {
|
||||
if (this.props.messages.length === 0) {
|
||||
@@ -184,6 +183,6 @@ MessageContainer.propTypes = {
|
||||
listViewProps: PropTypes.object,
|
||||
inverted: PropTypes.bool,
|
||||
loadEarlier: PropTypes.bool,
|
||||
invertibleScrollViewProps: PropTypes.object, // TODO: support or not?
|
||||
invertibleScrollViewProps: PropTypes.object,
|
||||
extraData: PropTypes.object,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user