-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Modified for FlatList #629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
1d9ca95
11d91ad
10b8e6a
33dc31f
6aa5c86
e177c39
ca4c700
7157e8e
6a7c4bd
528aa0e
45f3763
8efd338
1518e21
28cb467
5b67203
fd63b02
43e30a6
6dff834
aefde5c
961c5d8
e5f0cb2
3f09d38
4571dda
ce91bf3
587319e
1cf028d
da1cf48
ca47d62
20d8bd0
8fe384a
9745e81
0c046de
3c38612
ebe5a62
37762b0
163f731
7136a60
86d90e9
da43d5d
0ddacde
6ea779b
940ff59
c0281d5
5e94773
e054648
de89d2c
ed765b4
86046e3
349a4a0
4def71f
d50392a
806b0de
f7f99b2
f877a96
7538d4a
14562a1
edf8fff
a476408
68a0c3c
b388d9f
9fe28b5
fd3bfef
eec38d8
ee21489
6358a14
0ca7358
483d288
36ca1a3
31c3bde
142055a
19069ce
82d9329
cbd70c2
07ad31b
1c60140
3b0fdd4
907205f
e281b8a
2146795
a72daee
db937d0
22072ea
1ea1775
8ff8f3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,13 +2,12 @@ import PropTypes from 'prop-types'; | |
| import React from 'react'; | ||
|
|
||
| import { | ||
| ListView, | ||
| FlatList, | ||
| View, | ||
| StyleSheet, | ||
| } from 'react-native'; | ||
|
|
||
| import shallowequal from 'shallowequal'; | ||
| import InvertibleScrollView from 'react-native-invertible-scroll-view'; | ||
| import md5 from 'md5'; | ||
| import LoadEarlier from './LoadEarlier'; | ||
| import Message from './Message'; | ||
|
|
@@ -20,37 +19,22 @@ export default class MessageContainer extends React.Component { | |
| this.renderRow = this.renderRow.bind(this); | ||
| this.renderFooter = this.renderFooter.bind(this); | ||
| this.renderLoadEarlier = this.renderLoadEarlier.bind(this); | ||
| this.renderScrollComponent = this.renderScrollComponent.bind(this); | ||
|
|
||
| const dataSource = new ListView.DataSource({ | ||
| rowHasChanged: (r1, r2) => { | ||
| return r1.hash !== r2.hash; | ||
| } | ||
| }); | ||
|
|
||
| const messagesData = this.prepareMessages(props.messages); | ||
| this.state = { | ||
| dataSource: dataSource.cloneWithRows(messagesData.blob, messagesData.keys) | ||
| }; | ||
| messagesData: this.prepareMessages(props.messages) | ||
| }; | ||
| } | ||
|
|
||
| prepareMessages(messages) { | ||
| return { | ||
| keys: messages.map(m => m._id), | ||
| blob: messages.reduce((o, m, i) => { | ||
| const previousMessage = messages[i + 1] || {}; | ||
| const nextMessage = messages[i - 1] || {}; | ||
| // add next and previous messages to hash to ensure updates | ||
| const toHash = JSON.stringify(m) + previousMessage._id + nextMessage._id; | ||
| o[m._id] = { | ||
| ...m, | ||
| previousMessage, | ||
| nextMessage, | ||
| hash: md5(toHash) | ||
| }; | ||
| return o; | ||
| }, {}) | ||
| }; | ||
| return output = messages.reduce((o,m,i) => { | ||
| const previousMessage = messages[i + 1] || {} | ||
| const nextMessage = messages[i - 1] || {} | ||
| o.push( { | ||
| ...m, | ||
| previousMessage, | ||
| nextMessage | ||
| }) | ||
| return o | ||
| },[]) | ||
| } | ||
|
|
||
| shouldComponentUpdate(nextProps, nextState) { | ||
|
|
@@ -67,10 +51,9 @@ export default class MessageContainer extends React.Component { | |
| if (this.props.messages === nextProps.messages) { | ||
| return; | ||
| } | ||
| const messagesData = this.prepareMessages(nextProps.messages); | ||
| this.setState({ | ||
| dataSource: this.state.dataSource.cloneWithRows(messagesData.blob, messagesData.keys) | ||
| }); | ||
| messagesData: this.prepareMessages(nextProps.messages) | ||
|
||
| }) | ||
| } | ||
|
|
||
| renderFooter() { | ||
|
|
@@ -99,66 +82,68 @@ export default class MessageContainer extends React.Component { | |
| } | ||
|
|
||
| scrollTo(options) { | ||
| this._invertibleScrollViewRef.scrollTo(options); | ||
| this.refs.flatListRef.scrollToOffset(options) | ||
| } | ||
|
|
||
| renderRow(message, sectionId, rowId) { | ||
| if (!message._id && message._id !== 0) { | ||
| console.warn('GiftedChat: `_id` is missing for message', JSON.stringify(message)); | ||
| renderRow({item,index}) { | ||
| if (!item._id && item._id !== 0) { | ||
| console.warn('GiftedChat: `_id` is missing for message', JSON.stringify(item)); | ||
| } | ||
| if (!message.user) { | ||
| if (!message.system) { | ||
| console.warn("GiftedChat: `user` is missing for message", JSON.stringify(message)); | ||
| if (!item.user) { | ||
| if (!item.system) { | ||
| console.warn("GiftedChat: `user` is missing for message", JSON.stringify(item)); | ||
| } | ||
| message.user = {}; | ||
| item.user = {}; | ||
| } | ||
|
|
||
| const messageProps = { | ||
| ...this.props, | ||
| key: message._id, | ||
| currentMessage: message, | ||
| previousMessage: message.previousMessage, | ||
| nextMessage: message.nextMessage, | ||
| position: message.user._id === this.props.user._id ? 'right' : 'left', | ||
| key: item._id, | ||
| currentMessage: item, | ||
| previousMessage: item.previousMessage, | ||
| nextMessage: item.nextMessage, | ||
| position: item.user._id === this.props.user._id ? 'right' : 'left', | ||
| }; | ||
|
|
||
| if (this.props.renderMessage) { | ||
| return this.props.renderMessage(messageProps); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it on purpose that this is outside of the |
||
| } | ||
| return <Message {...messageProps}/>; | ||
| } | ||
|
|
||
| renderScrollComponent(props) { | ||
| const invertibleScrollViewProps = this.props.invertibleScrollViewProps; | ||
| return ( | ||
| <InvertibleScrollView | ||
| {...props} | ||
| {...invertibleScrollViewProps} | ||
| ref={component => this._invertibleScrollViewRef = component} | ||
| /> | ||
| ); | ||
| <View style={{ transform: [{ scaleY: -1 },{perspective: 1280}]}}> | ||
| <Message {...messageProps}/> | ||
| </View> | ||
| ) | ||
| } | ||
|
|
||
| renderHeaderWrapper = () => { | ||
| return <View style={{ flex: 1, transform: [{ scaleY: -1 },{perspective: 1280}] }}>{this.renderLoadEarlier()}</View>; | ||
| }; | ||
|
|
||
| _keyExtractor = (item, index) => item._id+" "+index | ||
|
|
||
| render() { | ||
| return ( | ||
| <View | ||
| ref='container' | ||
| style={styles.container} | ||
| > | ||
| <ListView | ||
| <FlatList | ||
| enableEmptySections={true} | ||
| automaticallyAdjustContentInsets={false} | ||
| initialListSize={20} | ||
| pageSize={20} | ||
|
|
||
| ref='flatListRef' | ||
| keyExtractor={this._keyExtractor} | ||
| {...this.props.listViewProps} | ||
|
|
||
| dataSource={this.state.dataSource} | ||
| data={this.state.messagesData} | ||
|
|
||
| renderRow={this.renderRow} | ||
| renderItem={this.renderRow} | ||
| renderHeader={this.renderFooter} | ||
| renderFooter={this.renderLoadEarlier} | ||
| renderScrollComponent={this.renderScrollComponent} | ||
| renderFooter={this.renderLoadEarlier()} | ||
| style={{transform: [{scaleY: -1 },{perspective: 1280}]}} | ||
|
||
| {...this.props.invertibleScrollViewProps} | ||
| ListFooterComponent={this.renderHeaderWrapper} | ||
| /> | ||
| </View> | ||
| ); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two small questions here:
It seems to me this is a lot simpler done using
.map, maybe even more performant? (Dunno if that even matters here)Because you merge previousMessage and nextMessage props onto the existing message, that message will be "invalidated" when matching it against existing messages (causing PureComponent or shouldComponentUpdate to always see change). I'd recommend setting
{ currentMessage, previousMessage, nextMessage }and properly usingitem.currentMessageinstead of justitemin https://github.com/FaridSafi/react-native-gifted-chat/pull/629/files#diff-bd8395a0a94eca8b61a34ec66f8a605cR102It might be that I miss something why this is necessary, let me know :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About the second one, I see that Message isn't PureComponent yet, but I think it is still good to these optimisations already, if we want Message to be an effective PureComponent later ;)
https://github.com/gavin-gmlab/react-native-gifted-chat/blob/33dc31f41d29be98e441c4b27ad74e453b9801b5/src/Message.js#L16