rework discovery views with new/top/trending sorting #25
5 changed files with 100 additions and 96 deletions
|
@ -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 }) => {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue