From 2ab96e0c370d1787a3805872238369c0feca36db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=9D=A4?= <1498710037@qq.com> Date: Mon, 9 Dec 2019 16:01:27 +0800 Subject: [PATCH 01/13] fixed https://github.com/gameboyVito/react-native-ultimate-listview/issues/34 --- src/ultimateListView.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ultimateListView.js b/src/ultimateListView.js index c824ebe..44feb05 100644 --- a/src/ultimateListView.js +++ b/src/ultimateListView.js @@ -17,7 +17,8 @@ const { width, height } = Dimensions.get('window') const PaginationStatus = { firstLoad: 0, waiting: 1, - allLoaded: 2 + allLoaded: 2, + fetching: 3 } export default class UltimateListView extends Component { @@ -180,15 +181,15 @@ export default class UltimateListView extends Component { } } - onPaginate = () => { + onPaginate = async () => { if (this.state.paginationStatus !== PaginationStatus.allLoaded && !this.state.isRefreshing) { console.log('onPaginate()') - this.setState({ paginationStatus: PaginationStatus.waiting }) + await this.setState({ paginationStatus: PaginationStatus.fetching }) this.props.onFetch(this.getPage() + 1, this.postPaginate, this.endFetch) } } - onEndReached = () => { + onEndReached = async () => { // console.log('onEndReached()'); if (this.props.pagination && this.props.autoPagination && this.state.paginationStatus === PaginationStatus.waiting) { this.onPaginate() @@ -238,7 +239,7 @@ export default class UltimateListView extends Component { endFetch = () => { // console.log('endRefresh()'); if (this.mounted) { - this.setState({ isRefreshing: false }) + this.setState({ isRefreshing: false, paginationStatus: PaginationStatus.allLoaded }) if (this.props.refreshableMode === 'advanced' && this._flatList._listRef._scrollRef.onRefreshEnd) { this._flatList._listRef._scrollRef.onRefreshEnd() } @@ -378,9 +379,9 @@ export default class UltimateListView extends Component { renderFooter = () => { if (this.state.paginationStatus === PaginationStatus.firstLoad) { return this.paginationFetchingView() - } else if (this.state.paginationStatus === PaginationStatus.waiting && this.props.autoPagination === false) { + } else if (this.state.paginationStatus === PaginationStatus.fetching && this.props.autoPagination === false) { return this.paginationWaitingView(this.onPaginate) - } else if (this.state.paginationStatus === PaginationStatus.waiting && this.props.autoPagination === true) { + } else if (this.state.paginationStatus === PaginationStatus.fetching && this.props.autoPagination === true) { return this.paginationWaitingView() } else if (this.getRows().length !== 0 && this.state.paginationStatus === PaginationStatus.allLoaded) { return this.paginationAllLoadedView() From 87d846ed8f35832ca854eaa2b2bb1db71eee9252 Mon Sep 17 00:00:00 2001 From: bang88 Date: Wed, 15 Jul 2020 11:25:10 +0800 Subject: [PATCH 02/13] fix: rn 0.62 --- package.json | 4 ++-- src/refreshableScrollView.android.js | 2 +- src/refreshableScrollView.ios.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e36327f..3afba1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "react-native-ultimate-listview", - "version": "3.3.0", + "name": "@bang88/react-native-ultimate-listview", + "version": "3.3.1", "description": "A high performance FlatList providing customised pull-to-refresh | auto-pagination & infinite-scrolling | gridview layout | swipeable-row. The truly ultimate version that I have done the most tricky part for you, just simply follow the instructions shown below to put it in your app.", "main": "index.js", "scripts": { diff --git a/src/refreshableScrollView.android.js b/src/refreshableScrollView.android.js index 42dee12..53fcf21 100644 --- a/src/refreshableScrollView.android.js +++ b/src/refreshableScrollView.android.js @@ -25,7 +25,7 @@ const PaginationStatus = { allLoaded: 2 } -export default class RefreshableScrollView extends ScrollView { +export default class RefreshableScrollView extends React.Component { static defaultProps = { horizontal: false, scrollEnabled: true, diff --git a/src/refreshableScrollView.ios.js b/src/refreshableScrollView.ios.js index e29399b..9c1e17e 100644 --- a/src/refreshableScrollView.ios.js +++ b/src/refreshableScrollView.ios.js @@ -14,7 +14,7 @@ const PaginationStatus = { allLoaded: 2 } -export default class RefreshableScrollView extends ScrollView { +export default class RefreshableScrollView extends React.Component { static defaultProps = { horizontal: false, scrollEnabled: true, From cf4f078e9977a0fabbd29b7672adf8e3e6037a58 Mon Sep 17 00:00:00 2001 From: bang88 Date: Mon, 20 Jul 2020 11:12:13 +0800 Subject: [PATCH 03/13] feat: useNativeDriver --- package.json | 2 +- src/refreshableScrollView.android.js | 9 ++++++--- src/refreshableScrollView.ios.js | 9 ++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 3afba1d..3960571 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bang88/react-native-ultimate-listview", - "version": "3.3.1", + "version": "3.3.2", "description": "A high performance FlatList providing customised pull-to-refresh | auto-pagination & infinite-scrolling | gridview layout | swipeable-row. The truly ultimate version that I have done the most tricky part for you, just simply follow the instructions shown below to put it in your app.", "main": "index.js", "scripts": { diff --git a/src/refreshableScrollView.android.js b/src/refreshableScrollView.android.js index 53fcf21..624d0de 100644 --- a/src/refreshableScrollView.android.js +++ b/src/refreshableScrollView.android.js @@ -98,7 +98,8 @@ export default class RefreshableScrollView extends React.Component { Animated.timing(this.state.arrowAngle, { toValue: 1, duration: 50, - easing: Easing.inOut(Easing.quad) + easing: Easing.inOut(Easing.quad), + useNativeDriver: true, }).start() } } else if (this.state.refreshStatus !== RefreshStatus.pullToRefresh) { @@ -109,7 +110,8 @@ export default class RefreshableScrollView extends React.Component { Animated.timing(this.state.arrowAngle, { toValue: 0, duration: 50, - easing: Easing.inOut(Easing.quad) + easing: Easing.inOut(Easing.quad), + useNativeDriver: true, }).start() } } @@ -194,7 +196,8 @@ export default class RefreshableScrollView extends React.Component { Animated.timing(this.state.arrowAngle, { toValue: 0, duration: 50, - easing: Easing.inOut(Easing.quad) + easing: Easing.inOut(Easing.quad), + useNativeDriver: true, }).start() } } diff --git a/src/refreshableScrollView.ios.js b/src/refreshableScrollView.ios.js index 9c1e17e..f3e1ce2 100644 --- a/src/refreshableScrollView.ios.js +++ b/src/refreshableScrollView.ios.js @@ -82,7 +82,8 @@ export default class RefreshableScrollView extends React.Component { Animated.timing(this.state.arrowAngle, { toValue: 1, duration: 50, - easing: Easing.inOut(Easing.quad) + easing: Easing.inOut(Easing.quad), + useNativeDriver: true, }).start() } else { this.setState({ @@ -92,7 +93,8 @@ export default class RefreshableScrollView extends React.Component { Animated.timing(this.state.arrowAngle, { toValue: 0, duration: 50, - easing: Easing.inOut(Easing.quad) + easing: Easing.inOut(Easing.quad), + useNativeDriver: true, }).start() } } @@ -163,7 +165,8 @@ export default class RefreshableScrollView extends React.Component { Animated.timing(this.state.arrowAngle, { toValue: 0, duration: 50, - easing: Easing.inOut(Easing.quad) + easing: Easing.inOut(Easing.quad), + useNativeDriver: true, }).start() this._scrollview.scrollTo({ x: 0, y: 0, animated: true }) } From b2b969f2e684dfa25b04e870f36c6167a828ae07 Mon Sep 17 00:00:00 2001 From: bang88 Date: Mon, 10 Aug 2020 09:11:28 +0800 Subject: [PATCH 04/13] fix: warning --- src/refreshableScrollView.android.js | 2 +- src/refreshableScrollView.ios.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/refreshableScrollView.android.js b/src/refreshableScrollView.android.js index 624d0de..16fae01 100644 --- a/src/refreshableScrollView.android.js +++ b/src/refreshableScrollView.android.js @@ -2,7 +2,6 @@ import React from 'react' import { ActivityIndicator, Animated, - AsyncStorage, Dimensions, Easing, ScrollView, @@ -10,6 +9,7 @@ import { Text, View } from 'react-native' +import AsyncStorage from '@react-native-community/async-storage' import dateFormat from './util' const { width, height } = Dimensions.get('window') diff --git a/src/refreshableScrollView.ios.js b/src/refreshableScrollView.ios.js index f3e1ce2..4b98e9e 100644 --- a/src/refreshableScrollView.ios.js +++ b/src/refreshableScrollView.ios.js @@ -1,5 +1,7 @@ import React from 'react' -import { ActivityIndicator, Animated, AsyncStorage, Easing, ScrollView, StyleSheet, Text, View } from 'react-native' +import { ActivityIndicator, Animated, Easing, ScrollView, StyleSheet, Text, View } from 'react-native' +import AsyncStorage from '@react-native-community/async-storage' + import dateFormat from './util' const DATE_KEY = 'ultimateRefreshDate' From b13ab8261faacaab26adbb071abe83ccbd652a41 Mon Sep 17 00:00:00 2001 From: bang88 Date: Mon, 10 Aug 2020 09:11:38 +0800 Subject: [PATCH 05/13] bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3960571..7406ed4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bang88/react-native-ultimate-listview", - "version": "3.3.2", + "version": "3.3.3", "description": "A high performance FlatList providing customised pull-to-refresh | auto-pagination & infinite-scrolling | gridview layout | swipeable-row. The truly ultimate version that I have done the most tricky part for you, just simply follow the instructions shown below to put it in your app.", "main": "index.js", "scripts": { From 0bcc6a44596adec34df20b0be4a3329385becab3 Mon Sep 17 00:00:00 2001 From: bang88 Date: Tue, 11 Aug 2020 17:22:59 +0800 Subject: [PATCH 06/13] bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7406ed4..098261b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bang88/react-native-ultimate-listview", - "version": "3.3.3", + "version": "3.3.4", "description": "A high performance FlatList providing customised pull-to-refresh | auto-pagination & infinite-scrolling | gridview layout | swipeable-row. The truly ultimate version that I have done the most tricky part for you, just simply follow the instructions shown below to put it in your app.", "main": "index.js", "scripts": { From 106b1edf2c4275c2642ac14124241cd34490d1dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=9D=A4?= <1498710037@qq.com> Date: Fri, 14 Aug 2020 12:32:24 +0800 Subject: [PATCH 07/13] 1. Add `paginationLoadMoreView` Improve paginationLoadMoreView function when `autoPagination={false}`. & Optimize `onEndReached` & Refactor `renderEmptyView` --- src/refreshableScrollView.ios.js | 1 + src/ultimateListView.js | 86 +++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/refreshableScrollView.ios.js b/src/refreshableScrollView.ios.js index 4b98e9e..d169d4b 100644 --- a/src/refreshableScrollView.ios.js +++ b/src/refreshableScrollView.ios.js @@ -229,6 +229,7 @@ export default class RefreshableScrollView extends React.Component { onScroll={this.onScroll} onScrollEndDrag={this.onScrollEndDrag} onScrollBeginDrag={this.onScrollBeginDrag} + contentInset={{ top: 80 }} > {this.renderRefreshHeader()} {this.props.children} diff --git a/src/ultimateListView.js b/src/ultimateListView.js index 44feb05..eff3e6b 100644 --- a/src/ultimateListView.js +++ b/src/ultimateListView.js @@ -7,6 +7,7 @@ import { RefreshControl, ScrollView, StyleSheet, + Button, Text, View } from 'react-native' @@ -16,9 +17,9 @@ import RefreshableScrollView from './refreshableScrollView' const { width, height } = Dimensions.get('window') const PaginationStatus = { firstLoad: 0, - waiting: 1, + waiting: 1, // Free process with user's doing-nothing allLoaded: 2, - fetching: 3 + fetching: 3 // Waiting for fetch in `onRefresh()` } export default class UltimateListView extends Component { @@ -37,6 +38,7 @@ export default class UltimateListView extends Component { paginationFetchingView: null, paginationAllLoadedView: null, paginationWaitingView: null, + paginationLoadMoreView: null, emptyView: null, separator: null, @@ -99,6 +101,7 @@ export default class UltimateListView extends Component { paginationFetchingView: PropTypes.func, paginationAllLoadedView: PropTypes.func, paginationWaitingView: PropTypes.func, + paginationLoadMoreView: PropTypes.func, emptyView: PropTypes.func, separator: PropTypes.func, @@ -162,7 +165,7 @@ export default class UltimateListView extends Component { componentDidMount() { this.mounted = true if (this.props.firstLoader) { - this.props.onFetch(this.getPage(), this.postRefresh, this.endFetch) + this.props.onFetch(1, this.postRefresh, this.endFetch) } } @@ -171,27 +174,38 @@ export default class UltimateListView extends Component { } onRefresh = () => { - console.log('onRefresh()') if (this.mounted) { this.setState({ - isRefreshing: true + isRefreshing: true, + paginationStatus: PaginationStatus.fetching + }, () => { + this.props.onFetch(1, this.postRefresh, this.endFetch) }) - this.setPage(1) - this.props.onFetch(this.getPage(), this.postRefresh, this.endFetch) + } + } + + /** + * onRefreshEnd + * + * @description Scroll to top before `onRefresh()` ending + * * */ + onRefreshEnd = () => { + if (this.props.refreshableMode === 'advanced' && this._flatList._listRef._scrollRef.onRefreshEnd) { + this._flatList._listRef._scrollRef.onRefreshEnd() + } else if (this._flatList._listRef._scrollRef.scrollTo && this.state.isRefreshing) { + this._flatList._listRef._scrollRef.scrollTo({ x: 0, y: 0, animated: true }) } } onPaginate = async () => { if (this.state.paginationStatus !== PaginationStatus.allLoaded && !this.state.isRefreshing) { - console.log('onPaginate()') await this.setState({ paginationStatus: PaginationStatus.fetching }) this.props.onFetch(this.getPage() + 1, this.postPaginate, this.endFetch) } } - onEndReached = async () => { - // console.log('onEndReached()'); - if (this.props.pagination && this.props.autoPagination && this.state.paginationStatus === PaginationStatus.waiting) { + onEndReached = ({ distanceFromEnd }) => { + if (distanceFromEnd > 0 && this.props.pagination && this.props.autoPagination && this.state.paginationStatus === PaginationStatus.waiting) { this.onPaginate() } } @@ -232,17 +246,16 @@ export default class UltimateListView extends Component { if (rows.length < pageLimit) { paginationStatus = PaginationStatus.allLoaded } - this.updateRows(rows, paginationStatus) + this.setPage(1) + this.updateRows(rows.slice(), paginationStatus) } } endFetch = () => { - // console.log('endRefresh()'); if (this.mounted) { - this.setState({ isRefreshing: false, paginationStatus: PaginationStatus.allLoaded }) - if (this.props.refreshableMode === 'advanced' && this._flatList._listRef._scrollRef.onRefreshEnd) { - this._flatList._listRef._scrollRef.onRefreshEnd() - } + this.onRefreshEnd() + + this.setState({ isRefreshing: false, paginationStatus: PaginationStatus.allLoaded, dataSource: [] }) } } @@ -261,6 +274,8 @@ export default class UltimateListView extends Component { } updateRows = (rows, paginationStatus) => { + this.onRefreshEnd() + if (rows) { this.setRows(rows) this.setState({ @@ -275,10 +290,6 @@ export default class UltimateListView extends Component { paginationStatus }) } - - if (this.props.refreshableMode === 'advanced') { - this.endFetch() - } } updateDataSource(rows = []) { @@ -318,11 +329,11 @@ export default class UltimateListView extends Component { return null } - paginationWaitingView = (paginateCallback) => { + paginationWaitingView = () => { if (this.props.pagination) { - if (this.props.autoPagination) { + if (!this.state.isRefreshing) { if (this.props.paginationWaitingView) { - return this.props.paginationWaitingView(paginateCallback) + return this.props.paginationWaitingView() } return ( @@ -340,6 +351,22 @@ export default class UltimateListView extends Component { return null } + paginationLoadMoreView = (paginateCallback) => { + if (this.props.pagination) { + if (!this.state.isRefreshing) { + if (this.props.paginationLoadMoreView) { + return this.props.paginationLoadMoreView(paginateCallback) + } + + return ( +