Skip to content

Commit

Permalink
Merge branch 'PhilippKrone-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
FaridSafi committed Nov 2, 2015
2 parents 5cc349d + e310b30 commit 870b822
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 30 deletions.
28 changes: 26 additions & 2 deletions Examples/example_advanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ var Example = React.createClass({
* Should be replaced by your own logic
* @param {number} page Requested page to fetch
* @param {function} callback Should pass the rows
* @param {object} options Inform if first load
*/
_onFetch(page = 1, callback) {
_onFetch(page = 1, callback, options) {
setTimeout(() => {
var rows = ['row '+((page - 1) * 3 + 1), 'row '+((page - 1) * 3 + 2), 'row '+((page - 1) * 3 + 3)];
var header = 'Header '+page;
var rows = {};
rows[header] = ['row '+((page - 1) * 3 + 1), 'row '+((page - 1) * 3 + 2), 'row '+((page - 1) * 3 + 3)];
if (page === 3) {
callback(rows, {
allLoaded: true, // the end of the list is reached
Expand Down Expand Up @@ -61,6 +64,20 @@ var Example = React.createClass({
</TouchableHighlight>
);
},

/**
* Render a row
* @param {object} rowData Row data
*/
_renderSectionHeaderView(sectionData, sectionID) {
return (
<View style={customStyles.header}>
<Text>
{sectionID}
</Text>
</View>
);
},

/**
* Render the refreshable view when waiting for refresh
Expand Down Expand Up @@ -217,6 +234,9 @@ var Example = React.createClass({
emptyView={this._renderEmptyView}

renderSeparator={this._renderSeparatorView}

withSections={true} // enable sections
sectionHeaderView={this._renderSectionHeaderView}
/>
</View>
);
Expand Down Expand Up @@ -258,6 +278,10 @@ var customStyles = {
padding: 10,
height: 44,
},
header: {
backgroundColor: '#EEE',
padding: 10,
}
};

var screenStyles = {
Expand Down
4 changes: 3 additions & 1 deletion Examples/example_simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ var Example = React.createClass({
* Should be replaced by your own logic
* @param {number} page Requested page to fetch
* @param {function} callback Should pass the rows
* @param {object} options Inform if first load
*/
_onFetch(page = 1, callback) {
_onFetch(page = 1, callback, options) {
setTimeout(() => {
var rows = ['row '+((page - 1) * 3 + 1), 'row '+((page - 1) * 3 + 2), 'row '+((page - 1) * 3 + 3)];
if (page === 3) {
Expand Down Expand Up @@ -70,6 +71,7 @@ var Example = React.createClass({
firstLoader={true} // display a loader for the first fetching
pagination={true} // enable infinite scrolling using touch to load more
refreshable={true} // enable pull-to-refresh for iOS and touch-to-refresh for Android
withSections={false} // enable sections
/>
</View>
);
Expand Down
104 changes: 79 additions & 25 deletions GiftedListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ var {
Text
} = React;

// small helper function which merged two objects into one
function MergeRecursive(obj1, obj2) {
for (var p in obj2) {
try {
if ( obj2[p].constructor==Object ) {
obj1[p] = MergeRecursive(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
obj1[p] = obj2[p];
}
}
return obj1;
}

var GiftedSpinner = require('react-native-gifted-spinner');

var GiftedListView = React.createClass({
Expand Down Expand Up @@ -54,7 +70,9 @@ var GiftedListView = React.createClass({
refreshable: true,
refreshableViewHeight: 50,
refreshableDistance: 40,
onFetch(page, callback) { callback([]); },
sectionHeaderView: null,
withSections: false,
onFetch(page, callback, options) { callback([]); },

paginationFetchigView() {
return (
Expand Down Expand Up @@ -157,11 +175,9 @@ var GiftedListView = React.createClass({
_setRows(rows) { this._rows = rows; },
_getRows() { return this._rows; },


getInitialState() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
return r1 !== r2;
}});


if (this.props.refreshable === true && Platform.OS !== 'android') {
this._setY(this.props.refreshableViewHeight);
} else {
Expand All @@ -170,26 +186,50 @@ var GiftedListView = React.createClass({

this._setPage(1);
this._setRows([]);

return {
dataSource: ds.cloneWithRows(this._getRows()),
refreshStatus: 'waiting',
paginationStatus: 'firstLoad',
};

var ds = null;
if (this.props.withSections === true) {
ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
sectionHeaderHasChanged: (section1, section2) => section1 !== section2,
});
return {
dataSource: ds.cloneWithRowsAndSections(this._getRows()),
refreshStatus: 'waiting',
paginationStatus: 'firstLoad',
};
} else {
ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});
return {
dataSource: ds.cloneWithRows(this._getRows()),
refreshStatus: 'waiting',
paginationStatus: 'firstLoad',
};
}
},

componentDidMount() {
this._scrollResponder = this.refs.listview.getScrollResponder();
this.props.onFetch(this._getPage(), this._postRefresh);
this.props.onFetch(this._getPage(), this._postRefresh, {firstLoad: true});
},

setNativeProps(props) {
this.refs.listview.setNativeProps(props);
},

_refresh() {
this._onRefresh({external: true});
},

_onRefresh() {
_onRefresh(options = {}) {
this._scrollResponder.scrollTo(0);
this.setState({
refreshStatus: 'fetching',
});
this._setPage(1);
this.props.onFetch(this._getPage(), this._postRefresh);
this.props.onFetch(this._getPage(), this._postRefresh, options);
},

_postRefresh(rows = [], options = {}) {
Expand All @@ -205,22 +245,35 @@ var GiftedListView = React.createClass({
this.setState({
paginationStatus: 'fetching',
});
this.props.onFetch(this._getPage() + 1, this._postPaginate);
this.props.onFetch(this._getPage() + 1, this._postPaginate, {});
},

_postPaginate(rows = [], options = {}) {
this._setPage(this._getPage() + 1);
var concatenatedRows = this._getRows().concat(rows);
this._updateRows(concatenatedRows, options);
var mergedRows = null;
if (this.props.withSections === true) {
mergedRows = MergeRecursive(this._getRows(), rows);
} else {
mergedRows = this._getRows().concat(rows);
}
this._updateRows(mergedRows, options);
},

_updateRows(rows = [], options = {}) {
this._setRows(rows);
this.setState({
dataSource: this.state.dataSource.cloneWithRows(rows),
refreshStatus: 'waiting',
paginationStatus: (options.allLoaded === true ? 'allLoaded' : 'waiting'),
});
if (this.props.withSections === true) {
this.setState({
dataSource: this.state.dataSource.cloneWithRowsAndSections(rows),
refreshStatus: 'waiting',
paginationStatus: (options.allLoaded === true ? 'allLoaded' : 'waiting'),
});
} else {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(rows),
refreshStatus: 'waiting',
paginationStatus: (options.allLoaded === true ? 'allLoaded' : 'waiting'),
});
}
},

_onResponderRelease() {
Expand Down Expand Up @@ -264,9 +317,9 @@ var GiftedListView = React.createClass({
},

_renderPaginationView() {
if ((this.state.paginationStatus === 'fetching' && this.props.pagination === true) || this.state.paginationStatus === 'firstLoad' && this.props.firstLoader === true) {
if ((this.state.paginationStatus === 'fetching' && this.props.pagination === true) || (this.state.paginationStatus === 'firstLoad' && this.props.firstLoader === true)) {
return this.props.paginationFetchigView();
} else if (this.state.paginationStatus === 'waiting' && this.props.pagination === true && this._getRows().length > 0) {
} else if (this.state.paginationStatus === 'waiting' && this.props.pagination === true && (this.props.withSections === true || this._getRows().length > 0)) {
return this.props.paginationWaitingView(this._onPaginate);
} else if (this.state.paginationStatus === 'allLoaded' && this.props.pagination === true) {
return this.props.paginationAllLoadedView();
Expand Down Expand Up @@ -299,6 +352,7 @@ var GiftedListView = React.createClass({
ref="listview"
dataSource={this.state.dataSource}
renderRow={this.props.rowView}
renderSectionHeader={this.props.sectionHeaderView}
initialListSize={this.props.initialListSize}
renderSeparator={this.props.renderSeparator}

Expand All @@ -322,4 +376,4 @@ var GiftedListView = React.createClass({
});


module.exports = GiftedListView;
module.exports = GiftedListView;
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ var Example = React.createClass({
* Should be replaced by your own logic
* @param {number} page Requested page to fetch
* @param {function} callback Should pass the rows
* @param {object} options Inform if first load
*/
_onFetch(page = 1, callback) {
_onFetch(page = 1, callback, options) {
setTimeout(() => {
var rows = ['row '+((page - 1) * 3 + 1), 'row '+((page - 1) * 3 + 2), 'row '+((page - 1) * 3 + 3)];
if (page === 3) {
Expand Down Expand Up @@ -77,6 +78,7 @@ var Example = React.createClass({
firstLoader={true} // display a loader for the first fetching
pagination={true} // enable infinite scrolling using touch to load more
refreshable={true} // enable pull-to-refresh for iOS and touch-to-refresh for Android
withSections={false} // enable sections
/>
</View>
);
Expand Down Expand Up @@ -117,6 +119,7 @@ var styles = {
- [x] Loader for first display
- [x] Default view when no content to display
- [x] Customizable (see advanced example)
- [x] Support for section header
- [ ] Pull-to-refresh in Android (tried to implement it but it seems that onResponderRelease event is not catchable yet in Android ListView - React-Native 0.13.2)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-gifted-listview",
"version": "0.0.2",
"version": "0.0.3",
"description": "A ListView that embed some recurrents features like pull-to-refresh, infinite scrolling and more for Android and iOS React-Native apps",
"main": "GiftedListView.js",
"scripts": {
Expand Down

0 comments on commit 870b822

Please sign in to comment.