rework discovery views with new/top/trending sorting #25

Merged
akinwale merged 9 commits from content-views into master 2019-08-20 10:03:34 +02:00
5 changed files with 100 additions and 96 deletions
Showing only changes of commit 84dda42a56 - Show all commits

View file

@ -161,8 +161,16 @@ class ClaimList extends React.PureComponent {
};
renderVerticalItem = ({ item }) => {
const { navigation } = this.props;
return <FileListItem key={item} uri={item} style={claimListStyle.verticalListItem} navigation={navigation} />;
const { hideChannel, navigation } = this.props;
return (
<FileListItem
key={item}
uri={item}
hideChannel={hideChannel}
style={claimListStyle.verticalListItem}
navigation={navigation}
/>
);
};
renderHorizontalItem = ({ item }) => {

View file

@ -1,7 +1,7 @@
// @flow
import React from 'react';
import { ActivityIndicator, Text, TouchableOpacity, View } from 'react-native';
import { formatBigNumberCredits } from 'lbry-redux';
import { formatCredits } from 'lbry-redux';
import Address from 'component/address';
import Button from 'component/button';
import Colors from 'styles/colors';
@ -34,7 +34,7 @@ class FloatingWalletBalance extends React.PureComponent<Props> {
<Icon name="coins" size={12} style={floatingButtonStyle.balanceIcon} />
{isNaN(balance) && <ActivityIndicator size="small" color={Colors.White} />}
{(!isNaN(balance) || balance === 0) && (
<Text style={floatingButtonStyle.text}>{formatBigNumberCredits(parseFloat(balance), 0)}</Text>
<Text style={floatingButtonStyle.text}>{formatCredits(parseFloat(balance), 0, true)}</Text>
)}
</TouchableOpacity>
</View>

View file

@ -1,26 +1,23 @@
import { connect } from 'react-redux';
import {
doFetchClaimsByChannel,
makeSelectClaimForUri,
makeSelectClaimsInChannelForCurrentPageState,
makeSelectFetchingChannelClaims,
makeSelectTotalPagesForChannel,
} from 'lbry-redux';
import { doFetchClaimsByChannel, makeSelectClaimForUri } from 'lbry-redux';
import { doPopDrawerStack } from 'redux/actions/drawer';
import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings';
import { selectDrawerStack } from 'redux/selectors/drawer';
import { selectSortByItem, selectTimeItem } from 'redux/selectors/settings';
import ChannelPage from './view';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
claimsInChannel: makeSelectClaimsInChannelForCurrentPageState(props.uri)(state),
drawerStack: selectDrawerStack(state),
fetching: makeSelectFetchingChannelClaims(props.uri)(state),
totalPages: makeSelectTotalPagesForChannel(props.uri, 10)(state), // Update to use a default PAGE_SIZE constant
sortByItem: selectSortByItem(state),
timeItem: selectTimeItem(state),
});
const perform = dispatch => ({
fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)),
popDrawerStack: () => dispatch(doPopDrawerStack()),
setSortByItem: item => dispatch(doSetSortByItem(item)),
setTimeItem: item => dispatch(doSetTimeItem(item)),
});
export default connect(

View file

@ -3,111 +3,86 @@ import React from 'react';
import { ActivityIndicator, Dimensions, Image, ScrollView, Text, TouchableOpacity, View } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
import { normalizeURI } from 'lbry-redux';
import { navigateBack } from 'utils/helper';
import { navigateBack, getOrderBy } from 'utils/helper';
import ClaimList from 'component/claimList';
import Colors from 'styles/colors';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import Button from 'component/button';
import Icon from 'react-native-vector-icons/FontAwesome5';
import Link from 'component/link';
import FileList from 'component/fileList';
import ModalPicker from 'component/modalPicker';
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';
import discoverStyle from 'styles/discover';
class ChannelPage extends React.PureComponent {
state = {
page: 1,
showPageButtons: false,
showSortPicker: false,
showTimePicker: false,
orderBy: Constants.DEFAULT_ORDER_BY,
activeTab: Constants.CONTENT_TAB,
};
componentDidMount() {
const { uri, page, claimsInChannel, fetchClaims, fetchClaimCount } = this.props;
if (!claimsInChannel || !claimsInChannel.length) {
fetchClaims(uri, page || this.state.page);
}
}
handlePreviousPage = () => {
const { uri, fetchClaims } = this.props;
if (this.state.page > 1) {
this.setState({ page: this.state.page - 1, showPageButtons: false }, () => {
fetchClaims(uri, this.state.page);
});
}
handleSortByItemSelected = item => {
const { setSortByItem } = this.props;
setSortByItem(item);
this.setState({ orderBy: getOrderBy(item), showSortPicker: false });
};
handleNextPage = () => {
const { uri, fetchClaims, totalPages } = this.props;
if (this.state.page < totalPages) {
this.setState({ page: this.state.page + 1, showPageButtons: false }, () => {
fetchClaims(uri, this.state.page);
});
}
handleTimeItemSelected = item => {
const { setTimeItem } = this.props;
setTimeItem(item);
this.setState({ showTimePicker: false });
};
listHeader = () => {
const { sortByItem, timeItem } = this.props;
return (
<View style={discoverStyle.listHeader}>
<View style={discoverStyle.pickerRow}>
<View style={discoverStyle.leftPickerRow}>
<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} />
</TouchableOpacity>
{Constants.SORT_BY_TOP === sortByItem.name && (
<TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}>
<Text style={discoverStyle.tagSortText}>{timeItem.label}</Text>
<Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} />
</TouchableOpacity>
)}
</View>
</View>
</View>
);
};
renderContent = () => {
const { fetching, claimsInChannel, totalPages, navigation } = this.props;
const { claim, navigation, timeItem } = this.props;
let contentList;
if (fetching) {
contentList = (
<View style={channelPageStyle.busyContainer}>
<ActivityIndicator size="large" color={Colors.NextLbryGreen} />
<Text style={channelPageStyle.infoText}>Fetching content...</Text>
</View>
);
} else {
contentList =
claimsInChannel && claimsInChannel.length ? (
<FileList
sortByHeight
hideFilter
fileInfos={claimsInChannel}
navigation={navigation}
style={channelPageStyle.fileList}
contentContainerStyle={channelPageStyle.fileListContent}
onEndReached={() => this.setState({ showPageButtons: true })}
/>
) : (
<View style={channelPageStyle.busyContainer}>
<Text style={channelPageStyle.infoText}>No content found.</Text>
</View>
);
}
let pageButtons;
if (totalPages > 1 && this.state.showPageButtons) {
pageButtons = (
<View style={channelPageStyle.pageButtons}>
<View>
{this.state.page > 1 && (
<Button
style={channelPageStyle.button}
text={'Previous'}
disabled={!!fetching}
onPress={this.handlePreviousPage}
/>
)}
</View>
{this.state.page < totalPages && (
<Button
style={[channelPageStyle.button, channelPageStyle.nextButton]}
text={'Next'}
disabled={!!fetching}
onPress={this.handleNextPage}
/>
)}
</View>
);
let channelId;
if (claim) {
channelId = claim.claim_id;
}
return (
<View style={channelPageStyle.contentTab}>
{contentList}
{pageButtons}
{channelId && (
<ClaimList
ListHeaderComponent={this.listHeader}
hideChannel
orderBy={this.state.orderBy}
time={timeItem.name}
navigation={navigation}
orientation={Constants.ORIENTATION_VERTICAL}
channelIds={[channelId]}
style={channelPageStyle.claimList}
/>
)}
</View>
);
};
@ -162,8 +137,9 @@ class ChannelPage extends React.PureComponent {
};
render() {
const { fetching, claimsInChannel, claim, navigation, totalPages, uri, drawerStack, popDrawerStack } = this.props;
const { claim, navigation, uri, drawerStack, popDrawerStack, sortByItem, timeItem } = this.props;
const { name, permanent_url: permanentUrl } = claim;
const { showSortPicker, showTimePicker } = this.state;
let thumbnailUrl, coverUrl, title, fullUri;
if (claim) {
@ -242,6 +218,25 @@ class ChannelPage extends React.PureComponent {
{Constants.CONTENT_TAB === this.state.activeTab && this.renderContent()}
{Constants.ABOUT_TAB === this.state.activeTab && this.renderAbout()}
</View>
{showSortPicker && (
<ModalPicker
title={__('Sort content by')}
onOverlayPress={() => this.setState({ showSortPicker: false })}
onItemSelected={this.handleSortByItemSelected}
selectedItem={sortByItem}
items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS}
/>
)}
{showTimePicker && (
<ModalPicker
title={__('Content from')}
onOverlayPress={() => this.setState({ showTimePicker: false })}
onItemSelected={this.handleTimeItemSelected}
selectedItem={timeItem}
items={Constants.CLAIM_SEARCH_TIME_ITEMS}
/>
)}
</View>
);
}

View file

@ -69,7 +69,7 @@ const channelPageStyle = StyleSheet.create({
subscribeButtonContainer: {
position: 'absolute',
flexDirection: 'row',
left: 8,
right: 8,
bottom: -90,
zIndex: 100,
},
@ -153,6 +153,10 @@ const channelPageStyle = StyleSheet.create({
width: '100%',
height: '100%',
},
claimList: {
flex: 1,
marginTop: 16,
},
});
export default channelPageStyle;