Skip to content

Instantly share code, notes, and snippets.

@terrysahaidak
Created February 13, 2016 03:11
Show Gist options
  • Save terrysahaidak/188591082292ca674462 to your computer and use it in GitHub Desktop.
Save terrysahaidak/188591082292ca674462 to your computer and use it in GitHub Desktop.
import React, {
Component, StyleSheet, PropTypes, Text, View, TouchableOpacity, ListView, Animated
} from 'react-native';
import _ from 'lodash'
import InvertibleScrollView from 'react-native-invertible-scroll-view'
import Message from './Message'
export default class MessagesListView extends Component {
constructor(props) {
super(props)
this.initLoad = this.initLoad.bind(this)
this.appendNewerMessages = this.appendNewerMessages.bind(this)
this.prependOldestMessages = this.prependOldestMessages.bind(this)
this.renderListView = this.renderListView.bind(this)
this.onEndReached = this.onEndReached.bind(this)
this.onHasNoMore = this.onHasNoMore.bind(this)
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
this._data = []
this._rowIds = []
this.state = ({
dataSource: ds.cloneWithRows([]),
noMessages: false,
initialLoading: true,
oldestMessageId: null
})
}
componentDidMount() {
}
shouldComponentUpdate(nextProps, nextState) {
debugger
if (_.isEqual(nextProps.messages.fetchHistory, this.props.messages.fetchHistory)) {
return false
} else {
return true
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.loading) return
const {map, ids, fetchHistory, incoming} = nextProps.messages
if (ids.length == 0) {
this.setState({noMessages: true})
return
}
if (nextProps.activeRoom !== this.props.activeRoom &&
this.props.messages.fetchHistory !== nextProps.messages.fetchHistory) {
const times = (ids.length > 50) ? 50 : ids.length
const messages = _.times(times, n => map[ids[n]])
this.initLoad(messages)
}
if (!nextProps.messages.hasMore) {
this.onHasNoMore()
}
if (this.state.initialLoading) {
const times = (ids.length > 50) ? 50 : ids.length
const messages = _.times(times, n => map[ids[n]])
this.initLoad(messages)
} else if (!_.isEqual(fetchHistory, this.props.messages.fetchHistory)) {
this.prependOldestMessages(fetchHistory)
}
}
initLoad(messages) {
messages.reverse()
let rowId = null
this._data = []
this._rowIds = []
for (let i = 0; i < messages.length; i++) {
this._data.push(messages[i]);
this._rowIds.push(this._data.length - 1);
rowID = this._data.length - 1;
}
let arrCopy = [].concat(this._rowIds)
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this._data, arrCopy),
initialLoading: false,
oldestMessageId: _.last(messages).id
})
console.warn(this._data[0].id)
}
appendNewerMessages(messages) {
var rowID = null;
// for (let i = 0; i < _.indexOf(newerMessageId, _.; i++) {
// this._data.push(messages[i]);
// this._rowIds.push(this._data.length - 1);
// rowID = this._data.length - 1;
// }
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this._data, this._rowIds),
newerMessageId: this._data[rowID].id
});
}
prependOldestMessages(messages) {
messages.reverse()
var rowID = null;
for (let i = 0; i < messages.length; i++) {
this._data.push(messages[i]);
this._rowIds.push(this._data.length - 1);
rowID = this._data.length - 1;
}
let arrCopy = [].concat(this._rowIds)
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this._data, arrCopy),
oldestMessageId: _.last(messages).id
})
}
onEndReached() {
if (this.props.messages.hasMore) {
this.props.onGetOldestMessages(this.state.oldestMessageId)
}
}
onHasNoMore() {
this._data.push({hasNoMore: true});
this._rowIds.push(this._data.length - 1);
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this._data, this.__rowIds)
})
}
renderRow(rowData, rowId) {
if (rowData.hasNoMore) {
return (<Text>This is a very begining!</Text>)
} else {
return (<Message {...rowData} index={rowID}/>)
}
}
renderListView() {
return (
<ListView
ref='listView'
renderScrollComponent={props => <InvertibleScrollView {...props} inverted />}
onEndReached={this.onEndReached.bind(this)}
onEndReachedThreshold={200}
dataSource={this.state.dataSource}
pageSize={50}
initialListSize={50}
renderRow={(rowData,_,rowId) => this.renderRow(rowData, rowId)}
/>
)
}
render() {
return (
<View style={styles.container}>
{this.props.loading && <Text style={{textAlign: 'center'}}>Loading...</Text>}
{this.renderListView()}
</View>
);
}
}
MessagesListView.propTypes = {
messages: PropTypes.object,
loading: PropTypes.bool,
activeRoom: PropTypes.string,
onGetOldestMessages: PropTypes.func
}
MessagesListView.defaultProps = {
messages: {
fetchHistory: []
},
loading: true
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
buttonGroup: {
height: 20,
width: 360,
flexDirection: 'row',
alignItems: 'center'
},
button: {
height: 20,
width: 180,
borderWidth: 1,
borderColor: 'black',
},
buttonText: {
textAlign: 'center'
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment