Redux master updates #18

Merged
akinwale merged 7 commits from redux-master-updates into master 2019-08-15 05:55:02 +02:00
10 changed files with 147 additions and 205 deletions
package.json
src
component
claimList
suggestedSubscriptions
page

View file

@ -12,7 +12,7 @@
"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#1a8ce5ee1397e101f2a015f1c3a9050c15ca6157", "lbry-redux": "lbryio/lbry-redux#e10986e8e54d25480ac2b5dd2a31fec8b254471a",
"lbryinc": "lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb", "lbryinc": "lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
"lodash": ">=4.17.11", "lodash": ">=4.17.11",
"merge": ">=1.2.1", "merge": ">=1.2.1",

View file

@ -2,11 +2,10 @@ import { connect } from 'react-redux';
import { import {
MATURE_TAGS, MATURE_TAGS,
doClaimSearch, doClaimSearch,
doClaimSearchByTags, selectClaimSearchByQuery,
makeSelectClaimSearchUrisForTags, selectClaimSearchByQueryLastPageReached,
makeSelectFetchingClaimSearchForTags, selectFetchingClaimSearchByQuery,
selectFetchingClaimSearch, selectFetchingClaimSearch,
selectLastClaimSearchUris,
} from 'lbry-redux'; } from 'lbry-redux';
import { selectShowNsfw } from 'redux/selectors/settings'; import { selectShowNsfw } from 'redux/selectors/settings';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
@ -14,33 +13,15 @@ import ClaimList from './view';
const select = (state, props) => { const select = (state, props) => {
return { return {
loading: makeSelectFetchingClaimSearchForTags(props.tags)(state), claimSearchByQuery: selectClaimSearchByQuery(state),
uris: makeSelectClaimSearchUrisForTags(props.tags)(state), lastPageReached: selectClaimSearchByQueryLastPageReached(state),
// for subscriptions loadingByQuery: selectFetchingClaimSearchByQuery(state),
claimSearchLoading: selectFetchingClaimSearch(state), loading: selectFetchingClaimSearch(state),
claimSearchUris: selectLastClaimSearchUris(state),
showNsfwContent: selectShowNsfw(state),
}; };
}; };
const perform = dispatch => ({ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(Constants.DEFAULT_PAGE_SIZE, options)), claimSearch: options => dispatch(doClaimSearch(options)),
searchByTags: (tags, orderBy = Constants.DEFAULT_ORDER_BY, page = 1, additionalOptions = {}) =>
dispatch(
doClaimSearchByTags(
tags,
Constants.DEFAULT_PAGE_SIZE,
Object.assign(
{},
{
no_totals: true,
order_by: orderBy,
page,
},
additionalOptions
)
)
),
}); });
export default connect( export default connect(

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import NavigationActions from 'react-navigation'; import NavigationActions from 'react-navigation';
import { ActivityIndicator, FlatList, Text, TouchableOpacity, View } from 'react-native'; import { ActivityIndicator, FlatList, Text, TouchableOpacity, View } from 'react-native';
import { MATURE_TAGS, normalizeURI } from 'lbry-redux'; import { MATURE_TAGS, normalizeURI, createNormalizedClaimSearchKey } from 'lbry-redux';
import _ from 'lodash'; import _ from 'lodash';
import FileItem from 'component/fileItem'; import FileItem from 'component/fileItem';
import FileListItem from 'component/fileListItem'; import FileListItem from 'component/fileListItem';
@ -26,58 +26,30 @@ class ClaimList extends React.PureComponent {
}; };
componentDidMount() { componentDidMount() {
const { const { channelIds, trendingForAll } = this.props;
channelIds,
trendingForAll,
claimSearch,
orderBy = Constants.DEFAULT_ORDER_BY,
searchByTags,
showNsfwContent,
tags,
time,
} = this.props;
if (channelIds || trendingForAll) {
const options = {
order_by: orderBy,
no_totals: true,
page: this.state.currentPage,
};
if (!showNsfwContent) {
options.not_tags = MATURE_TAGS;
}
if (channelIds) {
this.setState({ subscriptionsView: true });
options.channel_ids = channelIds;
} else if (trendingForAll) {
this.setState({ trendingForAllView: true });
}
claimSearch(options); if (channelIds) {
} else if (tags && tags.length > 0) { this.setState({ subscriptionsView: true });
const additionalOptions = {}; } else if (trendingForAll) {
if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) { this.setState({ trendingForAllView: true });
additionalOptions.release_time = this.getReleaseTimeOption(time);
}
if (!showNsfwContent) {
additionalOptions.not_tags = MATURE_TAGS;
}
searchByTags(tags, orderBy, this.state.currentPage, additionalOptions);
} }
this.doClaimSearch();
} }
componentWillReceiveProps(nextProps) { componentDidUpdate(prevProps) {
const { const {
claimSearch, claimSearchByQuery: prevClaimSearchByQuery,
orderBy: prevOrderBy, orderBy: prevOrderBy,
searchByTags, searchByTags,
tags: prevTags, tags: prevTags,
channelIds: prevChannelIds, channelIds: prevChannelIds,
trendingForAll: prevTrendingForAll, trendingForAll: prevTrendingForAll,
time: prevTime, time: prevTime,
claimSearchUris: prevClaimSearchUris,
showNsfwContent, showNsfwContent,
} = this.props; } = prevProps;
const { orderBy, tags, channelIds, trendingForAll, time, claimSearchUris } = nextProps; const { claimSearchByQuery, orderBy, tags, channelIds, trendingForAll, time } = this.props;
if ( if (
!_.isEqual(orderBy, prevOrderBy) || !_.isEqual(orderBy, prevOrderBy) ||
!_.isEqual(tags, prevTags) || !_.isEqual(tags, prevTags) ||
@ -90,49 +62,55 @@ class ClaimList extends React.PureComponent {
if (this.scrollView) { if (this.scrollView) {
this.scrollView.scrollToOffset({ animated: true, offset: 0 }); this.scrollView.scrollToOffset({ animated: true, offset: 0 });
} }
if (trendingForAll || (prevChannelIds && channelIds)) { if (trendingForAll || (prevChannelIds && channelIds)) {
const options = {
order_by: orderBy,
no_totals: true,
page: this.state.currentPage,
};
if (!showNsfwContent) {
options.not_tags = MATURE_TAGS;
}
if (channelIds) { if (channelIds) {
this.setState({ subscriptionsView: true }); this.setState({ subscriptionsView: true });
options.channel_ids = channelIds;
} }
if (trendingForAll) { if (trendingForAll) {
this.setState({ trendingForAllView: true }); this.setState({ trendingForAllView: true });
} }
claimSearch(options);
} else if (tags && tags.length > 0) { } else if (tags && tags.length > 0) {
this.setState({ subscriptionsView: false, trendingForAllView: false }); this.setState({ subscriptionsView: false, trendingForAllView: false });
const additionalOptions = {};
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);
} }
this.doClaimSearch();
}); });
kauffj commented 2019-08-15 00:01:18 +02:00 (Migrated from github.com)
Review

would it make sense to have a single view parameter rather than binary parameters for each view? what happens if trendingForAllView and subscriptionView both end up true? (yes, this probably shouldn't be possible)

would it make sense to have a single view parameter rather than binary parameters for each view? what happens if `trendingForAllView` and `subscriptionView` both end up true? (yes, this probably shouldn't be possible)
akinwale commented 2019-08-15 05:51:56 +02:00 (Migrated from github.com)
Review

It's possible to have tags set for the component in the trending view, so trending for all has to be explicitly set in order to not pass those tags when building the options for the request. channelIds is used to filter for content from subscribed channels, which is a whole different condition. So that's effectively 3 different states:

  • Trending for tags you follow: tags is set and is an array, channelIds is null or empty
  • Trending for all: tags is null or empty, channelIds is null or empty
  • Channels you follow: channelIds is set and is an array, tags is null or empty
It's possible to have `tags` set for the component in the trending view, so trending for all has to be explicitly set in order to not pass those tags when building the options for the request. `channelIds` is used to filter for content from subscribed channels, which is a whole different condition. So that's effectively 3 different states: * Trending for tags you follow: `tags` is set and is an array, `channelIds` is null or empty * Trending for all: `tags` is null or empty, `channelIds` is null or empty * Channels you follow: `channelIds` is set and is an array, `tags` is null or empty
} }
}
if ( buildClaimSearchOptions() {
(this.state.subscriptionsView || this.state.trendingForAllView) && const {
this.state.currentPage > 1 && orderBy = Constants.DEFAULT_ORDER_BY,
prevClaimSearchUris && channelIds,
prevClaimSearchUris.length > 0 && showNsfwContent,
_.isEqual(prevClaimSearchUris, claimSearchUris) tags,
) { time,
this.setState({ lastPageReached: true }); trendingForAll,
} else { } = this.props;
this.setState({ lastPageReached: false }); const { currentPage, subscriptionsView, trendingForAllView } = this.state;
const options = {
order_by: orderBy,
no_totals: true,
page: currentPage,
page_size: Constants.DEFAULT_PAGE_SIZE,
};
if (channelIds) {
options.channel_ids = channelIds;
} else if (!trendingForAll && !trendingForAllView && tags && tags.length > 0) {
options.any_tags = tags;
} }
if (!showNsfwContent) {
options.not_tags = MATURE_TAGS;
}
if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) {
options.release_time = this.getReleaseTimeOption(time);
}
return options;
} }
getReleaseTimeOption = time => { getReleaseTimeOption = time => {
@ -143,56 +121,27 @@ class ClaimList extends React.PureComponent {
)}`; )}`;
}; };
doClaimSearch() {
const { claimSearch } = this.props;
const options = this.buildClaimSearchOptions();
claimSearch(options);
}
handleVerticalEndReached = () => { handleVerticalEndReached = () => {
// fetch more content // fetch more content
const { const { claimSearchByQuery, lastPageReached } = this.props;
channelIds,
claimSearch,
claimSearchUris,
orderBy,
searchByTags,
showNsfwContent,
tags,
time,
uris,
} = this.props;
const { subscriptionsView, trendingForAllView } = this.state;
const options = this.buildClaimSearchOptions();
const claimSearchKey = createNormalizedClaimSearchKey(options);
const uris = claimSearchByQuery[claimSearchKey];
if ( if (
this.state.lastPageReached || lastPageReached[claimSearchKey] ||
((claimSearchUris.length > 0 && claimSearchUris.length < Constants.DEFAULT_PAGE_SIZE) || ((uris.length > 0 && uris.length < Constants.DEFAULT_PAGE_SIZE) || uris.length >= softLimit)
claimSearchUris.length >= softLimit) ||
(uris && uris.length >= softLimit)
) { ) {
return; return;
} }
this.setState({ currentPage: this.state.currentPage + 1 }, () => { this.setState({ currentPage: this.state.currentPage + 1 }, () => this.doClaimSearch());
if (subscriptionsView || trendingForAllView) {
const options = {
order_by: orderBy,
no_totals: true,
page: this.state.currentPage,
};
if (!showNsfwContent) {
options.not_tags = MATURE_TAGS;
}
if (subscriptionsView) {
options.channel_ids = channelIds;
}
claimSearch(options);
} else {
const additionalOptions = {};
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);
}
});
}; };
appendMorePlaceholder = items => { appendMorePlaceholder = items => {
@ -253,19 +202,19 @@ class ClaimList extends React.PureComponent {
const { const {
ListHeaderComponent, ListHeaderComponent,
loading, loading,
claimSearchLoading,
claimSearchUris,
morePlaceholder, morePlaceholder,
navigation, navigation,
orientation = Constants.ORIENTATION_VERTICAL, orientation = Constants.ORIENTATION_VERTICAL,
style, style,
uris, claimSearchByQuery,
} = this.props; } = this.props;
const { subscriptionsView, trendingForAllView } = this.state; const { subscriptionsView, trendingForAllView } = this.state;
if (Constants.ORIENTATION_VERTICAL === orientation) { const options = this.buildClaimSearchOptions();
const data = subscriptionsView || trendingForAllView ? claimSearchUris : uris; const claimSearchKey = createNormalizedClaimSearchKey(options);
const uris = claimSearchByQuery[claimSearchKey];
if (Constants.ORIENTATION_VERTICAL === orientation) {
return ( return (
<View style={style}> <View style={style}>
<FlatList <FlatList
@ -273,19 +222,19 @@ class ClaimList extends React.PureComponent {
this.scrollView = ref; this.scrollView = ref;
}} }}
ListHeaderComponent={ListHeaderComponent} ListHeaderComponent={ListHeaderComponent}
ListEmptyComponent={loading || claimSearchLoading ? null : this.verticalListEmptyComponent} ListEmptyComponent={loading ? null : this.verticalListEmptyComponent}
style={claimListStyle.verticalScrollContainer} style={claimListStyle.verticalScrollContainer}
contentContainerStyle={claimListStyle.verticalScrollPadding} contentContainerStyle={claimListStyle.verticalScrollPadding}
initialNumToRender={10} initialNumToRender={10}
maxToRenderPerBatch={20} maxToRenderPerBatch={20}
removeClippedSubviews removeClippedSubviews
renderItem={this.renderVerticalItem} renderItem={this.renderVerticalItem}
data={data} data={uris}
keyExtractor={(item, index) => item} keyExtractor={(item, index) => item}
onEndReached={this.handleVerticalEndReached} onEndReached={this.handleVerticalEndReached}
onEndReachedThreshold={0.2} onEndReachedThreshold={0.2}
/> />
{(((subscriptionsView || trendingForAllView) && claimSearchLoading) || loading) && ( {loading && (
<View style={claimListStyle.verticalLoading}> <View style={claimListStyle.verticalLoading}>
<ActivityIndicator size={'small'} color={Colors.LbryGreen} /> <ActivityIndicator size={'small'} color={Colors.LbryGreen} />
</View> </View>

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doClaimSearch, selectFetchingClaimSearch, selectLastClaimSearchUris, selectFollowedTags } from 'lbry-redux'; import { doClaimSearch, selectFetchingClaimSearch, selectClaimSearchByQuery, selectFollowedTags } from 'lbry-redux';
import { selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc'; import { selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc';
import SuggestedSubscriptions from './view'; import SuggestedSubscriptions from './view';
@ -7,11 +7,11 @@ const select = state => ({
followedTags: selectFollowedTags(state), followedTags: selectFollowedTags(state),
suggested: selectSuggestedChannels(state), suggested: selectSuggestedChannels(state),
loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state), loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state),
claimSearchUris: selectLastClaimSearchUris(state), claimSearchByQuery: selectClaimSearchByQuery(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(10, options)), claimSearch: options => dispatch(doClaimSearch(options)),
}); });
export default connect( export default connect(

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { ActivityIndicator, FlatList, SectionList, Text, View } from 'react-native'; import { ActivityIndicator, FlatList, SectionList, Text, View } from 'react-native';
import { normalizeURI } from 'lbry-redux'; import { createNormalizedClaimSearchKey, normalizeURI } from 'lbry-redux';
import { __, navigateToUri } from 'utils/helper'; import { __, navigateToUri } from 'utils/helper';
import SubscribeButton from 'component/subscribeButton'; import SubscribeButton from 'component/subscribeButton';
import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem'; import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem';
@ -11,19 +11,27 @@ import Link from 'component/link';
import _ from 'lodash'; import _ from 'lodash';
class SuggestedSubscriptions extends React.PureComponent { class SuggestedSubscriptions extends React.PureComponent {
state = {
options: {},
};
componentDidMount() { componentDidMount() {
const { claimSearch, followedTags } = this.props; const { claimSearch, followedTags } = this.props;
const options = { const options = {
any_tags: _.shuffle(followedTags.map(tag => tag.name)).slice(0, 2), any_tags: followedTags.map(tag => tag.name),
page: 1, page: 1,
no_totals: true, no_totals: true,
claim_type: 'channel', claim_type: 'channel',
}; };
this.setState({ options });
claimSearch(options); claimSearch(options);
} }
buildSections = () => { buildSections = () => {
const { suggested, claimSearchUris } = this.props; const { suggested, claimSearchByQuery } = this.props;
const claimSearchKey = createNormalizedClaimSearchKey(this.state.options);
const claimSearchUris = claimSearchByQuery[claimSearchKey];
const suggestedUris = suggested ? suggested.map(suggested => suggested.uri) : []; const suggestedUris = suggested ? suggested.map(suggested => suggested.uri) : [];
return [ return [
{ {

View file

@ -1,12 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import { doClaimSearch, doFileList, selectBalance, selectFileInfosDownloaded, selectFollowedTags } from 'lbry-redux';
doClaimSearch,
doFileList,
selectBalance,
selectFileInfosDownloaded,
selectLastClaimSearchUris,
selectFollowedTags,
} from 'lbry-redux';
import { import {
doFetchFeaturedUris, doFetchFeaturedUris,
doFetchRewardedContent, doFetchRewardedContent,
@ -35,7 +28,6 @@ const select = state => ({
ratingReminderLastShown: makeSelectClientSetting(Constants.SETTING_RATING_REMINDER_LAST_SHOWN)(state), ratingReminderLastShown: makeSelectClientSetting(Constants.SETTING_RATING_REMINDER_LAST_SHOWN)(state),
sortByItem: selectSortByItem(state), sortByItem: selectSortByItem(state),
unreadSubscriptions: selectUnreadSubscriptions(state), unreadSubscriptions: selectUnreadSubscriptions(state),
uris: selectLastClaimSearchUris(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({

View file

@ -957,7 +957,9 @@ class FilePage extends React.PureComponent {
</View> </View>
)} )}
{costInfo && parseFloat(costInfo.cost) > balance && <FileRewardsDriver navigation={navigation} />} {costInfo && parseFloat(costInfo.cost) > balance && !fileInfo && (
<FileRewardsDriver navigation={navigation} />
)}
<View onLayout={this.setRelatedContentPosition} /> <View onLayout={this.setRelatedContentPosition} />
<RelatedContent navigation={navigation} uri={uri} fullUri={fullUri} /> <RelatedContent navigation={navigation} uri={uri} fullUri={fullUri} />

View file

@ -21,7 +21,7 @@ const perform = dispatch => ({
notify: data => dispatch(doToast(data)), notify: data => dispatch(doToast(data)),
updatePublishForm: value => dispatch(doUpdatePublishForm(value)), updatePublishForm: value => dispatch(doUpdatePublishForm(value)),
uploadThumbnail: (filePath, fsAdapter) => dispatch(doUploadThumbnail(filePath, null, fsAdapter)), uploadThumbnail: (filePath, fsAdapter) => dispatch(doUploadThumbnail(filePath, null, fsAdapter)),
publish: params => dispatch(doPublish(params)), publish: (success, fail) => dispatch(doPublish(success, fail)),
resolveUri: uri => dispatch(doResolveUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH)), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH)),
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),

View file

@ -42,6 +42,7 @@ import Tag from 'component/tag';
import TagSearch from 'component/tagSearch'; import TagSearch from 'component/tagSearch';
import UriBar from 'component/uriBar'; import UriBar from 'component/uriBar';
import publishStyle from 'styles/publish'; import publishStyle from 'styles/publish';
import __ from 'utils/helper';
const languages = { const languages = {
en: 'English', en: 'English',
@ -185,7 +186,7 @@ class PublishPage extends React.PureComponent {
}; };
handlePublishPressed = () => { handlePublishPressed = () => {
const { notify, publish } = this.props; const { notify, publish, updatePublishForm } = this.props;
const { const {
bid, bid,
channelName, channelName,
@ -239,7 +240,18 @@ class PublishPage extends React.PureComponent {
}, },
}; };
this.setState({ publishStarted: true }, () => publish(publishParams)); updatePublishForm(publishParams);
this.setState({ publishStarted: true }, () => publish(this.handlePublishSuccess, this.handlePublishFailure));
};
handlePublishSuccess = data => {
this.setState({ publishStarted: false, currentPhase: Constants.PHASE_PUBLISH });
};
handlePublishFailure = error => {
const { notify } = this.props;
notify({ message: __('Your content could not be published at this time. Please try again.') });
this.setState({ publishStarted: false });
}; };
componentDidMount() { componentDidMount() {
@ -256,30 +268,21 @@ class PublishPage extends React.PureComponent {
if (publishFormValues) { if (publishFormValues) {
if (publishFormValues.thumbnail && !this.state.uploadedThumbnailUri) { if (publishFormValues.thumbnail && !this.state.uploadedThumbnailUri) {
this.setState({ uploadedThumbnailUri: publishFormValues.thumbnail }); this.setState({
} currentThumbnailUri: publishFormValues.thumbnail,
uploadedThumbnailUri: publishFormValues.thumbnail,
if (this.state.publishStarted) { });
if (publishFormValues.publishSuccess) {
this.setState({ publishStarted: false, currentPhase: Constants.PHASE_PUBLISH });
} else if (publishFormValues.publishError) {
// TODO: Display error if any
notify({ message: 'Your content could not be published at this time. Please try again.' });
}
if (!publishFormValues.publishing && this.state.publishStarted) {
this.setState({ publishStarted: false });
}
} }
} }
} }
setCurrentMedia(media) { setCurrentMedia(media) {
const name = generateCombination(2, ' ', true);
this.setState( this.setState(
{ {
currentMedia: media, currentMedia: media,
title: media.name, title: name,
name: this.formatNameForTitle(media.name), name: this.formatNameForTitle(name),
currentPhase: Constants.PHASE_DETAILS, currentPhase: Constants.PHASE_DETAILS,
}, },
() => this.handleNameChange(this.state.name) () => this.handleNameChange(this.state.name)
@ -365,7 +368,6 @@ class PublishPage extends React.PureComponent {
const currentMedia = { const currentMedia = {
id: -1, id: -1,
filePath: this.getFilePathFromUri(data.uri), filePath: this.getFilePathFromUri(data.uri),
name: generateCombination(2, ' ', true),
type: 'video/mp4', // always MP4 type: 'video/mp4', // always MP4
duration: 0, duration: 0,
}; };

View file

@ -75,29 +75,37 @@ class TagPage extends React.PureComponent {
return ( return (
<View style={discoverStyle.container}> <View style={discoverStyle.container}>
<UriBar navigation={navigation} belowOverlay={showSortPicker || showTimePicker} /> <UriBar navigation={navigation} belowOverlay={showSortPicker || showTimePicker} />
<ClaimList {this.state.tag && (
ListHeaderComponent={ <ClaimList
<View style={discoverStyle.tagTitleRow}> ListHeaderComponent={
<Text style={discoverStyle.tagPageTitle}>{formatTagTitle(tag)}</Text> <View style={discoverStyle.tagTitleRow}>
{Constants.SORT_BY_TOP === sortByItem.name && ( <Text style={discoverStyle.tagPageTitle}>{formatTagTitle(tag)}</Text>
<TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}> {Constants.SORT_BY_TOP === sortByItem.name && (
<Text style={discoverStyle.tagSortText}>{currentTimeItem.label}</Text> <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}>{sortByItem.label.split(' ')[0]}</Text>
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} />
</TouchableOpacity> </TouchableOpacity>
)} </View>
<TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}> }
<Text style={discoverStyle.tagSortText}>{sortByItem.label.split(' ')[0]}</Text> style={discoverStyle.tagPageClaimList}
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> orderBy={this.state.orderBy}
</TouchableOpacity> time={this.state.time}
</View> tags={[tag]}
} navigation={navigation}
style={discoverStyle.tagPageClaimList} orientation={Constants.ORIENTATION_VERTICAL}
orderBy={this.state.orderBy} />
time={this.state.time} )}
tags={[tag]}
navigation={navigation}
orientation={Constants.ORIENTATION_VERTICAL}
/>
{!showSortPicker && !showTimePicker && <FloatingWalletBalance navigation={navigation} />} {!showSortPicker && !showTimePicker && <FloatingWalletBalance navigation={navigation} />}
{showSortPicker && ( {showSortPicker && (
<ModalPicker <ModalPicker