Fix release blockers (#10)
This commit is contained in:
parent
4b7f3f140a
commit
1e0a636b4f
47 changed files with 405 additions and 241 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -5562,8 +5562,8 @@
|
|||
}
|
||||
},
|
||||
"lbry-redux": {
|
||||
"version": "github:lbryio/lbry-redux#cd23c12fb7fd541d28d7cbf3874b1058b036fd13",
|
||||
"from": "github:lbryio/lbry-redux#cd23c12fb7fd541d28d7cbf3874b1058b036fd13",
|
||||
"version": "github:lbryio/lbry-redux#4e5e51b99b730cc834747edb9fd7d87d47a7d4f9",
|
||||
"from": "github:lbryio/lbry-redux#4e5e51b99b730cc834747edb9fd7d87d47a7d4f9",
|
||||
"requires": {
|
||||
"proxy-polyfill": "0.1.6",
|
||||
"reselect": "^3.0.0",
|
||||
|
@ -5571,8 +5571,8 @@
|
|||
}
|
||||
},
|
||||
"lbryinc": {
|
||||
"version": "github:lbryio/lbryinc#2cc861145e79ed59478c150ac63f5ffc5fc2ad28",
|
||||
"from": "github:lbryio/lbryinc",
|
||||
"version": "github:lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
|
||||
"from": "github:lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
|
||||
"requires": {
|
||||
"reselect": "^3.0.0"
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"base-64": "^0.1.0",
|
||||
"@expo/vector-icons": "^8.1.0",
|
||||
"gfycat-style-urls": "^1.0.3",
|
||||
"lbry-redux": "lbryio/lbry-redux#67a654f60630710cae72419448a73a18d076d18a",
|
||||
"lbryinc": "lbryio/lbryinc",
|
||||
"lbry-redux": "lbryio/lbry-redux#4e5e51b99b730cc834747edb9fd7d87d47a7d4f9",
|
||||
"lbryinc": "lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
|
||||
"lodash": ">=4.17.11",
|
||||
"merge": ">=1.2.1",
|
||||
"moment": "^2.22.1",
|
||||
|
|
|
@ -127,79 +127,83 @@ const walletStack = createStackNavigator(
|
|||
}
|
||||
);
|
||||
|
||||
const drawerIconSize = 18;
|
||||
const drawer = createDrawerNavigator(
|
||||
{
|
||||
DiscoverStack: {
|
||||
screen: discoverStack,
|
||||
navigationOptions: {
|
||||
title: 'Explore',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="home" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="home" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
TrendingStack: {
|
||||
screen: TrendingPage,
|
||||
navigationOptions: {
|
||||
title: 'Trending',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="fire" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="fire" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
MySubscriptionsStack: {
|
||||
screen: SubscriptionsPage,
|
||||
navigationOptions: {
|
||||
title: 'Subscriptions',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="heart" solid size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="heart" solid size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
WalletStack: {
|
||||
screen: walletStack,
|
||||
navigationOptions: {
|
||||
title: 'Wallet',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="wallet" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="wallet" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
Publish: {
|
||||
screen: PublishPage,
|
||||
navigationOptions: {
|
||||
drawerIcon: ({ tintColor }) => <Icon name="upload" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="upload" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
Publishes: {
|
||||
screen: PublishesPage,
|
||||
navigationOptions: {
|
||||
drawerIcon: ({ tintColor }) => <Icon name="cloud-upload-alt" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => (
|
||||
<Icon name="cloud-upload-alt" size={drawerIconSize} style={{ color: tintColor }} />
|
||||
),
|
||||
},
|
||||
},
|
||||
Rewards: {
|
||||
screen: RewardsPage,
|
||||
navigationOptions: {
|
||||
drawerIcon: ({ tintColor }) => <Icon name="award" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="award" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
MyLBRYStack: {
|
||||
Downloads: {
|
||||
screen: DownloadsPage,
|
||||
navigationOptions: {
|
||||
title: 'Library',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="download" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="download" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
Settings: {
|
||||
screen: SettingsPage,
|
||||
navigationOptions: {
|
||||
drawerLockMode: 'locked-closed',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="cog" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="cog" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
About: {
|
||||
screen: AboutPage,
|
||||
navigationOptions: {
|
||||
drawerLockMode: 'locked-closed',
|
||||
drawerIcon: ({ tintColor }) => <Icon name="info" size={20} style={{ color: tintColor }} />,
|
||||
drawerIcon: ({ tintColor }) => <Icon name="info" size={drawerIconSize} style={{ color: tintColor }} />,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
drawerWidth: 300,
|
||||
headerMode: 'none',
|
||||
backBehavior: 'none',
|
||||
unmountInactiveRoutes: true,
|
||||
contentComponent: DrawerContent,
|
||||
contentOptions: {
|
||||
|
@ -314,6 +318,7 @@ class AppWithNavigationState extends React.Component {
|
|||
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'false');
|
||||
this.setState({ verifyPending: false });
|
||||
|
||||
NativeModules.Firebase.track('email_verified', { email: user.primary_email });
|
||||
ToastAndroid.show('Your email address was successfully verified.', ToastAndroid.LONG);
|
||||
|
||||
// upon successful email verification, do wallet sync (if password has been set)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react';
|
||||
import { CLAIM_VALUES, isNameValid } from 'lbry-redux';
|
||||
import { CLAIM_VALUES, isURIValid } from 'lbry-redux';
|
||||
import { ActivityIndicator, Picker, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import Button from 'component/button';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||
import Link from 'component/link';
|
||||
import channelSelectorStyle from 'styles/channelSelector';
|
||||
|
@ -102,7 +102,7 @@ export default class ChannelSelector extends React.PureComponent {
|
|||
const { balance, createChannel, onChannelChange, notify } = this.props;
|
||||
const { newChannelBid, newChannelName } = this.state;
|
||||
|
||||
if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) {
|
||||
if (newChannelName.trim().length === 0 || !isURIValid(newChannelName.substr(1), false)) {
|
||||
notify({ message: 'Your channel name contains invalid characters.' });
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
selectFetchingClaimSearch,
|
||||
selectLastClaimSearchUris,
|
||||
} from 'lbry-redux';
|
||||
import { selectShowNsfw } from 'redux/selectors/settings';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import ClaimList from './view';
|
||||
|
||||
|
@ -18,6 +19,7 @@ const select = (state, props) => {
|
|||
// for subscriptions
|
||||
claimSearchLoading: selectFetchingClaimSearch(state),
|
||||
claimSearchUris: selectLastClaimSearchUris(state),
|
||||
showNsfwContent: selectShowNsfw(state),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -34,7 +36,6 @@ const perform = dispatch => ({
|
|||
no_totals: true,
|
||||
order_by: orderBy,
|
||||
page,
|
||||
not_tags: MATURE_TAGS,
|
||||
},
|
||||
additionalOptions
|
||||
)
|
||||
|
|
|
@ -31,6 +31,7 @@ class ClaimList extends React.PureComponent {
|
|||
claimSearch,
|
||||
orderBy = Constants.DEFAULT_ORDER_BY,
|
||||
searchByTags,
|
||||
showNsfwContent,
|
||||
tags,
|
||||
time,
|
||||
} = this.props;
|
||||
|
@ -38,9 +39,11 @@ class ClaimList extends React.PureComponent {
|
|||
const options = {
|
||||
order_by: orderBy,
|
||||
no_totals: true,
|
||||
not_tags: MATURE_TAGS,
|
||||
page: this.state.currentPage,
|
||||
};
|
||||
if (!showNsfwContent) {
|
||||
options.not_tags = MATURE_TAGS;
|
||||
}
|
||||
if (channelIds) {
|
||||
this.setState({ subscriptionsView: true });
|
||||
options.channel_ids = channelIds;
|
||||
|
@ -54,6 +57,9 @@ class ClaimList extends React.PureComponent {
|
|||
if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) {
|
||||
additionalOptions.release_time = this.getReleaseTimeOption(time);
|
||||
}
|
||||
if (!showNsfwContent) {
|
||||
additionalOptions.not_tags = MATURE_TAGS;
|
||||
}
|
||||
searchByTags(tags, orderBy, this.state.currentPage, additionalOptions);
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +73,7 @@ class ClaimList extends React.PureComponent {
|
|||
channelIds: prevChannelIds,
|
||||
trendingForAll: prevTrendingForAll,
|
||||
time: prevTime,
|
||||
showNsfwContent,
|
||||
} = this.props;
|
||||
const { orderBy, tags, channelIds, trendingForAll, time } = nextProps;
|
||||
if (
|
||||
|
@ -85,9 +92,11 @@ class ClaimList extends React.PureComponent {
|
|||
const options = {
|
||||
order_by: orderBy,
|
||||
no_totals: true,
|
||||
not_tags: MATURE_TAGS,
|
||||
page: this.state.currentPage,
|
||||
};
|
||||
if (!showNsfwContent) {
|
||||
options.not_tags = MATURE_TAGS;
|
||||
}
|
||||
if (channelIds) {
|
||||
this.setState({ subscriptionsView: true });
|
||||
options.channel_ids = channelIds;
|
||||
|
@ -103,6 +112,9 @@ class ClaimList extends React.PureComponent {
|
|||
if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) {
|
||||
additionalOptions.release_time = this.getReleaseTimeOption(time);
|
||||
}
|
||||
if (!showNsfwContent) {
|
||||
additionalOptions.not_tags = MATURE_TAGS;
|
||||
}
|
||||
searchByTags(tags, orderBy, this.state.currentPage, additionalOptions);
|
||||
}
|
||||
});
|
||||
|
@ -119,7 +131,17 @@ class ClaimList extends React.PureComponent {
|
|||
|
||||
handleVerticalEndReached = () => {
|
||||
// fetch more content
|
||||
const { channelIds, claimSearch, claimSearchUris, orderBy, searchByTags, tags, time, uris } = this.props;
|
||||
const {
|
||||
channelIds,
|
||||
claimSearch,
|
||||
claimSearchUris,
|
||||
orderBy,
|
||||
searchByTags,
|
||||
showNsfwContent,
|
||||
tags,
|
||||
time,
|
||||
uris,
|
||||
} = this.props;
|
||||
const { subscriptionsView, trendingForAllView } = this.state;
|
||||
if ((claimSearchUris && claimSearchUris.length >= softLimit) || (uris && uris.length >= softLimit)) {
|
||||
// don't fetch more than the specified limit to be displayed
|
||||
|
@ -131,9 +153,11 @@ class ClaimList extends React.PureComponent {
|
|||
const options = {
|
||||
order_by: orderBy,
|
||||
no_totals: true,
|
||||
not_tags: MATURE_TAGS,
|
||||
page: this.state.currentPage,
|
||||
};
|
||||
if (!showNsfwContent) {
|
||||
options.not_tags = MATURE_TAGS;
|
||||
}
|
||||
if (subscriptionsView) {
|
||||
options.channel_ids = channelIds;
|
||||
}
|
||||
|
@ -144,6 +168,9 @@ class ClaimList extends React.PureComponent {
|
|||
if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) {
|
||||
additionalOptions.release_time = this.getReleaseTimeOption(time);
|
||||
}
|
||||
if (!showNsfwContent) {
|
||||
additionalOptions.not_tags = MATURE_TAGS;
|
||||
}
|
||||
searchByTags(tags, orderBy, this.state.currentPage, additionalOptions);
|
||||
}
|
||||
});
|
||||
|
@ -174,6 +201,29 @@ class ClaimList extends React.PureComponent {
|
|||
);
|
||||
};
|
||||
|
||||
renderVerticalItem = ({ item }) => {
|
||||
const { navigation } = this.props;
|
||||
return <FileListItem key={item} uri={item} style={claimListStyle.verticalListItem} navigation={navigation} />;
|
||||
};
|
||||
|
||||
renderHorizontalItem = ({ item }) => {
|
||||
const { navigation } = this.props;
|
||||
|
||||
return item === Constants.MORE_PLACEHOLDER ? (
|
||||
this.renderMorePlaceholder()
|
||||
) : (
|
||||
<FileItem
|
||||
style={discoverStyle.fileItem}
|
||||
mediaStyle={discoverStyle.fileItemMedia}
|
||||
key={item}
|
||||
uri={normalizeURI(item)}
|
||||
navigation={navigation}
|
||||
showDetails
|
||||
compactView={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
ListHeaderComponent,
|
||||
|
@ -202,9 +252,7 @@ class ClaimList extends React.PureComponent {
|
|||
initialNumToRender={10}
|
||||
maxToRenderPerBatch={20}
|
||||
removeClippedSubviews
|
||||
renderItem={({ item }) => (
|
||||
<FileListItem key={item} uri={item} style={claimListStyle.verticalListItem} navigation={navigation} />
|
||||
)}
|
||||
renderItem={this.renderVerticalItem}
|
||||
data={data}
|
||||
keyExtractor={(item, index) => item}
|
||||
onEndReached={this.handleVerticalEndReached}
|
||||
|
@ -235,21 +283,7 @@ class ClaimList extends React.PureComponent {
|
|||
initialNumToRender={3}
|
||||
maxToRenderPerBatch={3}
|
||||
removeClippedSubviews
|
||||
renderItem={({ item }) => {
|
||||
return item === Constants.MORE_PLACEHOLDER ? (
|
||||
this.renderMorePlaceholder()
|
||||
) : (
|
||||
<FileItem
|
||||
style={discoverStyle.fileItem}
|
||||
mediaStyle={discoverStyle.fileItemMedia}
|
||||
key={item}
|
||||
uri={normalizeURI(item)}
|
||||
navigation={navigation}
|
||||
showDetails
|
||||
compactView={false}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
renderItem={this.renderHorizontalItem}
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
data={uris ? this.appendMorePlaceholder(uris.slice(0, horizontalLimit)) : []}
|
||||
|
|
|
@ -50,13 +50,15 @@ class FileItem extends React.PureComponent {
|
|||
style,
|
||||
mediaStyle,
|
||||
navigation,
|
||||
nsfw,
|
||||
obscureNsfw,
|
||||
showDetails,
|
||||
compactView,
|
||||
titleBeforeThumbnail,
|
||||
} = this.props;
|
||||
|
||||
const uri = normalizeURI(this.props.uri);
|
||||
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
||||
const obscure = obscureNsfw && nsfw;
|
||||
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
|
||||
const signingChannel = claim ? claim.signing_channel : null;
|
||||
const channelName = signingChannel ? signingChannel.name : null;
|
||||
|
@ -75,7 +77,7 @@ class FileItem extends React.PureComponent {
|
|||
<FileItemMedia
|
||||
title={title}
|
||||
thumbnail={thumbnail}
|
||||
blurRadius={obscureNsfw ? 15 : 0}
|
||||
blurRadius={obscure ? 15 : 0}
|
||||
resizeMode="cover"
|
||||
isResolvingUri={isResolvingUri}
|
||||
style={mediaStyle}
|
||||
|
@ -106,13 +108,12 @@ class FileItem extends React.PureComponent {
|
|||
}}
|
||||
/>
|
||||
)}
|
||||
{!channelName && <Text style={discoverStyle.anonChannelName}>Anonymous</Text>}
|
||||
<DateTime style={discoverStyle.dateTime} textStyle={discoverStyle.dateTimeText} timeAgo uri={uri} />
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
{obscureNsfw && (
|
||||
<NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />
|
||||
)}
|
||||
{obscure && <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
makeSelectMetadataForUri,
|
||||
makeSelectFileInfoForUri,
|
||||
makeSelectIsUriResolving,
|
||||
makeSelectClaimIsNsfw,
|
||||
makeSelectTitleForUri,
|
||||
makeSelectThumbnailForUri,
|
||||
} from 'lbry-redux';
|
||||
|
@ -19,6 +20,7 @@ const select = (state, props) => ({
|
|||
filteredOutpoints: selectFilteredOutpoints(state),
|
||||
isDownloaded: !!makeSelectFileInfoForUri(props.uri)(state),
|
||||
metadata: makeSelectMetadataForUri(props.uri)(state),
|
||||
nsfw: makeSelectClaimIsNsfw(props.uri)(state),
|
||||
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
|
||||
obscureNsfw: !selectShowNsfw(state),
|
||||
title: makeSelectTitleForUri(props.uri)(state),
|
||||
|
|
|
@ -53,10 +53,12 @@ class FileListItem extends React.PureComponent {
|
|||
fileInfo,
|
||||
filteredOutpoints,
|
||||
metadata,
|
||||
nsfw,
|
||||
featuredResult,
|
||||
isResolvingUri,
|
||||
isDownloaded,
|
||||
style,
|
||||
obscureNsfw,
|
||||
onPress,
|
||||
navigation,
|
||||
thumbnail,
|
||||
|
@ -65,7 +67,7 @@ class FileListItem extends React.PureComponent {
|
|||
} = this.props;
|
||||
|
||||
const uri = normalizeURI(this.props.uri);
|
||||
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
||||
const obscure = obscureNsfw && nsfw;
|
||||
const isResolving = !fileInfo && isResolvingUri;
|
||||
|
||||
let name, channel, height, channelClaimId, fullChannelUri, shouldHide, signingChannel;
|
||||
|
@ -92,7 +94,7 @@ class FileListItem extends React.PureComponent {
|
|||
<TouchableOpacity style={style} onPress={onPress || this.defaultOnPress}>
|
||||
<FileItemMedia
|
||||
style={fileListStyle.thumbnail}
|
||||
blurRadius={obscureNsfw ? 15 : 0}
|
||||
blurRadius={obscure ? 15 : 0}
|
||||
resizeMode="cover"
|
||||
title={title || name}
|
||||
thumbnail={thumbnail}
|
||||
|
@ -155,9 +157,7 @@ class FileListItem extends React.PureComponent {
|
|||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
{obscureNsfw && (
|
||||
<NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />
|
||||
)}
|
||||
{obscure && <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ export default class ModalTagSelector extends React.PureComponent {
|
|||
}
|
||||
|
||||
this.props.doToggleTagFollow(tag);
|
||||
if (window.persistor) {
|
||||
window.persistor.flush();
|
||||
}
|
||||
NativeModules.Firebase.track('tag_follow', { tag });
|
||||
};
|
||||
|
||||
|
@ -32,6 +35,9 @@ export default class ModalTagSelector extends React.PureComponent {
|
|||
}
|
||||
|
||||
this.props.doToggleTagFollow(tag);
|
||||
if (window.persistor) {
|
||||
window.persistor.flush();
|
||||
}
|
||||
NativeModules.Firebase.track('tag_unfollow', { tag });
|
||||
};
|
||||
|
||||
|
|
|
@ -5,17 +5,27 @@ import Button from 'component/button';
|
|||
import Colors from 'styles/colors';
|
||||
|
||||
class SubscribeNotificationButton extends React.PureComponent {
|
||||
render() {
|
||||
handlePress = () => {
|
||||
const {
|
||||
uri,
|
||||
name,
|
||||
doChannelSubscriptionEnableNotifications,
|
||||
doChannelSubscriptionDisableNotifications,
|
||||
doToast,
|
||||
enabledChannelNotifications,
|
||||
isSubscribed,
|
||||
style,
|
||||
} = this.props;
|
||||
const shouldNotify = enabledChannelNotifications.indexOf(name) > -1;
|
||||
|
||||
if (shouldNotify) {
|
||||
doChannelSubscriptionDisableNotifications(name);
|
||||
doToast({ message: 'You will not receive notifications for new content.' });
|
||||
} else {
|
||||
doChannelSubscriptionEnableNotifications(name);
|
||||
doToast({ message: 'You will receive all notifications for new content.' });
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { enabledChannelNotifications, name, uri, isSubscribed, style } = this.props;
|
||||
|
||||
if (!isSubscribed) {
|
||||
return null;
|
||||
|
@ -31,23 +41,14 @@ class SubscribeNotificationButton extends React.PureComponent {
|
|||
}
|
||||
|
||||
const shouldNotify = enabledChannelNotifications.indexOf(name) > -1;
|
||||
const { claimName } = parseURI(uri);
|
||||
|
||||
return (
|
||||
<Button
|
||||
style={styles}
|
||||
theme={'light'}
|
||||
icon={shouldNotify ? 'bell-slash' : 'bell'}
|
||||
solid={true}
|
||||
onPress={() => {
|
||||
if (shouldNotify) {
|
||||
doChannelSubscriptionDisableNotifications(name);
|
||||
doToast({ message: 'You will not receive notifications for new content.' });
|
||||
} else {
|
||||
doChannelSubscriptionEnableNotifications(name);
|
||||
doToast({ message: 'You will receive all notifications for new content.' });
|
||||
}
|
||||
}}
|
||||
solid
|
||||
onPress={this.handlePress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import React from 'react';
|
||||
import { buildURI, normalizeURI } from 'lbry-redux';
|
||||
import { ActivityIndicator, FlatList, Image, Text, View } from 'react-native';
|
||||
import { navigateToUri } from 'utils/helper';
|
||||
import Colors from 'styles/colors';
|
||||
import discoverStyle from 'styles/discover';
|
||||
import FileItem from 'component/fileItem';
|
||||
import SubscribeButton from 'component/subscribeButton';
|
||||
import subscriptionsStyle from 'styles/subscriptions';
|
||||
import Link from 'component/link';
|
||||
import Tag from 'component/tag';
|
||||
|
||||
class SuggestedSubscriptionItem extends React.PureComponent {
|
||||
|
@ -47,15 +49,22 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
|||
{title}
|
||||
</Text>
|
||||
)}
|
||||
<Text style={subscriptionsStyle.suggestedItemName} numberOfLines={1}>
|
||||
{claim && claim.name}
|
||||
</Text>
|
||||
{claim && (
|
||||
<Link
|
||||
style={subscriptionsStyle.suggestedItemName}
|
||||
numberOfLines={1}
|
||||
text={claim.name}
|
||||
onPress={() => navigateToUri(navigation, normalizeURI(uri))}
|
||||
/>
|
||||
)}
|
||||
{tags && (
|
||||
<View style={subscriptionsStyle.suggestedItemTagList}>
|
||||
{tags &&
|
||||
tags
|
||||
.slice(0, 3)
|
||||
.map(tag => <Tag style={subscriptionsStyle.tag} key={tag} name={tag} navigation={navigation} />)}
|
||||
.map(tag => (
|
||||
<Tag style={subscriptionsStyle.tag} key={tag} name={tag} navigation={navigation} truncate />
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
import { MATURE_TAGS } from 'lbry-redux';
|
||||
import { formatTagName } from 'utils/helper';
|
||||
import tagStyle from 'styles/tag';
|
||||
import Colors from 'styles/colors';
|
||||
|
@ -29,7 +30,7 @@ export default class Tag extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { name, onPress, style, type } = this.props;
|
||||
const { name, onPress, style, type, truncate } = this.props;
|
||||
|
||||
let styles = [];
|
||||
if (style) {
|
||||
|
@ -41,7 +42,7 @@ export default class Tag extends React.PureComponent {
|
|||
}
|
||||
|
||||
styles.push({
|
||||
backgroundColor: Colors.TagGreen,
|
||||
backgroundColor: MATURE_TAGS.includes(name) ? Colors.TagGrape : Colors.TagGreen,
|
||||
borderRadius: 8,
|
||||
marginBottom: 4,
|
||||
});
|
||||
|
@ -49,7 +50,7 @@ export default class Tag extends React.PureComponent {
|
|||
return (
|
||||
<TouchableOpacity style={styles} onPress={onPress || this.onPressDefault}>
|
||||
<View style={tagStyle.content}>
|
||||
<Text style={tagStyle.text}>{formatTagName(name)}</Text>
|
||||
<Text style={tagStyle.text}>{truncate ? formatTagName(name) : name}</Text>
|
||||
{type && <Icon style={tagStyle.icon} name={type === 'add' ? 'plus' : 'times'} size={8} />}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { KeyboardAvoidingView, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import { MATURE_TAGS } from 'lbry-redux';
|
||||
import Tag from 'component/tag';
|
||||
import tagStyle from 'styles/tag';
|
||||
import Colors from 'styles/colors';
|
||||
|
@ -66,7 +67,7 @@ export default class TagSearch extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { name, style, type, selectedTags = [] } = this.props;
|
||||
const { name, style, type, selectedTags = [], showNsfwTags } = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
|
@ -85,6 +86,22 @@ export default class TagSearch extends React.PureComponent {
|
|||
))}
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
{showNsfwTags && (
|
||||
<View style={tagStyle.nsfwTagsContainer}>
|
||||
<Text style={tagStyle.nsfwTagsTitle}>Mature tags</Text>
|
||||
<View style={tagStyle.tagResultsList}>
|
||||
{MATURE_TAGS.map(tag => (
|
||||
<Tag
|
||||
key={tag}
|
||||
name={tag}
|
||||
style={tagStyle.tag}
|
||||
type="add"
|
||||
onAddPress={name => this.onAddTagPress(name)}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ const Constants = {
|
|||
ACTION_REACT_NAVIGATION_NAVIGATE: 'Navigation/NAVIGATE',
|
||||
ACTION_REACT_NAVIGATION_REPLACE: 'Navigation/REPLACE',
|
||||
|
||||
ACTION_SORT_BY_ITEM_CHANGED: 'SORT_BY_ITEM_CHANGED',
|
||||
|
||||
ORIENTATION_HORIZONTAL: 'horizontal',
|
||||
ORIENTATION_VERTICAL: 'vertical',
|
||||
|
||||
|
@ -79,7 +81,6 @@ const Constants = {
|
|||
FULL_ROUTE_NAME_TRENDING: 'TrendingStack',
|
||||
FULL_ROUTE_NAME_MY_SUBSCRIPTIONS: 'MySubscriptionsStack',
|
||||
FULL_ROUTE_NAME_WALLET: 'WalletStack',
|
||||
FULL_ROUTE_NAME_MY_LBRY: 'MyLBRYStack',
|
||||
|
||||
ROUTE_FILE: 'File',
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { Lbry } from 'lbry-redux';
|
||||
import { NativeModules, Text, View, ScrollView } from 'react-native';
|
||||
import { navigateBack } from 'utils/helper';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import Link from 'component/link';
|
||||
import PageHeader from 'component/pageHeader';
|
||||
import aboutStyle from 'styles/about';
|
||||
|
@ -18,7 +18,7 @@ class AboutPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -105,7 +105,7 @@ class AboutPage extends React.PureComponent {
|
|||
<Text style={aboutStyle.text}>Connected email</Text>
|
||||
</View>
|
||||
<View style={aboutStyle.col}>
|
||||
<Text selectable={true} style={aboutStyle.valueText}>
|
||||
<Text selectable style={aboutStyle.valueText}>
|
||||
{userEmail}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -125,7 +125,7 @@ class AboutPage extends React.PureComponent {
|
|||
<Text style={aboutStyle.text}>App version</Text>
|
||||
</View>
|
||||
<View style={aboutStyle.col}>
|
||||
<Text selectable={true} style={aboutStyle.valueText}>
|
||||
<Text selectable style={aboutStyle.valueText}>
|
||||
{this.state.appVersion}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -136,7 +136,7 @@ class AboutPage extends React.PureComponent {
|
|||
<Text style={aboutStyle.text}>Daemon (lbrynet)</Text>
|
||||
</View>
|
||||
<View style={aboutStyle.col}>
|
||||
<Text selectable={true} style={aboutStyle.valueText}>
|
||||
<Text selectable style={aboutStyle.valueText}>
|
||||
{ver ? ver.lbrynet_version : loading}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -147,7 +147,7 @@ class AboutPage extends React.PureComponent {
|
|||
<Text style={aboutStyle.text}>Platform</Text>
|
||||
</View>
|
||||
<View style={aboutStyle.col}>
|
||||
<Text selectable={true} style={aboutStyle.valueText}>
|
||||
<Text selectable style={aboutStyle.valueText}>
|
||||
{ver ? ver.platform : loading}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -156,7 +156,7 @@ class AboutPage extends React.PureComponent {
|
|||
<View style={aboutStyle.row}>
|
||||
<View style={aboutStyle.col}>
|
||||
<Text style={aboutStyle.text}>Installation ID</Text>
|
||||
<Text selectable={true} style={aboutStyle.lineValueText}>
|
||||
<Text selectable style={aboutStyle.lineValueText}>
|
||||
{this.state.lbryId ? this.state.lbryId : loading}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -10,6 +10,7 @@ import Link from 'component/link';
|
|||
import FileList from 'component/fileList';
|
||||
import PageHeader from 'component/pageHeader';
|
||||
import SubscribeButton from 'component/subscribeButton';
|
||||
import SubscribeNotificationButton from 'component/subscribeNotificationButton';
|
||||
import UriBar from 'component/uriBar';
|
||||
import channelPageStyle from 'styles/channelPage';
|
||||
|
||||
|
@ -206,7 +207,14 @@ class ChannelPage extends React.PureComponent {
|
|||
/>
|
||||
</View>
|
||||
|
||||
<SubscribeButton style={channelPageStyle.subscribeButton} uri={uri} name={name} />
|
||||
<View style={channelPageStyle.subscribeButtonContainer}>
|
||||
<SubscribeButton style={channelPageStyle.subscribeButton} uri={uri} name={name} />
|
||||
<SubscribeNotificationButton
|
||||
style={[channelPageStyle.subscribeButton, channelPageStyle.bellButton]}
|
||||
uri={uri}
|
||||
name={name}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={channelPageStyle.tabBar}>
|
||||
|
|
|
@ -18,9 +18,8 @@ import {
|
|||
selectSubscriptionClaims,
|
||||
selectUnreadSubscriptions,
|
||||
} from 'lbryinc';
|
||||
|
||||
import { doSetClientSetting } from 'redux/actions/settings';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import { doSetClientSetting, doSetSortByItem } from 'redux/actions/settings';
|
||||
import { makeSelectClientSetting, selectSortByItem } from 'redux/selectors/settings';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import DiscoverPage from './view';
|
||||
|
||||
|
@ -34,6 +33,7 @@ const select = state => ({
|
|||
followedTags: selectFollowedTags(state),
|
||||
ratingReminderDisabled: makeSelectClientSetting(Constants.SETTING_RATING_REMINDER_DISABLED)(state),
|
||||
ratingReminderLastShown: makeSelectClientSetting(Constants.SETTING_RATING_REMINDER_LAST_SHOWN)(state),
|
||||
sortByItem: selectSortByItem(state),
|
||||
unreadSubscriptions: selectUnreadSubscriptions(state),
|
||||
uris: selectLastClaimSearchUris(state),
|
||||
});
|
||||
|
@ -46,6 +46,7 @@ const perform = dispatch => ({
|
|||
fileList: () => dispatch(doFileList()),
|
||||
removeUnreadSubscriptions: () => dispatch(doRemoveUnreadSubscriptions()),
|
||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||
setSortByItem: item => dispatch(doSetSortByItem(item)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
View,
|
||||
} from 'react-native';
|
||||
import { DEFAULT_FOLLOWED_TAGS, Lbry, normalizeURI, parseURI } from 'lbry-redux';
|
||||
import { __, formatTagTitle } from 'utils/helper';
|
||||
import { __, formatTagTitle, getOrderBy } from 'utils/helper';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import moment from 'moment';
|
||||
import CategoryList from 'component/categoryList';
|
||||
|
@ -33,7 +33,6 @@ class DiscoverPage extends React.PureComponent {
|
|||
showModalTagSelector: false,
|
||||
showSortPicker: false,
|
||||
orderBy: Constants.DEFAULT_ORDER_BY,
|
||||
currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[0],
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -60,33 +59,22 @@ class DiscoverPage extends React.PureComponent {
|
|||
}
|
||||
});
|
||||
|
||||
const { fetchRewardedContent, fetchSubscriptions, fileList, followedTags } = this.props;
|
||||
const { sortByItem, fetchRewardedContent, fetchSubscriptions, fileList, followedTags } = this.props;
|
||||
|
||||
this.buildTagCollection(followedTags);
|
||||
fetchRewardedContent();
|
||||
fetchSubscriptions();
|
||||
fileList();
|
||||
|
||||
this.handleSortByItemSelected(sortByItem);
|
||||
this.showRatingReminder();
|
||||
}
|
||||
|
||||
handleSortByItemSelected = item => {
|
||||
let orderBy = [];
|
||||
switch (item.name) {
|
||||
case Constants.SORT_BY_HOT:
|
||||
orderBy = Constants.DEFAULT_ORDER_BY;
|
||||
break;
|
||||
|
||||
case Constants.SORT_BY_NEW:
|
||||
orderBy = ['release_time'];
|
||||
break;
|
||||
|
||||
case Constants.SORT_BY_TOP:
|
||||
orderBy = ['effective_amount'];
|
||||
break;
|
||||
}
|
||||
|
||||
this.setState({ currentSortByItem: item, orderBy, showSortPicker: false });
|
||||
const { setSortByItem } = this.props;
|
||||
setSortByItem(item);
|
||||
const orderBy = getOrderBy(item);
|
||||
this.setState({ orderBy, showSortPicker: false });
|
||||
};
|
||||
|
||||
subscriptionForUri = (uri, channelName) => {
|
||||
|
@ -217,7 +205,7 @@ class DiscoverPage extends React.PureComponent {
|
|||
|
||||
// each of the followed tags
|
||||
const tagCollection = _.shuffle(tags)
|
||||
.slice(0, 6)
|
||||
.slice(0, 5)
|
||||
.map(tag => [tag]);
|
||||
// everything
|
||||
tagCollection.unshift(tags);
|
||||
|
@ -226,68 +214,77 @@ class DiscoverPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleTagPress = name => {
|
||||
const { navigation } = this.props;
|
||||
if (name.toLowerCase() !== 'trending') {
|
||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: `tagPage`, params: { tag: name } });
|
||||
const { navigation, sortByItem } = this.props;
|
||||
if (name.toLowerCase() !== 'all tags you follow') {
|
||||
navigation.navigate({
|
||||
routeName: Constants.DRAWER_ROUTE_TAG,
|
||||
key: `tagPage`,
|
||||
params: {
|
||||
tag: name,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// navigate to the trending page
|
||||
navigation.navigate({ routeName: Constants.FULL_ROUTE_NAME_TRENDING });
|
||||
}
|
||||
};
|
||||
|
||||
sectionListHeader = () => (
|
||||
<View style={discoverStyle.titleRow}>
|
||||
<Text style={discoverStyle.pageTitle}>Explore</Text>
|
||||
<View style={discoverStyle.rightTitleRow}>
|
||||
<Link
|
||||
style={discoverStyle.customizeLink}
|
||||
text={'Customize'}
|
||||
onPress={() => this.setState({ showModalTagSelector: true })}
|
||||
/>
|
||||
<TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}>
|
||||
<Text style={discoverStyle.tagSortText}>{this.props.sortByItem.label.split(' ')[0]}</Text>
|
||||
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
renderSectionListItem = ({ item, index, section }) => (
|
||||
<ClaimList
|
||||
key={item.sort().join(',')}
|
||||
orderBy={this.state.orderBy}
|
||||
time={Constants.TIME_WEEK}
|
||||
tags={item}
|
||||
morePlaceholder
|
||||
navigation={this.props.navigation}
|
||||
orientation={Constants.ORIENTATION_HORIZONTAL}
|
||||
/>
|
||||
);
|
||||
|
||||
renderSectionHeader = ({ section: { title } }) => (
|
||||
<View style={discoverStyle.categoryTitleRow}>
|
||||
<Text style={discoverStyle.categoryName} onPress={() => this.handleTagPress(title)}>
|
||||
{formatTagTitle(title)}
|
||||
</Text>
|
||||
<TouchableOpacity onPress={() => this.handleTagPress(title)}>
|
||||
<Icon name={'angle-double-down'} size={16} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
const { currentSortByItem, orderBy, showModalTagSelector, showSortPicker } = this.state;
|
||||
const { navigation, sortByItem } = this.props;
|
||||
const { orderBy, showModalTagSelector, showSortPicker } = this.state;
|
||||
|
||||
return (
|
||||
<View style={discoverStyle.container}>
|
||||
<UriBar navigation={navigation} belowOverlay={showModalTagSelector} />
|
||||
<SectionList
|
||||
ListHeaderComponent={
|
||||
<View style={discoverStyle.titleRow}>
|
||||
<Text style={discoverStyle.pageTitle}>Explore</Text>
|
||||
<View style={discoverStyle.rightTitleRow}>
|
||||
<Link
|
||||
style={discoverStyle.customizeLink}
|
||||
text={'Customize'}
|
||||
onPress={() => this.setState({ showModalTagSelector: true })}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={discoverStyle.tagSortBy}
|
||||
onPress={() => this.setState({ showSortPicker: true })}
|
||||
>
|
||||
<Text style={discoverStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text>
|
||||
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
}
|
||||
ListHeaderComponent={this.sectionListHeader}
|
||||
style={discoverStyle.scrollContainer}
|
||||
contentContainerStyle={discoverStyle.scrollPadding}
|
||||
initialNumToRender={4}
|
||||
maxToRenderPerBatch={4}
|
||||
removeClippedSubviews
|
||||
renderItem={({ item, index, section }) => (
|
||||
<ClaimList
|
||||
key={item.sort().join(',')}
|
||||
orderBy={orderBy}
|
||||
time={Constants.TIME_WEEK}
|
||||
tags={item}
|
||||
morePlaceholder
|
||||
navigation={navigation}
|
||||
orientation={Constants.ORIENTATION_HORIZONTAL}
|
||||
/>
|
||||
)}
|
||||
renderSectionHeader={({ section: { title } }) => (
|
||||
<View style={discoverStyle.categoryTitleRow}>
|
||||
<Text style={discoverStyle.categoryName} onPress={() => this.handleTagPress(title)}>
|
||||
{formatTagTitle(title)}
|
||||
</Text>
|
||||
<TouchableOpacity onPress={() => this.handleTagPress(title)}>
|
||||
<Icon name={'angle-double-down'} size={16} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
renderItem={this.renderSectionListItem}
|
||||
renderSectionHeader={this.renderSectionHeader}
|
||||
sections={this.buildSections()}
|
||||
keyExtractor={(item, index) => item}
|
||||
/>
|
||||
|
@ -303,7 +300,7 @@ class DiscoverPage extends React.PureComponent {
|
|||
title={__('Sort content by')}
|
||||
onOverlayPress={() => this.setState({ showSortPicker: false })}
|
||||
onItemSelected={this.handleSortByItemSelected}
|
||||
selectedItem={currentSortByItem}
|
||||
selectedItem={sortByItem}
|
||||
items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -21,7 +21,7 @@ class DownloadsPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -44,7 +44,7 @@ class DownloadsPage extends React.PureComponent {
|
|||
componentWillReceiveProps(nextProps) {
|
||||
const { currentRoute } = nextProps;
|
||||
const { currentRoute: prevRoute } = this.props;
|
||||
if (Constants.FULL_ROUTE_NAME_MY_LBRY === currentRoute && currentRoute !== prevRoute) {
|
||||
if (Constants.DRAWER_ROUTE_MY_LBRY === currentRoute && currentRoute !== prevRoute) {
|
||||
this.onComponentFocused();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ class FilePage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
onComponentFocused = () => {
|
||||
|
@ -913,6 +913,7 @@ class FilePage extends React.PureComponent {
|
|||
<TextInput
|
||||
ref={ref => (this.tipAmountInput = ref)}
|
||||
onChangeText={value => this.setState({ tipAmount: value })}
|
||||
underlineColorAndroid={Colors.NextLbryGreen}
|
||||
keyboardType={'numeric'}
|
||||
placeholder={'0'}
|
||||
value={this.state.tipAmount}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ActivityIndicator, Linking, NativeModules, Text, TouchableOpacity, View
|
|||
import { NavigationActions, StackActions } from 'react-navigation';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import WalletPage from './internal/wallet-page';
|
||||
import WelcomePage from './internal/welcome-page';
|
||||
import EmailCollectPage from './internal/email-collect-page';
|
||||
|
@ -73,6 +73,7 @@ class FirstRunScreen extends React.PureComponent {
|
|||
notify({ message: String(emailNewErrorMessage), isError: true });
|
||||
} else {
|
||||
// Request successful. Navigate to email verify page.
|
||||
NativeModules.Firebase.track('email_added', { email: this.state.email });
|
||||
this.showPage(Constants.FIRST_RUN_PAGE_EMAIL_VERIFY);
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ class FirstRunScreen extends React.PureComponent {
|
|||
|
||||
onEmailChanged = email => {
|
||||
this.setState({ email });
|
||||
if (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT == this.state.currentPage) {
|
||||
if (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT === this.state.currentPage) {
|
||||
this.setState({ showSkip: !email || email.trim().length === 0 });
|
||||
} else {
|
||||
this.setState({ showSkip: false });
|
||||
|
@ -236,14 +237,14 @@ class FirstRunScreen extends React.PureComponent {
|
|||
};
|
||||
|
||||
onEmailViewLayout = phase => {
|
||||
if ('collect' === phase) {
|
||||
if (phase === 'collect') {
|
||||
if (!this.state.emailCollectTracked) {
|
||||
// we only want to track this once
|
||||
this.setState({ emailCollectTracked: true }, () =>
|
||||
NativeModules.Firebase.track('first_run_email_collect', null)
|
||||
);
|
||||
}
|
||||
} else if ('verify' === phase) {
|
||||
} else if (phase === 'verify') {
|
||||
NativeModules.Firebase.track('first_run_email_verify', null);
|
||||
}
|
||||
|
||||
|
@ -402,10 +403,10 @@ class FirstRunScreen extends React.PureComponent {
|
|||
|
||||
{Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT !== this.state.currentPage &&
|
||||
Constants.FIRST_RUN_PAGE_EMAIL_VERIFY !== this.state.currentPage && (
|
||||
<Text style={firstRunStyle.buttonText}>
|
||||
{Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage ? 'Use LBRY' : 'Continue'} »
|
||||
</Text>
|
||||
)}
|
||||
<Text style={firstRunStyle.buttonText}>
|
||||
{Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage ? 'Use LBRY' : 'Continue'} »
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
|
|
|
@ -15,7 +15,15 @@ import {
|
|||
View,
|
||||
} from 'react-native';
|
||||
import { FlatGrid } from 'react-native-super-grid';
|
||||
import { isNameValid, buildURI, regexInvalidURI, CLAIM_VALUES, LICENSES, THUMBNAIL_STATUSES } from 'lbry-redux';
|
||||
import {
|
||||
isNameValid,
|
||||
buildURI,
|
||||
regexInvalidURI,
|
||||
CLAIM_VALUES,
|
||||
LICENSES,
|
||||
MATURE_TAGS,
|
||||
THUMBNAIL_STATUSES,
|
||||
} from 'lbry-redux';
|
||||
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker';
|
||||
import { RNCamera } from 'react-native-camera';
|
||||
import { generateCombination } from 'gfycat-style-urls';
|
||||
|
@ -116,7 +124,7 @@ class PublishPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
DeviceEventEmitter.addListener('onGalleryThumbnailsChecked', this.handleGalleryThumbnailsChecked);
|
||||
}
|
||||
|
||||
|
@ -203,10 +211,6 @@ class PublishPage extends React.PureComponent {
|
|||
}
|
||||
|
||||
const publishTags = tags.slice();
|
||||
if (mature) {
|
||||
publishTags.push('nsfw');
|
||||
}
|
||||
|
||||
const publishParams = {
|
||||
filePath: currentMedia.filePath,
|
||||
bid: bid || 0.1,
|
||||
|
@ -215,7 +219,7 @@ class PublishPage extends React.PureComponent {
|
|||
thumbnail: thumbnail,
|
||||
description: description || '',
|
||||
language,
|
||||
nsfw: mature,
|
||||
nsfw: publishTags.some(tag => MATURE_TAGS.includes(tag)),
|
||||
license,
|
||||
licenseUrl: '',
|
||||
otherLicenseDescription: '',
|
||||
|
@ -654,7 +658,7 @@ class PublishPage extends React.PureComponent {
|
|||
/>
|
||||
))}
|
||||
</View>
|
||||
<TagSearch handleAddTag={this.handleAddTag} selectedTags={this.state.tags} />
|
||||
<TagSearch handleAddTag={this.handleAddTag} selectedTags={this.state.tags} showNsfwTags />
|
||||
</View>
|
||||
|
||||
<View style={publishStyle.card}>
|
||||
|
@ -727,11 +731,6 @@ class PublishPage extends React.PureComponent {
|
|||
{this.state.advancedMode && (
|
||||
<View style={publishStyle.card}>
|
||||
<Text style={publishStyle.cardTitle}>Additional Options</Text>
|
||||
<View style={publishStyle.toggleField}>
|
||||
<Switch value={this.state.mature} onValueChange={value => this.setState({ mature: value })} />
|
||||
<Text style={publishStyle.toggleText}>Mature content</Text>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<Text style={publishStyle.cardText}>Language</Text>
|
||||
<Picker
|
||||
|
|
|
@ -14,7 +14,7 @@ class PublishesPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -23,6 +23,10 @@ class PublishesPage extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.onComponentFocused();
|
||||
}
|
||||
|
||||
onComponentFocused = () => {
|
||||
const { checkPendingPublishes, pushDrawerStack, setPlayerVisible } = this.props;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class RewardsPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -24,7 +24,7 @@ class SearchPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { SETTINGS } from 'lbry-redux';
|
||||
import { Text, View, ScrollView, Switch, NativeModules } from 'react-native';
|
||||
import { navigateBack } from 'utils/helper';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import PageHeader from 'component/pageHeader';
|
||||
import settingsStyle from 'styles/settings';
|
||||
|
||||
|
@ -15,7 +15,7 @@ class SettingsPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -42,7 +42,7 @@ class SubscriptionsPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||
import { doSetSortByItem } from 'redux/actions/settings';
|
||||
import { selectCurrentRoute } from 'redux/selectors/drawer';
|
||||
import Constants from 'constants';
|
||||
import { selectSortByItem } from 'redux/selectors/settings';
|
||||
import TagPage from './view';
|
||||
|
||||
const select = state => ({
|
||||
currentRoute: selectCurrentRoute(state),
|
||||
sortByItem: selectSortByItem(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_TAG)),
|
||||
pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)),
|
||||
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
||||
setSortByItem: item => dispatch(doSetSortByItem(item)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { ActivityIndicator, NativeModules, FlatList, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { DEFAULT_FOLLOWED_TAGS, normalizeURI } from 'lbry-redux';
|
||||
import { formatTagTitle } from 'utils/helper';
|
||||
import { formatTagTitle, getOrderBy } from 'utils/helper';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import moment from 'moment';
|
||||
import ClaimList from 'component/claimList';
|
||||
|
@ -22,7 +22,6 @@ class TagPage extends React.PureComponent {
|
|||
showTimePicker: false,
|
||||
orderBy: Constants.DEFAULT_ORDER_BY,
|
||||
time: Constants.TIME_WEEK,
|
||||
currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[0],
|
||||
currentTimeItem: Constants.CLAIM_SEARCH_TIME_ITEMS[1],
|
||||
};
|
||||
|
||||
|
@ -30,7 +29,7 @@ class TagPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -40,9 +39,10 @@ class TagPage extends React.PureComponent {
|
|||
}
|
||||
|
||||
onComponentFocused = () => {
|
||||
const { pushDrawerStack, setPlayerVisible, navigation } = this.props;
|
||||
this.setState({ tag: navigation.state.params.tag });
|
||||
pushDrawerStack();
|
||||
const { navigation, pushDrawerStack, setPlayerVisible, sortByItem } = this.props;
|
||||
const { tag } = navigation.state.params;
|
||||
this.setState({ tag, sortByItem, orderBy: getOrderBy(sortByItem) });
|
||||
pushDrawerStack(Constants.DRAWER_ROUTE_TAG, navigation.state.params);
|
||||
setPlayerVisible();
|
||||
};
|
||||
|
||||
|
@ -59,22 +59,9 @@ class TagPage extends React.PureComponent {
|
|||
}
|
||||
|
||||
handleSortByItemSelected = item => {
|
||||
let orderBy = [];
|
||||
switch (item.name) {
|
||||
case Constants.SORT_BY_HOT:
|
||||
orderBy = Constants.DEFAULT_ORDER_BY;
|
||||
break;
|
||||
|
||||
case Constants.SORT_BY_NEW:
|
||||
orderBy = ['release_time'];
|
||||
break;
|
||||
|
||||
case Constants.SORT_BY_TOP:
|
||||
orderBy = [Constants.ORDER_BY_EFFECTIVE_AMOUNT];
|
||||
break;
|
||||
}
|
||||
|
||||
this.setState({ currentSortByItem: item, orderBy, showSortPicker: false });
|
||||
const { setSortByItem } = this.props;
|
||||
setSortByItem(item);
|
||||
this.setState({ orderBy: getOrderBy(item), showSortPicker: false });
|
||||
};
|
||||
|
||||
handleTimeItemSelected = item => {
|
||||
|
@ -82,8 +69,8 @@ class TagPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
const { tag, currentSortByItem, currentTimeItem, showSortPicker, showTimePicker } = this.state;
|
||||
const { navigation, sortByItem } = this.props;
|
||||
const { tag, currentTimeItem, showSortPicker, showTimePicker } = this.state;
|
||||
|
||||
return (
|
||||
<View style={discoverStyle.container}>
|
||||
|
@ -92,14 +79,14 @@ class TagPage extends React.PureComponent {
|
|||
ListHeaderComponent={
|
||||
<View style={discoverStyle.tagTitleRow}>
|
||||
<Text style={discoverStyle.tagPageTitle}>{formatTagTitle(tag)}</Text>
|
||||
{Constants.SORT_BY_TOP === currentSortByItem.name && (
|
||||
{Constants.SORT_BY_TOP === sortByItem.name && (
|
||||
<TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}>
|
||||
<Text style={discoverStyle.tagSortText}>{currentTimeItem.label}</Text>
|
||||
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}>
|
||||
<Text style={discoverStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text>
|
||||
<Text style={discoverStyle.tagSortText}>{sortByItem.label.split(' ')[0]}</Text>
|
||||
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
@ -117,7 +104,7 @@ class TagPage extends React.PureComponent {
|
|||
title={__('Sort content by')}
|
||||
onOverlayPress={() => this.setState({ showSortPicker: false })}
|
||||
onItemSelected={this.handleSortByItemSelected}
|
||||
selectedItem={this.state.currentSortByItem}
|
||||
selectedItem={this.state.sortByItem}
|
||||
items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { View, ScrollView, Text } from 'react-native';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import TransactionList from 'component/transactionList';
|
||||
import UriBar from 'component/uriBar';
|
||||
import walletStyle from 'styles/wallet';
|
||||
|
@ -10,7 +10,7 @@ class TransactionHistoryPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -31,7 +31,7 @@ class TrendingPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from 'react';
|
||||
import { Lbry } from 'lbry-redux';
|
||||
import { ActivityIndicator, View, Text, TextInput } from 'react-native';
|
||||
import { ActivityIndicator, NativeModules, View, Text, TextInput } from 'react-native';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import Button from 'component/button';
|
||||
import Link from 'component/link';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import firstRunStyle from 'styles/firstRun';
|
||||
import rewardStyle from 'styles/reward';
|
||||
|
||||
|
@ -44,11 +44,12 @@ class EmailVerifyPage extends React.PureComponent {
|
|||
notify({ message: String(emailNewErrorMessage), isError: true });
|
||||
this.setState({ verifyStarted: false });
|
||||
} else {
|
||||
NativeModules.Firebase.track('email_added', { email: this.state.email });
|
||||
this.setState({ phase: Constants.PHASE_VERIFICATION });
|
||||
if (setEmailVerificationPhase) {
|
||||
setEmailVerificationPhase(true);
|
||||
}
|
||||
//notify({ message: 'Please follow the instructions in the email sent to your address to continue.' });
|
||||
// notify({ message: 'Please follow the instructions in the email sent to your address to continue.' });
|
||||
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ActivityIndicator, Linking, NativeModules, Text, TouchableOpacity, View
|
|||
import { NavigationActions, StackActions } from 'react-navigation';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import EmailVerifyPage from './internal/email-verify-page';
|
||||
import ManualVerifyPage from './internal/manual-verify-page';
|
||||
import PhoneVerifyPage from './internal/phone-verify-page';
|
||||
|
@ -68,6 +68,9 @@ class VerificationScreen extends React.PureComponent {
|
|||
if (this.state.isEmailVerified && this.state.isRewardApproved) {
|
||||
// verification steps already completed
|
||||
// simply navigate back to the rewards page
|
||||
if (user.primary_email) {
|
||||
NativeModules.Firebase.track('reward_eligibility_completed', { email: user.primary_email });
|
||||
}
|
||||
navigation.goBack();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import WalletSyncDriver from 'component/walletSyncDriver';
|
|||
import Button from 'component/button';
|
||||
import Link from 'component/link';
|
||||
import UriBar from 'component/uriBar';
|
||||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import walletStyle from 'styles/wallet';
|
||||
|
||||
class WalletPage extends React.PureComponent {
|
||||
|
@ -17,7 +17,7 @@ class WalletPage extends React.PureComponent {
|
|||
|
||||
componentWillMount() {
|
||||
const { navigation } = this.props;
|
||||
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
// this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
export const doPushDrawerStack = routeName => dispatch =>
|
||||
export const doPushDrawerStack = (routeName, params) => dispatch =>
|
||||
dispatch({
|
||||
type: Constants.ACTION_PUSH_DRAWER_STACK,
|
||||
data: routeName,
|
||||
data: { routeName, params },
|
||||
});
|
||||
|
||||
export const doPopDrawerStack = () => dispatch =>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { ACTIONS } from 'lbry-redux';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
export function doSetClientSetting(key, value) {
|
||||
return dispatch => {
|
||||
|
@ -15,3 +16,14 @@ export function doSetClientSetting(key, value) {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function doSetSortByItem(item) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: Constants.ACTION_SORT_BY_ITEM_CHANGED,
|
||||
data: {
|
||||
name: item.name,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Constants from 'constants';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
const reducers = {};
|
||||
const defaultState = {
|
||||
stack: [Constants.DRAWER_ROUTE_DISCOVER], // Discover is always the first drawer route
|
||||
stack: [{ route: Constants.DRAWER_ROUTE_DISCOVER, params: {} }], // Discover is always the first drawer route
|
||||
playerVisible: false,
|
||||
currentRoute: null,
|
||||
};
|
||||
|
@ -13,11 +13,11 @@ reducers[Constants.ACTION_SET_PLAYER_VISIBLE] = (state, action) =>
|
|||
});
|
||||
|
||||
reducers[Constants.ACTION_PUSH_DRAWER_STACK] = (state, action) => {
|
||||
const routeName = action.data;
|
||||
const { routeName, params } = action.data;
|
||||
const newStack = state.stack.slice();
|
||||
|
||||
if (routeName !== newStack[newStack.length - 1]) {
|
||||
newStack.push(routeName);
|
||||
if (routeName !== newStack[newStack.length - 1].route) {
|
||||
newStack.push({ route: routeName, params });
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { ACTIONS } from 'lbry-redux';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
const reducers = {};
|
||||
const defaultState = {
|
||||
clientSettings: {},
|
||||
sortByItemName: Constants.SORT_BY_HOT,
|
||||
};
|
||||
|
||||
reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
||||
|
@ -16,6 +18,11 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
|||
});
|
||||
};
|
||||
|
||||
reducers[Constants.ACTION_SORT_BY_ITEM_CHANGED] = (state, action) =>
|
||||
Object.assign({}, state, {
|
||||
sortByItemName: action.data.name,
|
||||
});
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
const handler = reducers[action.type];
|
||||
if (handler) return handler(state, action);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { SETTINGS } from 'lbry-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { getSortByItemForName } from 'utils/helper';
|
||||
|
||||
const selectState = state => state.settings || {};
|
||||
|
||||
|
@ -13,6 +14,11 @@ export const selectClientSettings = createSelector(
|
|||
state => state.clientSettings || {}
|
||||
);
|
||||
|
||||
export const selectSortByItem = createSelector(
|
||||
selectState,
|
||||
state => getSortByItemForName(state.sortByItemName)
|
||||
);
|
||||
|
||||
export const makeSelectClientSetting = setting =>
|
||||
createSelector(
|
||||
selectClientSettings,
|
||||
|
|
|
@ -66,15 +66,21 @@ const channelPageStyle = StyleSheet.create({
|
|||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 18,
|
||||
},
|
||||
subscribeButtonContainer: {
|
||||
position: 'absolute',
|
||||
flexDirection: 'row',
|
||||
left: 8,
|
||||
bottom: -90,
|
||||
zIndex: 100,
|
||||
},
|
||||
subscribeButton: {
|
||||
alignSelf: 'flex-start',
|
||||
backgroundColor: Colors.White,
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
position: 'absolute',
|
||||
right: 8,
|
||||
bottom: -88,
|
||||
zIndex: 100,
|
||||
},
|
||||
bellButton: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
cover: {
|
||||
width: '100%',
|
||||
|
@ -120,6 +126,7 @@ const channelPageStyle = StyleSheet.create({
|
|||
marginBottom: 24,
|
||||
},
|
||||
aboutScrollContent: {
|
||||
paddingTop: 52,
|
||||
padding: 24,
|
||||
},
|
||||
aboutTitle: {
|
||||
|
|
|
@ -10,6 +10,7 @@ const Colors = {
|
|||
BrighterLbryGreen: '#40b887',
|
||||
NextLbryGreen: '#38d9a9',
|
||||
TagGreen: '#e3f6f1',
|
||||
TagGrape: '#da77f255',
|
||||
LightGrey: '#cccccc',
|
||||
LighterGrey: '#e5e5e5',
|
||||
Orange: '#ffbb00',
|
||||
|
|
|
@ -121,6 +121,12 @@ const discoverStyle = StyleSheet.create({
|
|||
marginTop: 4,
|
||||
color: Colors.LbryGreen,
|
||||
},
|
||||
anonChannelName: {
|
||||
fontFamily: 'Inter-UI-SemiBold',
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
color: Colors.DescriptionGrey,
|
||||
},
|
||||
downloadedIcon: {
|
||||
position: 'absolute',
|
||||
right: 8,
|
||||
|
|
|
@ -289,6 +289,7 @@ const filePageStyle = StyleSheet.create({
|
|||
},
|
||||
tipAmountInput: {
|
||||
alignSelf: 'flex-start',
|
||||
textAlign: 'right',
|
||||
width: 80,
|
||||
fontSize: 16,
|
||||
letterSpacing: 1,
|
||||
|
|
|
@ -114,6 +114,7 @@ const publishStyle = StyleSheet.create({
|
|||
width: 80,
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
textAlign: 'right',
|
||||
},
|
||||
currency: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
|
|
|
@ -30,6 +30,14 @@ const tagStyle = StyleSheet.create({
|
|||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
nsfwTagsContainer: {
|
||||
marginTop: 8,
|
||||
},
|
||||
nsfwTagsTitle: {
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 16,
|
||||
marginBottom: 4,
|
||||
},
|
||||
});
|
||||
|
||||
export default tagStyle;
|
||||
|
|
|
@ -154,11 +154,12 @@ export function navigateBack(navigation, drawerStack, popDrawerStack) {
|
|||
}
|
||||
|
||||
const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];
|
||||
const { route, params } = target;
|
||||
navigation.goBack(navigation.state.key);
|
||||
if (DrawerRoutes.indexOf(target) === -1 && isURIValid(target)) {
|
||||
navigateToUri(navigation, target, null, true);
|
||||
if (DrawerRoutes.indexOf(route) === -1 && isURIValid(route)) {
|
||||
navigateToUri(navigation, route, null, true);
|
||||
} else {
|
||||
navigation.navigate({ routeName: target });
|
||||
navigation.navigate({ routeName: route, params });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,13 +167,15 @@ export function dispatchNavigateBack(dispatch, nav, drawerStack) {
|
|||
dispatch(doPopDrawerStack());
|
||||
|
||||
const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];
|
||||
const { route } = target;
|
||||
dispatch(NavigationActions.back());
|
||||
|
||||
if (DrawerRoutes.indexOf(target) === -1 && isURIValid(target)) {
|
||||
dispatchNavigateToUri(dispatch, nav, target, true);
|
||||
if (DrawerRoutes.indexOf(route) === -1 && isURIValid(route)) {
|
||||
dispatchNavigateToUri(dispatch, nav, route, true);
|
||||
} else {
|
||||
const newTarget = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
routeName: drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0],
|
||||
routeName: newTarget.route,
|
||||
params: newTarget.params,
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
}
|
||||
|
@ -204,6 +207,35 @@ export function formatTagName(name) {
|
|||
return name.substring(0, 7) + '...';
|
||||
}
|
||||
|
||||
export function getSortByItemForName(name) {
|
||||
for (let i = 0; i < Constants.CLAIM_SEARCH_SORT_BY_ITEMS.length; i++) {
|
||||
if (name === Constants.CLAIM_SEARCH_SORT_BY_ITEMS[i].name) {
|
||||
return Constants.CLAIM_SEARCH_SORT_BY_ITEMS[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getOrderBy(item) {
|
||||
let orderBy = [];
|
||||
switch (item.name) {
|
||||
case Constants.SORT_BY_HOT:
|
||||
orderBy = Constants.DEFAULT_ORDER_BY;
|
||||
break;
|
||||
|
||||
case Constants.SORT_BY_NEW:
|
||||
orderBy = ['release_time'];
|
||||
break;
|
||||
|
||||
case Constants.SORT_BY_TOP:
|
||||
orderBy = [Constants.ORDER_BY_EFFECTIVE_AMOUNT];
|
||||
break;
|
||||
}
|
||||
|
||||
return orderBy;
|
||||
}
|
||||
|
||||
// i18n placeholder until we find a good react-native i18n module
|
||||
export function __(str) {
|
||||
return str;
|
||||
|
|
Loading…
Reference in a new issue