diff --git a/app/screens/search/index.js b/app/screens/search/index.js index badba8f63..672ad129c 100644 --- a/app/screens/search/index.js +++ b/app/screens/search/index.js @@ -5,7 +5,7 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import {selectFocusedPostId, selectPost} from 'mattermost-redux/actions/posts'; -import {clearSearch, removeSearchTerms, searchPostsWithParams} from 'mattermost-redux/actions/search'; +import {clearSearch, removeSearchTerms, searchPostsWithParams, getMorePostsForSearch} from 'mattermost-redux/actions/search'; import {getCurrentChannelId, filterPostIds} from 'mattermost-redux/selectors/entities/channels'; import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; @@ -52,6 +52,8 @@ function makeMapStateToProps() { const serverVersion = state.entities.general.serverVersion; const enableDateSuggestion = isMinimumServerVersion(serverVersion, 5, 3); + const isSearchGettingMore = state.entities.search.isSearchGettingMore; + return { currentTeamId, currentChannelId, @@ -60,6 +62,7 @@ function makeMapStateToProps() { archivedPostIds, recent: recent[currentTeamId], searchingStatus: searchRequest.status, + isSearchGettingMore, theme: getTheme(state), enableDateSuggestion, timezoneOffsetInSeconds, @@ -77,6 +80,7 @@ function mapDispatchToProps(dispatch) { removeSearchTerms, selectFocusedPostId, searchPostsWithParams, + getMorePostsForSearch, selectPost, }, dispatch), }; diff --git a/app/screens/search/search.js b/app/screens/search/search.js index 8a5ecabc6..6578c9ebf 100644 --- a/app/screens/search/search.js +++ b/app/screens/search/search.js @@ -19,6 +19,8 @@ import AwesomeIcon from 'react-native-vector-icons/FontAwesome'; import {RequestStatus} from 'mattermost-redux/constants'; +import {debounce} from 'mattermost-redux/actions/helpers'; + import Autocomplete from 'app/components/autocomplete'; import KeyboardLayout from 'app/components/layout/keyboard_layout'; import DateHeader from 'app/components/post_list/date_header'; @@ -53,6 +55,7 @@ export default class Search extends PureComponent { loadThreadIfNecessary: PropTypes.func.isRequired, removeSearchTerms: PropTypes.func.isRequired, searchPostsWithParams: PropTypes.func.isRequired, + getMorePostsForSearch: PropTypes.func.isRequired, selectFocusedPostId: PropTypes.func.isRequired, selectPost: PropTypes.func.isRequired, }).isRequired, @@ -64,6 +67,7 @@ export default class Search extends PureComponent { archivedPostIds: PropTypes.arrayOf(PropTypes.string), recent: PropTypes.array.isRequired, searchingStatus: PropTypes.string, + isSearchGettingMore: PropTypes.bool.isRequired, theme: PropTypes.object.isRequired, enableDateSuggestion: PropTypes.bool, timezoneOffsetInSeconds: PropTypes.number.isRequired, @@ -115,7 +119,7 @@ export default class Search extends PureComponent { const {searchingStatus: status, recent, enableDateSuggestion} = this.props; const {searchingStatus: prevStatus} = prevProps; const recentLength = recent.length; - const shouldScroll = prevStatus !== status && (status === RequestStatus.SUCCESS || status === RequestStatus.STARTED); + const shouldScroll = prevStatus !== status && (status === RequestStatus.SUCCESS || status === RequestStatus.STARTED) && !this.props.isSearchGettingMore && !prevProps.isSearchGettingMore; if (this.props.isLandscape !== prevProps.isLandscape) { this.refs.searchBar.blur(); @@ -205,11 +209,11 @@ export default class Search extends PureComponent { }; handleTextChanged = (value, selectionChanged) => { - const {actions, searchingStatus} = this.props; + const {actions, searchingStatus, isSearchGettingMore} = this.props; this.setState({value}); actions.handleSearchDraftChanged(value); - if (!value && searchingStatus === RequestStatus.SUCCESS) { + if (!value && searchingStatus === RequestStatus.SUCCESS && !isSearchGettingMore) { actions.clearSearch(); this.scrollToTop(); } @@ -496,7 +500,7 @@ export default class Search extends PureComponent { }); // timezone offset in seconds - actions.searchPostsWithParams(currentTeamId, {terms: terms.trim(), is_or_search: isOrSearch, time_zone_offset: this.props.timezoneOffsetInSeconds}, true); + actions.searchPostsWithParams(currentTeamId, {terms: terms.trim(), is_or_search: isOrSearch, time_zone_offset: this.props.timezoneOffsetInSeconds, page: 0, per_page: 20}, true); }; handleSearchButtonPress = preventDoubleTap((text) => { @@ -529,6 +533,10 @@ export default class Search extends PureComponent { Keyboard.dismiss(); }); + onEndReached = debounce(() => { + this.props.actions.getMorePostsForSearch(); + }, 100); + render() { const { isLandscape, @@ -536,6 +544,7 @@ export default class Search extends PureComponent { recent, searchingStatus, theme, + isSearchGettingMore, } = this.props; const {intl} = this.context; @@ -612,14 +621,18 @@ export default class Search extends PureComponent { let results; switch (searchingStatus) { case RequestStatus.STARTED: - results = [{ - id: SEARCHING, - component: ( - - - - ), - }]; + if (isSearchGettingMore) { + results = postIds; + } else { + results = [{ + id: SEARCHING, + component: ( + + + + ), + }]; + } break; case RequestStatus.SUCCESS: if (postIds.length) { @@ -706,6 +719,8 @@ export default class Search extends PureComponent { keyboardShouldPersistTaps='always' keyboardDismissMode='interactive' stickySectionHeadersEnabled={Platform.OS === 'ios'} + onEndReached={this.onEndReached} + onEndReachedThreshold={Platform.OS === 'ios' ? 0 : 1} />