diff --git a/package-lock.json b/package-lock.json index f1bf389..8bf3f03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7067,8 +7067,8 @@ } }, "lbry-redux": { - "version": "github:lbryio/lbry-redux#e8f29f1c47b136669df265babb109d2488a37db0", - "from": "github:lbryio/lbry-redux#e8f29f1c47b136669df265babb109d2488a37db0", + "version": "github:lbryio/lbry-redux#c910cd2b80b165843a81fdf6ce96094429b94ec8", + "from": "github:lbryio/lbry-redux#c910cd2b80b165843a81fdf6ce96094429b94ec8", "requires": { "proxy-polyfill": "0.1.6", "reselect": "^3.0.0", diff --git a/package.json b/package.json index a211509..5a6745b 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "base-64": "^0.1.0", "@expo/vector-icons": "^8.1.0", "gfycat-style-urls": "^1.0.3", - "lbry-redux": "lbryio/lbry-redux#e8f29f1c47b136669df265babb109d2488a37db0", + "lbry-redux": "lbryio/lbry-redux#c910cd2b80b165843a81fdf6ce96094429b94ec8", "lbryinc": "lbryio/lbryinc#053ca52f4f7f9bf8eb62a3581b183671a475ad1c", "lodash": ">=4.17.11", "merge": ">=1.2.1", diff --git a/src/page/search/index.js b/src/page/search/index.js index 339a0e4..edb4b1f 100644 --- a/src/page/search/index.js +++ b/src/page/search/index.js @@ -5,6 +5,7 @@ import { doResolvedSearch, doUpdateSearchQuery, makeSelectResolvedSearchResults, + makeSelectResolvedSearchResultsLastPageReached, makeSelectSearchUris, selectClaimSearchByQuery, selectIsSearching, @@ -17,20 +18,21 @@ import { selectCurrentRoute } from 'redux/selectors/drawer'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import SearchPage from './view'; -const numSearchResults = 25; - const select = state => ({ claimSearchByQuery: selectClaimSearchByQuery(state), currentRoute: selectCurrentRoute(state), isSearching: selectIsSearching(state), query: selectSearchValue(state), resolvingUris: selectResolvingUris(state), - uris: makeSelectSearchUris(makeSelectQueryWithOptions(null, numSearchResults)(state))(state), - results: makeSelectResolvedSearchResults(makeSelectQueryWithOptions(null, numSearchResults)(state))(state), + uris: makeSelectSearchUris(makeSelectQueryWithOptions(null, Constants.DEFAULT_PAGE_SIZE)(state))(state), + results: makeSelectResolvedSearchResults(makeSelectQueryWithOptions(null, Constants.DEFAULT_PAGE_SIZE)(state))(state), + lastPageReached: makeSelectResolvedSearchResultsLastPageReached( + makeSelectQueryWithOptions(null, Constants.DEFAULT_PAGE_SIZE)(state), + )(state), }); const perform = dispatch => ({ - search: query => dispatch(doResolvedSearch(query, numSearchResults, null, false, {})), + search: (query, from) => dispatch(doResolvedSearch(query, Constants.DEFAULT_PAGE_SIZE, from, false, {})), claimSearch: options => dispatch(doClaimSearch(options)), updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SEARCH)), diff --git a/src/page/search/view.js b/src/page/search/view.js index 5747637..7710b3e 100644 --- a/src/page/search/view.js +++ b/src/page/search/view.js @@ -20,9 +20,12 @@ import FloatingWalletBalance from 'component/floatingWalletBalance'; import UriBar from 'component/uriBar'; import searchStyle from 'styles/search'; +const softLimit = 500; + class SearchPage extends React.PureComponent { state = { currentQuery: null, + currentFrom: 0, currentUri: null, showTagResult: false, claimSearchRun: false, @@ -56,6 +59,7 @@ class SearchPage extends React.PureComponent { const searchQuery = query || this.getSearchQuery(); if (searchQuery && searchQuery.trim().length > 0) { this.setState({ + currentFrom: 0, currentQuery: searchQuery, currentUri: isURIValid(searchQuery) ? normalizeURI(searchQuery) : null, claimSearchOptions: null, @@ -64,7 +68,7 @@ class SearchPage extends React.PureComponent { resultsResolved: false, tagResultDisplayed: false, }); - search(searchQuery); + search(searchQuery, 0); } }); }; @@ -83,12 +87,13 @@ class SearchPage extends React.PureComponent { if (query && query.trim().length > 0 && query !== this.state.currentQuery) { this.setState({ + currentFrom: 0, currentQuery: query, currentUri: isURIValid(query) ? normalizeURI(query) : null, resultsResolved: false, tagResultDisplayed: false, }); - search(query); + search(query, 0); } } @@ -134,13 +139,15 @@ class SearchPage extends React.PureComponent { const { search } = this.props; this.setState({ currentUri: isURIValid(keywords) ? normalizeURI(keywords) : null, + currentFrom: 0, + currentQuery: keywords, claimSearchOptions: null, claimSearchRun: false, showTagResult: false, resultsResolved: false, tagResultDisplayed: false, }); - search(keywords); + search(keywords, 0); }; listEmptyComponent = () => { @@ -186,6 +193,21 @@ class SearchPage extends React.PureComponent { navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: `tagPage`, params: { tag: tag.toLowerCase() } }); }; + handleVerticalEndReached = () => { + // fetch more results + const { lastPageReached, results, search, isSearching } = this.props; + if (lastPageReached || (results && results.length > softLimit)) { + return; + } + + if (!isSearching) { + const from = results ? results.length : 0; + this.setState({ currentFrom: from }, () => { + search(this.state.currentQuery, from); + }); + } + }; + render() { const { isSearching, navigation, query, results } = this.props; @@ -193,13 +215,13 @@ class SearchPage extends React.PureComponent { - {isSearching && ( + {isSearching && this.state.currentFrom === 0 && ( )} - {!isSearching && ( + {(!isSearching || this.state.currentFrom > 0) && ( item.claimId} - initialNumToRender={8} + initialNumToRender={10} maxToRenderPerBatch={20} + onEndReached={this.handleVerticalEndReached} + onEndReachedThreshold={0.2} removeClippedSubviews ListEmptyComponent={!isSearching ? this.listEmptyComponent() : null} ListHeaderComponent={this.listHeaderComponent(this.state.showTagResult, this.state.currentQuery)} @@ -217,6 +241,11 @@ class SearchPage extends React.PureComponent { )} /> )} + {this.state.currentFrom > 0 && isSearching && ( + + + + )} ); diff --git a/src/styles/search.js b/src/styles/search.js index 4321f9e..b57373a 100644 --- a/src/styles/search.js +++ b/src/styles/search.js @@ -80,6 +80,12 @@ const searchStyle = StyleSheet.create({ loading: { position: 'absolute', }, + moreLoading: { + width: '100%', + height: 48, + alignItems: 'center', + justifyContent: 'center', + }, }); export default searchStyle;