refactor search results page for improved performance
This commit is contained in:
parent
bbdea90e0f
commit
4c864c00dd
10 changed files with 61 additions and 66 deletions
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -8056,9 +8056,9 @@
|
||||||
"integrity": "sha512-XRHhGH5aM4lSenX4zZBa07JaszJGXeF8cv1KY314Q4qJWOihKWLpkdvwqwsBieZ2iy8DPhdAVioQzw8JLD/Okw=="
|
"integrity": "sha512-XRHhGH5aM4lSenX4zZBa07JaszJGXeF8cv1KY314Q4qJWOihKWLpkdvwqwsBieZ2iy8DPhdAVioQzw8JLD/Okw=="
|
||||||
},
|
},
|
||||||
"react-native-fast-image": {
|
"react-native-fast-image": {
|
||||||
"version": "5.4.2",
|
"version": "6.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-5.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-6.1.1.tgz",
|
||||||
"integrity": "sha512-S4E96Lwmx6z6QD3MaAuP7cNcXRLfgEUYU2GB694TbGEoOjk/FO1OnfbxfFp0vUs/klr4HJwACcwihPPxrFTt8w=="
|
"integrity": "sha512-9bYUY8GLKpuTF9WOC28VM/ceH0+GyV60g3bcwYeiq0A+oDBVyVlj/ovMaJqRxHII6GQYX0WbTkiT5kWtPCtWkA=="
|
||||||
},
|
},
|
||||||
"react-native-fs": {
|
"react-native-fs": {
|
||||||
"version": "2.13.3",
|
"version": "2.13.3",
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"react-native-country-picker-modal": "^0.6.2",
|
"react-native-country-picker-modal": "^0.6.2",
|
||||||
"react-native-document-picker": "^2.3.0",
|
"react-native-document-picker": "^2.3.0",
|
||||||
"react-native-exception-handler": "2.9.0",
|
"react-native-exception-handler": "2.9.0",
|
||||||
"react-native-fast-image": "^5.0.3",
|
"react-native-fast-image": "^6.1.1",
|
||||||
"react-native-fs": "^2.13.3",
|
"react-native-fs": "^2.13.3",
|
||||||
"react-native-gesture-handler": "^1.1.0",
|
"react-native-gesture-handler": "^1.1.0",
|
||||||
"react-native-image-zoom-viewer": "^2.2.5",
|
"react-native-image-zoom-viewer": "^2.2.5",
|
||||||
|
|
|
@ -85,7 +85,6 @@ class FileItem extends React.PureComponent {
|
||||||
duration={duration}
|
duration={duration}
|
||||||
title={title}
|
title={title}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
blurRadius={obscure ? 15 : 0}
|
|
||||||
resizeMode="cover"
|
resizeMode="cover"
|
||||||
isResolvingUri={isResolvingUri}
|
isResolvingUri={isResolvingUri}
|
||||||
style={mediaStyle}
|
style={mediaStyle}
|
||||||
|
|
|
@ -59,34 +59,13 @@ class FileItemMedia extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let style = this.props.style;
|
let style = this.props.style;
|
||||||
const { blurRadius, duration, isResolvingUri, thumbnail, title, resizeMode } = this.props;
|
const { duration, isResolvingUri, thumbnail, title, resizeMode } = this.props;
|
||||||
const atStyle = this.state.autoThumbStyle;
|
const atStyle = this.state.autoThumbStyle;
|
||||||
if (this.isThumbnailValid(thumbnail) && !this.state.imageLoadFailed) {
|
if (this.isThumbnailValid(thumbnail) && !this.state.imageLoadFailed) {
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
style = fileItemMediaStyle.thumbnail;
|
style = fileItemMediaStyle.thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blurRadius > 0) {
|
|
||||||
// No blur radius support in FastImage yet
|
|
||||||
return (
|
|
||||||
<View style={style}>
|
|
||||||
<Image
|
|
||||||
source={{ uri: thumbnail }}
|
|
||||||
blurRadius={blurRadius}
|
|
||||||
resizeMode={resizeMode || 'cover'}
|
|
||||||
style={fileItemMediaStyle.image}
|
|
||||||
/>
|
|
||||||
{duration && (
|
|
||||||
<VideoDuration
|
|
||||||
duration={duration}
|
|
||||||
style={fileItemMediaStyle.duration}
|
|
||||||
textStyle={fileItemMediaStyle.durationText}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={style}>
|
<View style={style}>
|
||||||
<FastImage
|
<FastImage
|
||||||
|
|
|
@ -118,7 +118,6 @@ class FileListItem extends React.PureComponent {
|
||||||
>
|
>
|
||||||
<FileItemMedia
|
<FileItemMedia
|
||||||
style={fileListStyle.thumbnail}
|
style={fileListStyle.thumbnail}
|
||||||
blurRadius={obscure ? 15 : 0}
|
|
||||||
duration={duration}
|
duration={duration}
|
||||||
resizeMode="cover"
|
resizeMode="cover"
|
||||||
title={title || name}
|
title={title || name}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import discoverStyle from '../../styles/discover';
|
||||||
class NsfwOverlay extends React.PureComponent {
|
class NsfwOverlay extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity style={discoverStyle.overlay} activeOpacity={0.95} onPress={this.props.onPress}>
|
<TouchableOpacity style={discoverStyle.overlay} activeOpacity={1} onPress={this.props.onPress}>
|
||||||
<Text style={discoverStyle.overlayText}>
|
<Text style={discoverStyle.overlayText}>
|
||||||
This content is Not Safe For Work. To view adult content, please change your Settings.
|
This content is Not Safe For Work. To view adult content, please change your Settings.
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -10,19 +10,21 @@ import {
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||||
import { selectCurrentRoute } from 'redux/selectors/drawer';
|
import { selectCurrentRoute } from 'redux/selectors/drawer';
|
||||||
import Constants from 'constants';
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
import SearchPage from './view';
|
import SearchPage from './view';
|
||||||
|
|
||||||
|
const numSearchResults = 50;
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
currentRoute: selectCurrentRoute(state),
|
currentRoute: selectCurrentRoute(state),
|
||||||
isSearching: selectIsSearching(state),
|
isSearching: selectIsSearching(state),
|
||||||
query: selectSearchValue(state),
|
query: selectSearchValue(state),
|
||||||
uris: makeSelectSearchUris(makeSelectQueryWithOptions(null, 25)(state))(state),
|
uris: makeSelectSearchUris(makeSelectQueryWithOptions(null, numSearchResults)(state))(state),
|
||||||
urisByQuery: selectSearchUrisByQuery(state),
|
urisByQuery: selectSearchUrisByQuery(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
search: query => dispatch(doSearch(query, 25)),
|
search: query => dispatch(doSearch(query, numSearchResults)),
|
||||||
updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)),
|
updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)),
|
||||||
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SEARCH)),
|
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SEARCH)),
|
||||||
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Lbry, parseURI, normalizeURI, isURIValid } from 'lbry-redux';
|
import { Lbry, parseURI, normalizeURI, isURIValid } from 'lbry-redux';
|
||||||
import { ActivityIndicator, Button, NativeModules, Text, TextInput, View, ScrollView } from 'react-native';
|
import { ActivityIndicator, Button, FlatList, NativeModules, Text, TextInput, View } from 'react-native';
|
||||||
import { navigateToUri } from 'utils/helper';
|
import { navigateToUri } from 'utils/helper';
|
||||||
import Colors from 'styles/colors';
|
import Colors from 'styles/colors';
|
||||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
|
@ -84,6 +84,33 @@ class SearchPage extends React.PureComponent {
|
||||||
search(keywords);
|
search(keywords);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
listHeaderComponent = () => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
const { currentUri } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FileListItem
|
||||||
|
uri={currentUri}
|
||||||
|
featuredResult
|
||||||
|
style={searchStyle.featuredResultItem}
|
||||||
|
navigation={navigation}
|
||||||
|
onPress={() => navigateToUri(navigation, currentUri)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
listEmptyComponent = () => {
|
||||||
|
const { query } = this.props;
|
||||||
|
return (
|
||||||
|
<View style={searchStyle.noResults}>
|
||||||
|
<Text style={searchStyle.noResultsText}>
|
||||||
|
There are no results to display for <Text style={searchStyle.boldText}>{query}</Text>. Please try a different
|
||||||
|
search term.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isSearching, navigation, query, uris, urisByQuery } = this.props;
|
const { isSearching, navigation, query, uris, urisByQuery } = this.props;
|
||||||
|
|
||||||
|
@ -96,37 +123,21 @@ class SearchPage extends React.PureComponent {
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isSearching && (
|
<FlatList
|
||||||
<ScrollView
|
style={searchStyle.scrollContainer}
|
||||||
style={searchStyle.scrollContainer}
|
contentContainerStyle={searchStyle.scrollPadding}
|
||||||
contentContainerStyle={searchStyle.scrollPadding}
|
keyboardShouldPersistTaps={'handled'}
|
||||||
keyboardShouldPersistTaps={'handled'}
|
data={uris}
|
||||||
>
|
keyExtractor={(item, index) => item}
|
||||||
{this.state.currentUri && (
|
initialNumToRender={10}
|
||||||
<FileListItem
|
maxToRenderPerBatch={20}
|
||||||
key={this.state.currentUri}
|
removeClippedSubviews
|
||||||
uri={this.state.currentUri}
|
ListEmptyComponent={!isSearching ? this.listEmptyComponent() : null}
|
||||||
featuredResult
|
ListHeaderComponent={this.listHeaderComponent()}
|
||||||
style={searchStyle.featuredResultItem}
|
renderItem={({ item }) => (
|
||||||
navigation={navigation}
|
<FileListItem key={item} uri={item} style={searchStyle.resultItem} navigation={navigation} />
|
||||||
onPress={() => navigateToUri(navigation, this.state.currentUri)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
{uris && uris.length
|
|
||||||
? uris.map(uri => (
|
|
||||||
<FileListItem key={uri} uri={uri} style={searchStyle.resultItem} navigation={navigation} />
|
|
||||||
))
|
|
||||||
: null}
|
|
||||||
{(!uris || uris.length === 0) && (
|
|
||||||
<View style={searchStyle.noResults}>
|
|
||||||
<Text style={searchStyle.noResultsText}>
|
|
||||||
There are no results to display for <Text style={searchStyle.boldText}>{query}</Text>. Please try a
|
|
||||||
different search term.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</ScrollView>
|
|
||||||
)}
|
|
||||||
<FloatingWalletBalance navigation={navigation} />
|
<FloatingWalletBalance navigation={navigation} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -188,8 +188,8 @@ const discoverStyle = StyleSheet.create({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
width: '100%',
|
right: 0,
|
||||||
height: '100%',
|
bottom: 0,
|
||||||
},
|
},
|
||||||
overlayText: {
|
overlayText: {
|
||||||
color: Colors.White,
|
color: Colors.White,
|
||||||
|
|
|
@ -12,6 +12,11 @@ const searchStyle = StyleSheet.create({
|
||||||
},
|
},
|
||||||
busyContainer: {
|
busyContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
position: 'absolute',
|
||||||
|
top: 60,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue