Following rework (#124)
* make following the default page. add suggested grd. * suggested grid vertical scrolling. semi-infinite scroll * search and related content fixes
This commit is contained in:
parent
1f649b9d38
commit
f05d357fa7
20 changed files with 359 additions and 100 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -7067,8 +7067,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lbry-redux": {
|
"lbry-redux": {
|
||||||
"version": "github:lbryio/lbry-redux#1de1d534c982db913f145a6171f39d7b8ebd61af",
|
"version": "github:lbryio/lbry-redux#5c874e921769093428966fa7ecdf723719cb9067",
|
||||||
"from": "github:lbryio/lbry-redux#1de1d534c982db913f145a6171f39d7b8ebd61af",
|
"from": "github:lbryio/lbry-redux#5c874e921769093428966fa7ecdf723719cb9067",
|
||||||
"requires": {
|
"requires": {
|
||||||
"proxy-polyfill": "0.1.6",
|
"proxy-polyfill": "0.1.6",
|
||||||
"reselect": "^3.0.0",
|
"reselect": "^3.0.0",
|
||||||
|
@ -7076,8 +7076,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lbryinc": {
|
"lbryinc": {
|
||||||
"version": "github:lbryio/lbryinc#138a053754ec8e3da8e9bf153d32f527c962f25c",
|
"version": "github:lbryio/lbryinc#0dc8829a319a708f45a855765f70a193ccb72676",
|
||||||
"from": "github:lbryio/lbryinc#138a053754ec8e3da8e9bf153d32f527c962f25c",
|
"from": "github:lbryio/lbryinc#0dc8829a319a708f45a855765f70a193ccb72676",
|
||||||
"requires": {
|
"requires": {
|
||||||
"reselect": "^3.0.0"
|
"reselect": "^3.0.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
"base-64": "^0.1.0",
|
"base-64": "^0.1.0",
|
||||||
"@expo/vector-icons": "^8.1.0",
|
"@expo/vector-icons": "^8.1.0",
|
||||||
"gfycat-style-urls": "^1.0.3",
|
"gfycat-style-urls": "^1.0.3",
|
||||||
"lbry-redux": "lbryio/lbry-redux#1de1d534c982db913f145a6171f39d7b8ebd61af",
|
"lbry-redux": "lbryio/lbry-redux#5c874e921769093428966fa7ecdf723719cb9067",
|
||||||
"lbryinc": "lbryio/lbryinc#138a053754ec8e3da8e9bf153d32f527c962f25c",
|
"lbryinc": "lbryio/lbryinc#0dc8829a319a708f45a855765f70a193ccb72676",
|
||||||
"lodash": ">=4.17.11",
|
"lodash": ">=4.17.11",
|
||||||
"merge": ">=1.2.1",
|
"merge": ">=1.2.1",
|
||||||
"moment": "^2.22.1",
|
"moment": "^2.22.1",
|
||||||
|
|
|
@ -88,12 +88,13 @@ const menuNavigationButton = navigation => (
|
||||||
|
|
||||||
const discoverStack = createStackNavigator(
|
const discoverStack = createStackNavigator(
|
||||||
{
|
{
|
||||||
Discover: {
|
Subscriptions: {
|
||||||
screen: DiscoverPage,
|
screen: SubscriptionsPage,
|
||||||
navigationOptions: ({ navigation }) => ({
|
navigationOptions: {
|
||||||
title: 'Explore',
|
title: 'Following',
|
||||||
header: null,
|
header: null,
|
||||||
}),
|
drawerIcon: ({ tintColor }) => <Icon name="heart" solid size={drawerIconSize} style={{ color: tintColor }} />,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
File: {
|
File: {
|
||||||
screen: FilePage,
|
screen: FilePage,
|
||||||
|
@ -160,10 +161,17 @@ const drawer = createDrawerNavigator(
|
||||||
DiscoverStack: {
|
DiscoverStack: {
|
||||||
screen: discoverStack,
|
screen: discoverStack,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
title: 'Explore',
|
title: 'Following',
|
||||||
drawerIcon: ({ tintColor }) => <Icon name="home" size={drawerIconSize} style={{ color: tintColor }} />,
|
drawerIcon: ({ tintColor }) => <Icon name="home" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Discover: {
|
||||||
|
screen: DiscoverPage,
|
||||||
|
navigationOptions: ({ navigation }) => ({
|
||||||
|
title: 'Your Tags',
|
||||||
|
header: null,
|
||||||
|
}),
|
||||||
|
},
|
||||||
Trending: {
|
Trending: {
|
||||||
screen: TrendingPage,
|
screen: TrendingPage,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
|
@ -171,13 +179,6 @@ const drawer = createDrawerNavigator(
|
||||||
drawerIcon: ({ tintColor }) => <Icon name="fire" size={drawerIconSize} style={{ color: tintColor }} />,
|
drawerIcon: ({ tintColor }) => <Icon name="fire" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subscriptions: {
|
|
||||||
screen: SubscriptionsPage,
|
|
||||||
navigationOptions: {
|
|
||||||
title: 'Subscriptions',
|
|
||||||
drawerIcon: ({ tintColor }) => <Icon name="heart" solid size={drawerIconSize} style={{ color: tintColor }} />,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
WalletStack: {
|
WalletStack: {
|
||||||
screen: walletStack,
|
screen: walletStack,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
|
|
|
@ -9,8 +9,8 @@ import discoverStyle from 'styles/discover';
|
||||||
|
|
||||||
const groupedMenuItems = {
|
const groupedMenuItems = {
|
||||||
'Find content': [
|
'Find content': [
|
||||||
{ icon: 'hashtag', label: 'Your Tags', route: Constants.DRAWER_ROUTE_DISCOVER },
|
|
||||||
{ icon: 'heart', solid: true, label: 'Following', route: Constants.DRAWER_ROUTE_SUBSCRIPTIONS },
|
{ icon: 'heart', solid: true, label: 'Following', route: Constants.DRAWER_ROUTE_SUBSCRIPTIONS },
|
||||||
|
{ icon: 'hashtag', label: 'Your Tags', route: Constants.DRAWER_ROUTE_DISCOVER },
|
||||||
{ icon: 'globe-americas', label: 'All Content', route: Constants.DRAWER_ROUTE_TRENDING },
|
{ icon: 'globe-americas', label: 'All Content', route: Constants.DRAWER_ROUTE_TRENDING },
|
||||||
],
|
],
|
||||||
'Your content': [
|
'Your content': [
|
||||||
|
@ -145,7 +145,7 @@ class DrawerContent extends React.PureComponent {
|
||||||
const focused =
|
const focused =
|
||||||
activeItemKey === item.route ||
|
activeItemKey === item.route ||
|
||||||
(activeItemKey === Constants.FULL_ROUTE_NAME_DISCOVER &&
|
(activeItemKey === Constants.FULL_ROUTE_NAME_DISCOVER &&
|
||||||
item.route === Constants.DRAWER_ROUTE_DISCOVER) ||
|
item.route === Constants.DRAWER_ROUTE_SUBSCRIPTIONS) ||
|
||||||
(activeItemKey === Constants.FULL_ROUTE_NAME_WALLET &&
|
(activeItemKey === Constants.FULL_ROUTE_NAME_WALLET &&
|
||||||
item.route === Constants.DRAWER_ROUTE_WALLET);
|
item.route === Constants.DRAWER_ROUTE_WALLET);
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { selectFetchingClaimSearch } from 'lbry-redux';
|
||||||
import ModalSuggestedSubscriptions from './view';
|
import ModalSuggestedSubscriptions from './view';
|
||||||
|
|
||||||
export default connect()(ModalSuggestedSubscriptions);
|
const select = state => ({
|
||||||
|
loadingSuggested: selectFetchingClaimSearch(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select)(ModalSuggestedSubscriptions);
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
import { ActivityIndicator, ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
||||||
import modalStyle from 'styles/modal';
|
import modalStyle from 'styles/modal';
|
||||||
import subscriptionsStyle from 'styles/subscriptions';
|
import subscriptionsStyle from 'styles/subscriptions';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Colors from 'styles/colors';
|
import Colors from 'styles/colors';
|
||||||
import SuggestedSubscriptions from 'component/suggestedSubscriptions';
|
import SuggestedSubscriptionsGrid from 'component/suggestedSubscriptionsGrid';
|
||||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
|
||||||
export default class ModalSuggestedSubcriptions extends React.PureComponent {
|
export default class ModalSuggestedSubcriptions extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
const { navigation, onDonePress, onOverlayPress } = this.props;
|
const { loadingSuggested, navigation, onDonePress, onOverlayPress } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity style={modalStyle.overlay} activeOpacity={1} onPress={onOverlayPress}>
|
<TouchableOpacity style={modalStyle.overlay} activeOpacity={1} onPress={onOverlayPress}>
|
||||||
<TouchableOpacity style={[modalStyle.container, subscriptionsStyle.modalContainer]} activeOpacity={1}>
|
<TouchableOpacity style={[modalStyle.container, subscriptionsStyle.modalContainer]} activeOpacity={1}>
|
||||||
<SuggestedSubscriptions inModal navigation={navigation} />
|
<SuggestedSubscriptionsGrid inModal navigation={navigation} />
|
||||||
<View style={modalStyle.buttons}>
|
<View style={modalStyle.wideButtons}>
|
||||||
<Button style={modalStyle.doneButton} text={__('Done')} onPress={onDonePress} />
|
<Button style={modalStyle.wideDoneButton} text={__('Done')} onPress={onDonePress} />
|
||||||
|
{loadingSuggested && (
|
||||||
|
<ActivityIndicator size="small" color={Colors.White} style={subscriptionsStyle.modalLoading} />
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
18
src/component/subscribeButtonOverlay/index.js
Normal file
18
src/component/subscribeButtonOverlay/index.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doChannelSubscribe, doChannelUnsubscribe, selectSubscriptions, makeSelectIsSubscribed } from 'lbryinc';
|
||||||
|
import { doToast } from 'lbry-redux';
|
||||||
|
import SubscribeButtonOverlay from './view';
|
||||||
|
|
||||||
|
const select = (state, props) => ({
|
||||||
|
subscriptions: selectSubscriptions(state),
|
||||||
|
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
{
|
||||||
|
doChannelSubscribe,
|
||||||
|
doChannelUnsubscribe,
|
||||||
|
doToast,
|
||||||
|
},
|
||||||
|
)(SubscribeButtonOverlay);
|
36
src/component/subscribeButtonOverlay/view.js
Normal file
36
src/component/subscribeButtonOverlay/view.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { normalizeURI, parseURI } from 'lbry-redux';
|
||||||
|
import { NativeModules, Text, View, TouchableOpacity } from 'react-native';
|
||||||
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import Colors from 'styles/colors';
|
||||||
|
|
||||||
|
class SubscribeButtonOverlay extends React.PureComponent {
|
||||||
|
handlePress = () => {
|
||||||
|
const { claim, isSubscribed, doChannelSubscribe, doChannelUnsubscribe, uri } = this.props;
|
||||||
|
if (!claim) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe;
|
||||||
|
const { name: claimName } = claim;
|
||||||
|
subscriptionHandler({
|
||||||
|
channelName: claimName,
|
||||||
|
uri: normalizeURI(uri),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { uri, isSubscribed, style } = this.props;
|
||||||
|
let styles = style.length ? style : [style];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity style={styles} opacity={0.7} onPress={this.handlePress}>
|
||||||
|
{isSubscribed && <Icon name={'heart'} size={20} solid color={Colors.Red} />}
|
||||||
|
{!isSubscribed && <Icon name={'heart'} size={20} color={Colors.Red} />}
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SubscribeButtonOverlay;
|
|
@ -6,6 +6,7 @@ import {
|
||||||
makeSelectTitleForUri,
|
makeSelectTitleForUri,
|
||||||
makeSelectIsUriResolving,
|
makeSelectIsUriResolving,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
|
import { doChannelSubscribe, doChannelUnsubscribe, makeSelectIsSubscribed } from 'lbryinc';
|
||||||
import SuggestedSubscriptionItem from './view';
|
import SuggestedSubscriptionItem from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -13,13 +14,16 @@ const select = (state, props) => ({
|
||||||
title: makeSelectTitleForUri(props.uri)(state),
|
title: makeSelectTitleForUri(props.uri)(state),
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
|
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
|
||||||
|
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
resolveUri: uri => dispatch(doResolveUri(uri)),
|
resolveUri: uri => dispatch(doResolveUri(uri)),
|
||||||
|
subscribe: subscription => doChannelSubscribe(subscription),
|
||||||
|
unsubscribe: subscription => doChannelUnsubscribe(subscription),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
select,
|
select,
|
||||||
perform
|
perform,
|
||||||
)(SuggestedSubscriptionItem);
|
)(SuggestedSubscriptionItem);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { buildURI, normalizeURI } from 'lbry-redux';
|
import { buildURI, normalizeURI } from 'lbry-redux';
|
||||||
import { ActivityIndicator, FlatList, Image, Text, View } from 'react-native';
|
import { ActivityIndicator, FlatList, Image, Text, TouchableOpacity, 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 ChannelIconItem from 'component/channelIconItem';
|
import ChannelIconItem from 'component/channelIconItem';
|
||||||
import channelIconStyle from 'styles/channelIcon';
|
import channelIconStyle from 'styles/channelIcon';
|
||||||
import discoverStyle from 'styles/discover';
|
import discoverStyle from 'styles/discover';
|
||||||
import FileItem from 'component/fileItem';
|
import FileItem from 'component/fileItem';
|
||||||
import SubscribeButton from 'component/subscribeButton';
|
import SubscribeButtonOverlay from 'component/subscribeButtonOverlay';
|
||||||
import subscriptionsStyle from 'styles/subscriptions';
|
import subscriptionsStyle from 'styles/subscriptions';
|
||||||
import Link from 'component/link';
|
import Link from 'component/link';
|
||||||
import Tag from 'component/tag';
|
import Tag from 'component/tag';
|
||||||
|
@ -31,6 +31,7 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { claim, isResolvingUri, navigation, thumbnail, title, uri } = this.props;
|
const { claim, isResolvingUri, navigation, thumbnail, title, uri } = this.props;
|
||||||
|
|
||||||
let shortUrl, tags;
|
let shortUrl, tags;
|
||||||
if (claim) {
|
if (claim) {
|
||||||
shortUrl = claim.short_url;
|
shortUrl = claim.short_url;
|
||||||
|
@ -49,7 +50,7 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={subscriptionsStyle.suggestedItem}>
|
<TouchableOpacity style={subscriptionsStyle.suggestedItem}>
|
||||||
<View style={[subscriptionsStyle.suggestedItemThumbnailContainer, this.state.autoStyle]}>
|
<View style={[subscriptionsStyle.suggestedItemThumbnailContainer, this.state.autoStyle]}>
|
||||||
{hasThumbnail && (
|
{hasThumbnail && (
|
||||||
<Image style={subscriptionsStyle.suggestedItemThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} />
|
<Image style={subscriptionsStyle.suggestedItemThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} />
|
||||||
|
@ -62,35 +63,37 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={subscriptionsStyle.suggestedItemDetails}>
|
<View style={subscriptionsStyle.suggestedItemDetails}>
|
||||||
{title && (
|
<Text style={subscriptionsStyle.suggestedItemTitle} numberOfLines={2}>
|
||||||
<Text style={subscriptionsStyle.suggestedItemTitle} numberOfLines={1}>
|
{title || claim.name}
|
||||||
{title}
|
</Text>
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
{claim && (
|
|
||||||
<Link
|
|
||||||
style={subscriptionsStyle.suggestedItemName}
|
|
||||||
numberOfLines={1}
|
|
||||||
text={claim.name}
|
|
||||||
onPress={() => navigateToUri(navigation, normalizeURI(shortUrl || uri), null, false, claim.permanent_url)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{tags && (
|
{tags && (
|
||||||
<View style={subscriptionsStyle.suggestedItemTagList}>
|
<View style={subscriptionsStyle.suggestedItemTagList}>
|
||||||
{tags &&
|
{tags &&
|
||||||
tags
|
tags
|
||||||
.slice(0, 3)
|
.slice(0, 1)
|
||||||
.map(tag => (
|
.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>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{claim && (
|
{claim && (
|
||||||
<SubscribeButton style={subscriptionsStyle.suggestedItemSubscribe} uri={normalizeURI(claim.permanent_url)} />
|
<SubscribeButtonOverlay
|
||||||
|
claim={claim}
|
||||||
|
style={subscriptionsStyle.suggestedItemSubscribeOverlay}
|
||||||
|
uri={normalizeURI(claim.permanent_url)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</View>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
30
src/component/suggestedSubscriptionsGrid/index.js
Normal file
30
src/component/suggestedSubscriptionsGrid/index.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import {
|
||||||
|
doClaimSearch,
|
||||||
|
selectFetchingClaimSearch,
|
||||||
|
selectClaimSearchByQuery,
|
||||||
|
selectClaimSearchByQueryLastPageReached,
|
||||||
|
selectFollowedTags,
|
||||||
|
} from 'lbry-redux';
|
||||||
|
import { selectSubscriptions, selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc';
|
||||||
|
import { selectShowNsfw } from 'redux/selectors/settings';
|
||||||
|
import SuggestedSubscriptionsGrid from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
followedTags: selectFollowedTags(state),
|
||||||
|
subscriptions: selectSubscriptions(state),
|
||||||
|
suggested: selectSuggestedChannels(state),
|
||||||
|
loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state),
|
||||||
|
claimSearchByQuery: selectClaimSearchByQuery(state),
|
||||||
|
lastPageReached: selectClaimSearchByQueryLastPageReached(state),
|
||||||
|
showNsfwContent: selectShowNsfw(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
claimSearch: options => dispatch(doClaimSearch(options)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform,
|
||||||
|
)(SuggestedSubscriptionsGrid);
|
100
src/component/suggestedSubscriptionsGrid/view.js
Normal file
100
src/component/suggestedSubscriptionsGrid/view.js
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ActivityIndicator, SectionList, Text, View } from 'react-native';
|
||||||
|
import { MATURE_TAGS, createNormalizedClaimSearchKey, normalizeURI } from 'lbry-redux';
|
||||||
|
import { navigateToUri } from 'utils/helper';
|
||||||
|
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: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
buildClaimSearchOptions() {
|
||||||
|
const { showNsfwContent, subscriptions } = this.props;
|
||||||
|
const { currentPage } = this.state;
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
no_totals: true,
|
||||||
|
page: currentPage,
|
||||||
|
page_size: suggestedPageSize,
|
||||||
|
claim_type: 'channel',
|
||||||
|
order_by: [Constants.ORDER_BY_EFFECTIVE_AMOUNT],
|
||||||
|
};
|
||||||
|
if (!showNsfwContent) {
|
||||||
|
options.not_tags = MATURE_TAGS;
|
||||||
|
}
|
||||||
|
/* if (subscriptions && subscriptions.length > 0) {
|
||||||
|
options.not_channel_ids = subscriptions.map(subscription => subscription.uri.split('#')[1]);
|
||||||
|
} */
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
doClaimSearch() {
|
||||||
|
const { claimSearch } = this.props;
|
||||||
|
const options = this.buildClaimSearchOptions();
|
||||||
|
claimSearch(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleVerticalEndReached = () => {
|
||||||
|
// fetch more content
|
||||||
|
const { claimSearchByQuery, lastPageReached } = this.props;
|
||||||
|
|
||||||
|
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
|
||||||
|
initialNumToRender={24}
|
||||||
|
maxToRenderPerBatch={48}
|
||||||
|
removeClippedSubviews
|
||||||
|
itemDimension={120}
|
||||||
|
spacing={2}
|
||||||
|
items={claimSearchUris}
|
||||||
|
style={inModal ? subscriptionsStyle.modalScrollContainer : subscriptionsStyle.scrollContainer}
|
||||||
|
contentContainerStyle={
|
||||||
|
inModal ? subscriptionsStyle.modalSuggestedScrollContent : subscriptionsStyle.suggestedScrollContent
|
||||||
|
}
|
||||||
|
renderItem={({ item, index }) => (
|
||||||
|
<SuggestedSubscriptionItem key={item} uri={normalizeURI(item)} navigation={navigation} />
|
||||||
|
)}
|
||||||
|
onEndReached={this.handleVerticalEndReached}
|
||||||
|
onEndReachedThreshold={0.2}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SuggestedSubscriptionsGrid;
|
|
@ -30,7 +30,7 @@ export default class Tag extends React.PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { name, onPress, style, type, truncate } = this.props;
|
const { name, numberOfLines, onPress, style, type, truncate } = this.props;
|
||||||
|
|
||||||
let styles = [];
|
let styles = [];
|
||||||
if (style) {
|
if (style) {
|
||||||
|
@ -50,7 +50,9 @@ export default class Tag extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity style={styles} onPress={onPress || this.onPressDefault}>
|
<TouchableOpacity style={styles} onPress={onPress || this.onPressDefault}>
|
||||||
<View style={tagStyle.content}>
|
<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} />}
|
{type && <Icon style={tagStyle.icon} name={type === 'add' ? 'plus' : 'times'} size={8} />}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
|
@ -64,9 +64,7 @@ class DiscoverPage extends React.PureComponent {
|
||||||
|
|
||||||
onComponentFocused = () => {
|
onComponentFocused = () => {
|
||||||
const { pushDrawerStack, setPlayerVisible, currentRoute } = this.props;
|
const { pushDrawerStack, setPlayerVisible, currentRoute } = this.props;
|
||||||
if (currentRoute === Constants.DRAWER_ROUTE_DISCOVER) {
|
pushDrawerStack();
|
||||||
pushDrawerStack();
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeModules.Firebase.setCurrentScreen('Your tags');
|
NativeModules.Firebase.setCurrentScreen('Your tags');
|
||||||
setPlayerVisible();
|
setPlayerVisible();
|
||||||
|
|
|
@ -26,10 +26,14 @@ const select = state => ({
|
||||||
query: selectSearchValue(state),
|
query: selectSearchValue(state),
|
||||||
resolvingUris: selectResolvingUris(state),
|
resolvingUris: selectResolvingUris(state),
|
||||||
showNsfwContent: selectShowNsfw(state),
|
showNsfwContent: selectShowNsfw(state),
|
||||||
uris: makeSelectSearchUris(makeSelectQueryWithOptions(null, Constants.DEFAULT_PAGE_SIZE)(state))(state),
|
uris: makeSelectSearchUris(
|
||||||
results: makeSelectResolvedSearchResults(makeSelectQueryWithOptions(null, Constants.DEFAULT_PAGE_SIZE)(state))(state),
|
makeSelectQueryWithOptions(null, { size: Constants.DEFAULT_PAGE_SIZE, isBackgroundSearch: false })(state),
|
||||||
|
)(state),
|
||||||
|
results: makeSelectResolvedSearchResults(
|
||||||
|
makeSelectQueryWithOptions(null, { size: Constants.DEFAULT_PAGE_SIZE, isBackgroundSearch: false })(state),
|
||||||
|
)(state),
|
||||||
lastPageReached: makeSelectResolvedSearchResultsLastPageReached(
|
lastPageReached: makeSelectResolvedSearchResultsLastPageReached(
|
||||||
makeSelectQueryWithOptions(null, Constants.DEFAULT_PAGE_SIZE)(state),
|
makeSelectQueryWithOptions(null, { size: Constants.DEFAULT_PAGE_SIZE, isBackgroundSearch: false })(state),
|
||||||
)(state),
|
)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,13 @@ import {
|
||||||
selectSubscriptionClaims,
|
selectSubscriptionClaims,
|
||||||
selectSubscriptions,
|
selectSubscriptions,
|
||||||
selectIsFetchingSubscriptions,
|
selectIsFetchingSubscriptions,
|
||||||
selectIsFetchingSuggested,
|
|
||||||
selectSuggestedChannels,
|
selectSuggestedChannels,
|
||||||
selectUnreadSubscriptions,
|
selectUnreadSubscriptions,
|
||||||
selectViewMode,
|
selectViewMode,
|
||||||
selectFirstRunCompleted,
|
selectFirstRunCompleted,
|
||||||
selectShowSuggestedSubs,
|
selectShowSuggestedSubs,
|
||||||
} from 'lbryinc';
|
} from 'lbryinc';
|
||||||
|
import { doToast, selectFetchingClaimSearch } from 'lbry-redux';
|
||||||
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||||
import { doSetClientSetting, doSetTimeItem } from 'redux/actions/settings';
|
import { doSetClientSetting, doSetTimeItem } from 'redux/actions/settings';
|
||||||
import { makeSelectClientSetting, selectTimeItem } from 'redux/selectors/settings';
|
import { makeSelectClientSetting, selectTimeItem } from 'redux/selectors/settings';
|
||||||
|
@ -24,7 +24,7 @@ import SubscriptionsPage from './view';
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
currentRoute: selectCurrentRoute(state),
|
currentRoute: selectCurrentRoute(state),
|
||||||
loading: selectIsFetchingSubscriptions(state),
|
loading: selectIsFetchingSubscriptions(state),
|
||||||
loadingSuggested: selectIsFetchingSuggested(state),
|
loadingSuggested: selectFetchingClaimSearch(state),
|
||||||
subscribedChannels: selectSubscriptions(state),
|
subscribedChannels: selectSubscriptions(state),
|
||||||
suggestedChannels: selectSuggestedChannels(state),
|
suggestedChannels: selectSuggestedChannels(state),
|
||||||
subscriptionsViewMode: makeSelectClientSetting(Constants.SETTING_SUBSCRIPTIONS_VIEW_MODE)(state),
|
subscriptionsViewMode: makeSelectClientSetting(Constants.SETTING_SUBSCRIPTIONS_VIEW_MODE)(state),
|
||||||
|
@ -41,6 +41,7 @@ const perform = dispatch => ({
|
||||||
doFetchMySubscriptions: () => dispatch(doFetchMySubscriptions()),
|
doFetchMySubscriptions: () => dispatch(doFetchMySubscriptions()),
|
||||||
doFetchRecommendedSubscriptions: () => dispatch(doFetchRecommendedSubscriptions()),
|
doFetchRecommendedSubscriptions: () => dispatch(doFetchRecommendedSubscriptions()),
|
||||||
doSetViewMode: viewMode => dispatch(doSetViewMode(viewMode)),
|
doSetViewMode: viewMode => dispatch(doSetViewMode(viewMode)),
|
||||||
|
notify: data => dispatch(doToast(data)),
|
||||||
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SUBSCRIPTIONS)),
|
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SUBSCRIPTIONS)),
|
||||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||||
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
||||||
|
@ -49,5 +50,5 @@ const perform = dispatch => ({
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
select,
|
select,
|
||||||
perform
|
perform,
|
||||||
)(SubscriptionsPage);
|
)(SubscriptionsPage);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import ModalPicker from 'component/modalPicker';
|
||||||
import ModalSuggestedSubscriptions from 'component/modalSuggestedSubscriptions';
|
import ModalSuggestedSubscriptions from 'component/modalSuggestedSubscriptions';
|
||||||
import SubscribedChannelList from 'component/subscribedChannelList';
|
import SubscribedChannelList from 'component/subscribedChannelList';
|
||||||
import SuggestedSubscriptions from 'component/suggestedSubscriptions';
|
import SuggestedSubscriptions from 'component/suggestedSubscriptions';
|
||||||
|
import SuggestedSubscriptionsGrid from 'component/suggestedSubscriptionsGrid';
|
||||||
import UriBar from 'component/uriBar';
|
import UriBar from 'component/uriBar';
|
||||||
|
|
||||||
class SubscriptionsPage extends React.PureComponent {
|
class SubscriptionsPage extends React.PureComponent {
|
||||||
|
@ -56,6 +57,7 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
|
|
||||||
onComponentFocused = () => {
|
onComponentFocused = () => {
|
||||||
const {
|
const {
|
||||||
|
currentRoute,
|
||||||
doFetchMySubscriptions,
|
doFetchMySubscriptions,
|
||||||
doFetchRecommendedSubscriptions,
|
doFetchRecommendedSubscriptions,
|
||||||
doSetViewMode,
|
doSetViewMode,
|
||||||
|
@ -64,12 +66,13 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
subscriptionsViewMode,
|
subscriptionsViewMode,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
pushDrawerStack();
|
if (currentRoute === Constants.DRAWER_ROUTE_SUBSCRIPTIONS) {
|
||||||
|
pushDrawerStack();
|
||||||
|
}
|
||||||
setPlayerVisible();
|
setPlayerVisible();
|
||||||
NativeModules.Firebase.setCurrentScreen('Subscriptions');
|
NativeModules.Firebase.setCurrentScreen('Subscriptions');
|
||||||
|
|
||||||
doFetchMySubscriptions();
|
doFetchMySubscriptions();
|
||||||
doFetchRecommendedSubscriptions();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -90,6 +93,15 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
this.setState({ currentSortByItem: item, orderBy: getOrderBy(item), showSortPicker: false });
|
this.setState({ currentSortByItem: item, orderBy: getOrderBy(item), showSortPicker: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
const { showModalSuggestedSubs: prevShowModalSuggestedSubs } = this.state;
|
||||||
|
const { showModalSuggestedSubs } = this.state;
|
||||||
|
if (prevShowModalSuggestedSubs && showModalSuggestedSubs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
handleTimeItemSelected = item => {
|
handleTimeItemSelected = item => {
|
||||||
const { setTimeItem } = this.props;
|
const { setTimeItem } = this.props;
|
||||||
setTimeItem(item);
|
setTimeItem(item);
|
||||||
|
@ -138,6 +150,7 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
timeItem,
|
timeItem,
|
||||||
unreadSubscriptions,
|
unreadSubscriptions,
|
||||||
navigation,
|
navigation,
|
||||||
|
notify,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { currentSortByItem, filteredChannels, showModalSuggestedSubs, showSortPicker, showTimePicker } = this.state;
|
const { currentSortByItem, filteredChannels, showModalSuggestedSubs, showSortPicker, showTimePicker } = this.state;
|
||||||
|
|
||||||
|
@ -164,7 +177,11 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
<View style={subscriptionsStyle.container}>
|
<View style={subscriptionsStyle.container}>
|
||||||
<UriBar navigation={navigation} belowOverlay={this.state.showSortPicker} />
|
<UriBar navigation={navigation} belowOverlay={this.state.showSortPicker} />
|
||||||
<View style={subscriptionsStyle.titleRow}>
|
<View style={subscriptionsStyle.titleRow}>
|
||||||
<Text style={subscriptionsStyle.pageTitle}>{__('Channels you follow')}</Text>
|
<Text style={subscriptionsStyle.pageTitle}>
|
||||||
|
{hasSubscriptions && !this.state.showingSuggestedSubs
|
||||||
|
? __('Channels you follow')
|
||||||
|
: __('Find Channels to follow')}
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
{!this.state.showingSuggestedSubs && hasSubscriptions && (
|
{!this.state.showingSuggestedSubs && hasSubscriptions && (
|
||||||
<View style={subscriptionsStyle.pickerRow}>
|
<View style={subscriptionsStyle.pickerRow}>
|
||||||
|
@ -190,7 +207,7 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
style={subscriptionsStyle.suggestedLink}
|
style={subscriptionsStyle.suggestedLink}
|
||||||
text={__('Suggested')}
|
text={__('Discover')}
|
||||||
onPress={() => this.setState({ showModalSuggestedSubs: true })}
|
onPress={() => this.setState({ showModalSuggestedSubs: true })}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -220,39 +237,38 @@ class SubscriptionsPage extends React.PureComponent {
|
||||||
|
|
||||||
{this.state.showingSuggestedSubs && (
|
{this.state.showingSuggestedSubs && (
|
||||||
<View style={subscriptionsStyle.suggestedSubsContainer}>
|
<View style={subscriptionsStyle.suggestedSubsContainer}>
|
||||||
{!hasSubscriptions && (
|
<View style={subscriptionsStyle.infoArea}>
|
||||||
<View style={subscriptionsStyle.infoArea}>
|
<Text style={subscriptionsStyle.infoText}>
|
||||||
<Text style={subscriptionsStyle.infoText}>
|
{__('LBRY works better if you follow at least 5 creators you like.')}
|
||||||
{__('You are not subscribed to any channels at the moment.')}
|
</Text>
|
||||||
</Text>
|
</View>
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{hasSubscriptions && (
|
<View style={subscriptionsStyle.mainSuggested}>
|
||||||
<View style={subscriptionsStyle.infoArea}>
|
<SuggestedSubscriptionsGrid navigation={navigation} />
|
||||||
<Text style={subscriptionsStyle.infoText}>
|
</View>
|
||||||
You are currently subscribed to {numberOfSubscriptions} channel{numberOfSubscriptions > 1 ? 's' : ''}.
|
|
||||||
</Text>
|
<Button
|
||||||
<Button
|
style={subscriptionsStyle.suggestedDoneButton}
|
||||||
style={subscriptionsStyle.button}
|
text={
|
||||||
text={__('View my subscriptions')}
|
numberOfSubscriptions < 5
|
||||||
onPress={() => this.setState({ showingSuggestedSubs: false })}
|
? __('%remaining% more...', { remaining: 5 - numberOfSubscriptions })
|
||||||
/>
|
: __('Done')
|
||||||
</View>
|
}
|
||||||
)}
|
onPress={() => {
|
||||||
|
if (!hasSubscriptions) {
|
||||||
|
notify({ message: __('Tap on any channel to follow') });
|
||||||
|
} else {
|
||||||
|
this.setState({ showingSuggestedSubs: false });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{loadingSuggested && (
|
{loadingSuggested && (
|
||||||
<View style={subscriptionsStyle.centered}>
|
<ActivityIndicator size="small" color={Colors.White} style={subscriptionsStyle.suggestedLoading} />
|
||||||
<ActivityIndicator size="large" colors={Colors.NextLbryGreen} style={subscriptionsStyle.loading} />
|
|
||||||
</View>
|
|
||||||
)}
|
)}
|
||||||
{!loadingSuggested && <SuggestedSubscriptions navigation={navigation} />}
|
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!showSortPicker && !showTimePicker && !showModalSuggestedSubs && (
|
|
||||||
<FloatingWalletBalance navigation={navigation} />
|
|
||||||
)}
|
|
||||||
{showSortPicker && (
|
{showSortPicker && (
|
||||||
<ModalPicker
|
<ModalPicker
|
||||||
title={__('Sort content by')}
|
title={__('Sort content by')}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
|
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
stack: [{ route: Constants.DRAWER_ROUTE_DISCOVER, params: {} }], // Discover is always the first drawer route
|
stack: [{ route: Constants.DRAWER_ROUTE_SUBSCRIPTIONS, params: {} }], // Following is always the first drawer route
|
||||||
lastRouteInStack: {},
|
lastRouteInStack: {},
|
||||||
playerVisible: false,
|
playerVisible: false,
|
||||||
playerVisibleByUri: {},
|
playerVisibleByUri: {},
|
||||||
|
@ -42,7 +42,7 @@ reducers[Constants.ACTION_PUSH_DRAWER_STACK] = (state, action) => {
|
||||||
if (lastRoute === Constants.DRAWER_ROUTE_PUBLISH_FORM && routeName === Constants.DRAWER_ROUTE_PUBLISH) {
|
if (lastRoute === Constants.DRAWER_ROUTE_PUBLISH_FORM && routeName === Constants.DRAWER_ROUTE_PUBLISH) {
|
||||||
canPushStack = false;
|
canPushStack = false;
|
||||||
}
|
}
|
||||||
if (routeName === Constants.DRAWER_ROUTE_DISCOVER && newStack.length === 1) {
|
if (routeName === Constants.DRAWER_ROUTE_SUBSCRIPTIONS && newStack.length === 1) {
|
||||||
canPushStack = false;
|
canPushStack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,24 @@ const modalPickerStyle = StyleSheet.create({
|
||||||
bottom: 8,
|
bottom: 8,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
},
|
},
|
||||||
|
wideButtons: {
|
||||||
|
marginTop: 16,
|
||||||
|
left: 8,
|
||||||
|
bottom: 8,
|
||||||
|
right: 8,
|
||||||
|
position: 'absolute',
|
||||||
|
},
|
||||||
doneButton: {
|
doneButton: {
|
||||||
alignSelf: 'flex-start',
|
alignSelf: 'flex-start',
|
||||||
backgroundColor: Colors.LbryGreen,
|
backgroundColor: Colors.LbryGreen,
|
||||||
paddingLeft: 16,
|
paddingLeft: 16,
|
||||||
paddingRight: 16,
|
paddingRight: 16,
|
||||||
},
|
},
|
||||||
|
wideDoneButton: {
|
||||||
|
backgroundColor: Colors.LbryGreen,
|
||||||
|
paddingLeft: 16,
|
||||||
|
paddingRight: 16,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default modalPickerStyle;
|
export default modalPickerStyle;
|
||||||
|
|
|
@ -38,11 +38,13 @@ const subscriptionsStyle = StyleSheet.create({
|
||||||
},
|
},
|
||||||
infoText: {
|
infoText: {
|
||||||
fontFamily: 'Inter-Regular',
|
fontFamily: 'Inter-Regular',
|
||||||
fontSize: 16,
|
fontSize: 14,
|
||||||
marginTop: 8,
|
marginTop: 8,
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
},
|
},
|
||||||
infoArea: {
|
infoArea: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
marginLeft: 16,
|
marginLeft: 16,
|
||||||
marginRight: 16,
|
marginRight: 16,
|
||||||
paddingBottom: 4,
|
paddingBottom: 4,
|
||||||
|
@ -188,11 +190,11 @@ const subscriptionsStyle = StyleSheet.create({
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
suggestedItem: {
|
suggestedItem: {
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
marginLeft: 16,
|
marginLeft: 16,
|
||||||
marginRight: 16,
|
marginRight: 16,
|
||||||
|
height: 140,
|
||||||
},
|
},
|
||||||
suggestedItemThumbnailContainer: {
|
suggestedItemThumbnailContainer: {
|
||||||
width: 70,
|
width: 70,
|
||||||
|
@ -209,30 +211,37 @@ const subscriptionsStyle = StyleSheet.create({
|
||||||
suggestedItemDetails: {
|
suggestedItemDetails: {
|
||||||
marginLeft: 16,
|
marginLeft: 16,
|
||||||
marginRight: 16,
|
marginRight: 16,
|
||||||
flex: 0.8,
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
suggestedItemSubscribe: {
|
suggestedItemSubscribe: {
|
||||||
backgroundColor: Colors.White,
|
backgroundColor: Colors.White,
|
||||||
|
},
|
||||||
|
suggestedItemSubscribeOverlay: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
paddingBottom: 4,
|
||||||
|
height: 70,
|
||||||
},
|
},
|
||||||
suggestedItemTitle: {
|
suggestedItemTitle: {
|
||||||
fontFamily: 'Inter-Regular',
|
fontFamily: 'Inter-Regular',
|
||||||
fontSize: 16,
|
textAlign: 'center',
|
||||||
marginBottom: 4,
|
fontSize: 14,
|
||||||
width: '85%',
|
marginTop: 4,
|
||||||
|
marginBottom: 2,
|
||||||
},
|
},
|
||||||
suggestedItemName: {
|
suggestedItemName: {
|
||||||
fontFamily: 'Inter-SemiBold',
|
fontFamily: 'Inter-SemiBold',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
marginBottom: 4,
|
marginBottom: 4,
|
||||||
color: Colors.LbryGreen,
|
color: Colors.LbryGreen,
|
||||||
width: '95%',
|
|
||||||
},
|
},
|
||||||
suggestedItemTagList: {
|
suggestedItemTagList: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
flexWrap: 'wrap',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
suggestedSubTitle: {
|
suggestedSubTitle: {
|
||||||
fontFamily: 'Inter-Regular',
|
fontFamily: 'Inter-Regular',
|
||||||
|
@ -266,6 +275,23 @@ const subscriptionsStyle = StyleSheet.create({
|
||||||
modalSuggestedScrollContent: {
|
modalSuggestedScrollContent: {
|
||||||
paddingTop: 16,
|
paddingTop: 16,
|
||||||
},
|
},
|
||||||
|
suggestedDoneButton: {
|
||||||
|
backgroundColor: Colors.LbryGreen,
|
||||||
|
margin: 16,
|
||||||
|
},
|
||||||
|
mainSuggested: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
suggestedLoading: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: 24,
|
||||||
|
bottom: 22,
|
||||||
|
},
|
||||||
|
modalLoading: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: 7,
|
||||||
|
bottom: 7,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default subscriptionsStyle;
|
export default subscriptionsStyle;
|
||||||
|
|
Loading…
Add table
Reference in a new issue