suggested grid vertical scrolling. semi-infinite scroll
This commit is contained in:
parent
dbaaf66bb0
commit
647d7e6a93
7 changed files with 103 additions and 51 deletions
|
@ -72,7 +72,15 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
|||
tags
|
||||
.slice(0, 1)
|
||||
.map(tag => (
|
||||
<Tag style={subscriptionsStyle.tag} key={tag} name={tag} navigation={navigation} truncate />
|
||||
<Tag
|
||||
numberOfLines={1}
|
||||
onPress={this.handleItemPress}
|
||||
style={subscriptionsStyle.tag}
|
||||
key={tag}
|
||||
name={tag}
|
||||
navigation={navigation}
|
||||
truncate
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doClaimSearch, selectFetchingClaimSearch, selectClaimSearchByQuery, selectFollowedTags } from 'lbry-redux';
|
||||
import {
|
||||
doClaimSearch,
|
||||
selectFetchingClaimSearch,
|
||||
selectClaimSearchByQuery,
|
||||
selectClaimSearchByQueryLastPageReached,
|
||||
selectFollowedTags,
|
||||
} from 'lbry-redux';
|
||||
import { selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc';
|
||||
import { selectShowNsfw } from 'redux/selectors/settings';
|
||||
import SuggestedSubscriptionsGrid from './view';
|
||||
|
@ -9,6 +15,7 @@ const select = state => ({
|
|||
suggested: selectSuggestedChannels(state),
|
||||
loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state),
|
||||
claimSearchByQuery: selectClaimSearchByQuery(state),
|
||||
lastPageReached: selectClaimSearchByQueryLastPageReached(state),
|
||||
showNsfwContent: selectShowNsfw(state),
|
||||
});
|
||||
|
||||
|
|
|
@ -6,50 +6,76 @@ import { FlatGrid } from 'react-native-super-grid';
|
|||
import SubscribeButton from 'component/subscribeButton';
|
||||
import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import discoverStyle from 'styles/discover';
|
||||
import subscriptionsStyle from 'styles/subscriptions';
|
||||
import Link from 'component/link';
|
||||
import _ from 'lodash';
|
||||
|
||||
const suggestedPageSize = 24;
|
||||
const softLimit = 2400;
|
||||
class SuggestedSubscriptionsGrid extends React.PureComponent {
|
||||
state = {
|
||||
currentPage: 1,
|
||||
options: {},
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { claimSearch, followedTags, showNsfwContent } = this.props;
|
||||
buildClaimSearchOptions() {
|
||||
const { showNsfwContent } = this.props;
|
||||
const { currentPage } = this.state;
|
||||
|
||||
const options = {
|
||||
page: 1,
|
||||
page_size: 99,
|
||||
no_totals: true,
|
||||
page: currentPage,
|
||||
page_size: suggestedPageSize,
|
||||
claim_type: 'channel',
|
||||
order_by: ['trending_global', 'trending_mixed'],
|
||||
order_by: [Constants.ORDER_BY_EFFECTIVE_AMOUNT],
|
||||
};
|
||||
if (!showNsfwContent) {
|
||||
options.not_tags = MATURE_TAGS;
|
||||
}
|
||||
this.setState({ options });
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
doClaimSearch() {
|
||||
const { claimSearch } = this.props;
|
||||
const options = this.buildClaimSearchOptions();
|
||||
claimSearch(options);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { claimSearchByQuery, suggested, inModal, loading, navigation } = this.props;
|
||||
const claimSearchKey = createNormalizedClaimSearchKey(this.state.options);
|
||||
const claimSearchUris = claimSearchByQuery[claimSearchKey];
|
||||
handleVerticalEndReached = () => {
|
||||
// fetch more content
|
||||
const { claimSearchByQuery, lastPageReached } = this.props;
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<View style={subscriptionsStyle.centered}>
|
||||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
);
|
||||
const options = this.buildClaimSearchOptions();
|
||||
const claimSearchKey = createNormalizedClaimSearchKey(options);
|
||||
const uris = claimSearchByQuery[claimSearchKey];
|
||||
if (
|
||||
lastPageReached[claimSearchKey] ||
|
||||
((uris.length > 0 && uris.length < suggestedPageSize) || uris.length >= softLimit)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ currentPage: this.state.currentPage + 1 }, () => this.doClaimSearch());
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { claimSearch, followedTags, showNsfwContent } = this.props;
|
||||
this.doClaimSearch();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { claimSearchByQuery, suggested, inModal, navigation } = this.props;
|
||||
const options = this.buildClaimSearchOptions();
|
||||
const claimSearchKey = createNormalizedClaimSearchKey(options);
|
||||
const claimSearchUris = claimSearchByQuery[claimSearchKey];
|
||||
|
||||
return (
|
||||
<FlatGrid
|
||||
horizontal
|
||||
initialNumToRender={18}
|
||||
maxToRenderPerBatch={24}
|
||||
initialNumToRender={24}
|
||||
maxToRenderPerBatch={48}
|
||||
removeClippedSubviews
|
||||
itemDimension={120}
|
||||
spacing={2}
|
||||
|
@ -61,6 +87,8 @@ class SuggestedSubscriptionsGrid extends React.PureComponent {
|
|||
renderItem={({ item, index }) => (
|
||||
<SuggestedSubscriptionItem key={item} uri={normalizeURI(item)} navigation={navigation} />
|
||||
)}
|
||||
onEndReached={this.handleVerticalEndReached}
|
||||
onEndReachedThreshold={0.2}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class Tag extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { name, onPress, style, type, truncate } = this.props;
|
||||
const { name, numberOfLines, onPress, style, type, truncate } = this.props;
|
||||
|
||||
let styles = [];
|
||||
if (style) {
|
||||
|
@ -50,7 +50,9 @@ export default class Tag extends React.PureComponent {
|
|||
return (
|
||||
<TouchableOpacity style={styles} onPress={onPress || this.onPressDefault}>
|
||||
<View style={tagStyle.content}>
|
||||
<Text style={tagStyle.text}>{truncate ? formatTagName(name) : name}</Text>
|
||||
<Text style={tagStyle.text} numberOfLines={numberOfLines}>
|
||||
{truncate ? formatTagName(name) : name}
|
||||
</Text>
|
||||
{type && <Icon style={tagStyle.icon} name={type === 'add' ? 'plus' : 'times'} size={8} />}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
|
|
@ -7,14 +7,13 @@ import {
|
|||
selectSubscriptionClaims,
|
||||
selectSubscriptions,
|
||||
selectIsFetchingSubscriptions,
|
||||
selectIsFetchingSuggested,
|
||||
selectSuggestedChannels,
|
||||
selectUnreadSubscriptions,
|
||||
selectViewMode,
|
||||
selectFirstRunCompleted,
|
||||
selectShowSuggestedSubs,
|
||||
} from 'lbryinc';
|
||||
import { doToast } from 'lbry-redux';
|
||||
import { doToast, selectFetchingClaimSearch } from 'lbry-redux';
|
||||
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||
import { doSetClientSetting, doSetTimeItem } from 'redux/actions/settings';
|
||||
import { makeSelectClientSetting, selectTimeItem } from 'redux/selectors/settings';
|
||||
|
@ -25,7 +24,7 @@ import SubscriptionsPage from './view';
|
|||
const select = state => ({
|
||||
currentRoute: selectCurrentRoute(state),
|
||||
loading: selectIsFetchingSubscriptions(state),
|
||||
loadingSuggested: selectIsFetchingSuggested(state),
|
||||
loadingSuggested: selectFetchingClaimSearch(state),
|
||||
subscribedChannels: selectSubscriptions(state),
|
||||
suggestedChannels: selectSuggestedChannels(state),
|
||||
subscriptionsViewMode: makeSelectClientSetting(Constants.SETTING_SUBSCRIPTIONS_VIEW_MODE)(state),
|
||||
|
|
|
@ -178,7 +178,9 @@ class SubscriptionsPage extends React.PureComponent {
|
|||
<UriBar navigation={navigation} belowOverlay={this.state.showSortPicker} />
|
||||
<View style={subscriptionsStyle.titleRow}>
|
||||
<Text style={subscriptionsStyle.pageTitle}>
|
||||
{hasSubscriptions ? __('Channels you follow') : __('Find Channels to follow')}
|
||||
{hasSubscriptions && !this.state.showingSuggestedSubs
|
||||
? __('Channels you follow')
|
||||
: __('Find Channels to follow')}
|
||||
</Text>
|
||||
</View>
|
||||
{!this.state.showingSuggestedSubs && hasSubscriptions && (
|
||||
|
@ -239,29 +241,31 @@ class SubscriptionsPage extends React.PureComponent {
|
|||
<Text style={subscriptionsStyle.infoText}>
|
||||
{__('LBRY works better if you find and follow at least 5 creators you like.')}
|
||||
</Text>
|
||||
<Button
|
||||
style={subscriptionsStyle.suggestedDoneButton}
|
||||
text={
|
||||
numberOfSubscriptions < 5
|
||||
? __('%remaining% more...', { remaining: 5 - numberOfSubscriptions })
|
||||
: __('Done')
|
||||
}
|
||||
onPress={() => {
|
||||
if (!hasSubscriptions) {
|
||||
notify({ message: __('Tap on any channel to follow') });
|
||||
} else {
|
||||
this.setState({ showingSuggestedSubs: false });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={subscriptionsStyle.mainSuggested}>
|
||||
<SuggestedSubscriptionsGrid navigation={navigation} />
|
||||
</View>
|
||||
|
||||
<Button
|
||||
style={subscriptionsStyle.suggestedDoneButton}
|
||||
text={
|
||||
numberOfSubscriptions < 5
|
||||
? __('%remaining% more...', { remaining: 5 - numberOfSubscriptions })
|
||||
: __('Done')
|
||||
}
|
||||
onPress={() => {
|
||||
if (!hasSubscriptions) {
|
||||
notify({ message: __('Tap on any channel to follow') });
|
||||
} else {
|
||||
this.setState({ showingSuggestedSubs: false });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{loadingSuggested && (
|
||||
<View style={subscriptionsStyle.centered}>
|
||||
<ActivityIndicator size="large" colors={Colors.NextLbryGreen} style={subscriptionsStyle.loading} />
|
||||
</View>
|
||||
<ActivityIndicator size="small" color={Colors.White} style={subscriptionsStyle.suggestedLoading} />
|
||||
)}
|
||||
{!loadingSuggested && <SuggestedSubscriptionsGrid navigation={navigation} />}
|
||||
</View>
|
||||
)}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ const subscriptionsStyle = StyleSheet.create({
|
|||
fontSize: 16,
|
||||
marginTop: 8,
|
||||
marginBottom: 8,
|
||||
flex: 0.7,
|
||||
},
|
||||
infoArea: {
|
||||
flexDirection: 'row',
|
||||
|
@ -195,7 +194,7 @@ const subscriptionsStyle = StyleSheet.create({
|
|||
marginBottom: 16,
|
||||
marginLeft: 16,
|
||||
marginRight: 16,
|
||||
width: 120,
|
||||
height: 120,
|
||||
},
|
||||
suggestedItemThumbnailContainer: {
|
||||
width: 70,
|
||||
|
@ -275,10 +274,15 @@ const subscriptionsStyle = StyleSheet.create({
|
|||
},
|
||||
suggestedDoneButton: {
|
||||
backgroundColor: Colors.LbryGreen,
|
||||
margin: 16,
|
||||
},
|
||||
mainSuggested: {
|
||||
flex: 1,
|
||||
},
|
||||
suggestedLoading: {
|
||||
position: 'absolute',
|
||||
right: 8,
|
||||
top: 8,
|
||||
zIndex: 100,
|
||||
right: 24,
|
||||
bottom: 22,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue