add publishes page #5
7 changed files with 167 additions and 12 deletions
|
@ -6,6 +6,7 @@ import DrawerContent from 'component/drawerContent';
|
||||||
import FilePage from 'page/file';
|
import FilePage from 'page/file';
|
||||||
import FirstRunScreen from 'page/firstRun';
|
import FirstRunScreen from 'page/firstRun';
|
||||||
import PublishPage from 'page/publish';
|
import PublishPage from 'page/publish';
|
||||||
|
import PublishesPage from 'page/publishes';
|
||||||
import RewardsPage from 'page/rewards';
|
import RewardsPage from 'page/rewards';
|
||||||
import TagPage from 'page/tag';
|
import TagPage from 'page/tag';
|
||||||
import TrendingPage from 'page/trending';
|
import TrendingPage from 'page/trending';
|
||||||
|
@ -162,6 +163,12 @@ const drawer = createDrawerNavigator(
|
||||||
drawerIcon: ({ tintColor }) => <Icon name="upload" size={20} style={{ color: tintColor }} />,
|
drawerIcon: ({ tintColor }) => <Icon name="upload" size={20} style={{ color: tintColor }} />,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Publishes: {
|
||||||
|
screen: PublishesPage,
|
||||||
|
navigationOptions: {
|
||||||
|
drawerIcon: ({ tintColor }) => <Icon name="cloud-upload-alt" size={20} style={{ color: tintColor }} />,
|
||||||
|
},
|
||||||
|
},
|
||||||
Rewards: {
|
Rewards: {
|
||||||
screen: RewardsPage,
|
screen: RewardsPage,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
|
|
|
@ -58,6 +58,7 @@ class FileListItem extends React.PureComponent {
|
||||||
onPress,
|
onPress,
|
||||||
navigation,
|
navigation,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
|
hideChannel,
|
||||||
title,
|
title,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ class FileListItem extends React.PureComponent {
|
||||||
{this.formatTitle(title) || this.formatTitle(name)}
|
{this.formatTitle(title) || this.formatTitle(name)}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
{channel && (
|
{channel && !hideChannel && (
|
||||||
<Link
|
<Link
|
||||||
style={fileListStyle.publisher}
|
style={fileListStyle.publisher}
|
||||||
text={channel}
|
text={channel}
|
||||||
|
|
|
@ -60,6 +60,7 @@ const Constants = {
|
||||||
DRAWER_ROUTE_SUBSCRIPTIONS: 'Subscriptions',
|
DRAWER_ROUTE_SUBSCRIPTIONS: 'Subscriptions',
|
||||||
DRAWER_ROUTE_MY_LBRY: 'Downloads',
|
DRAWER_ROUTE_MY_LBRY: 'Downloads',
|
||||||
DRAWER_ROUTE_PUBLISH: 'Publish',
|
DRAWER_ROUTE_PUBLISH: 'Publish',
|
||||||
|
DRAWER_ROUTE_PUBLISHES: 'Publishes',
|
||||||
DRAWER_ROUTE_REWARDS: 'Rewards',
|
DRAWER_ROUTE_REWARDS: 'Rewards',
|
||||||
DRAWER_ROUTE_WALLET: 'Wallet',
|
DRAWER_ROUTE_WALLET: 'Wallet',
|
||||||
DRAWER_ROUTE_SETTINGS: 'Settings',
|
DRAWER_ROUTE_SETTINGS: 'Settings',
|
||||||
|
@ -113,6 +114,8 @@ export const DrawerRoutes = [
|
||||||
Constants.DRAWER_ROUTE_MY_LBRY,
|
Constants.DRAWER_ROUTE_MY_LBRY,
|
||||||
Constants.DRAWER_ROUTE_REWARDS,
|
Constants.DRAWER_ROUTE_REWARDS,
|
||||||
Constants.DRAWER_ROUTE_WALLET,
|
Constants.DRAWER_ROUTE_WALLET,
|
||||||
|
Constants.DRAWER_ROUTE_PUBLISH,
|
||||||
|
Constants.DRAWER_ROUTE_PUBLISHES,
|
||||||
Constants.DRAWER_ROUTE_SETTINGS,
|
Constants.DRAWER_ROUTE_SETTINGS,
|
||||||
Constants.DRAWER_ROUTE_ABOUT,
|
Constants.DRAWER_ROUTE_ABOUT,
|
||||||
Constants.DRAWER_ROUTE_SEARCH,
|
Constants.DRAWER_ROUTE_SEARCH,
|
||||||
|
|
|
@ -123,6 +123,17 @@ class PublishPage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onComponentFocused = () => {
|
||||||
|
const { pushDrawerStack, setPlayerVisible } = this.props;
|
||||||
|
|
||||||
|
pushDrawerStack();
|
||||||
|
setPlayerVisible();
|
||||||
|
|
||||||
|
NativeModules.Gallery.canUseCamera().then(canUseCamera => this.setState({ canUseCamera }));
|
||||||
|
NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath }));
|
||||||
|
NativeModules.Gallery.getVideos().then(videos => this.setState({ videos }));
|
||||||
|
};
|
||||||
|
|
||||||
getNewUri(name, channel) {
|
getNewUri(name, channel) {
|
||||||
const { resolveUri } = this.props;
|
const { resolveUri } = this.props;
|
||||||
// If they are midway through a channel creation, treat it as anonymous until it completes
|
// If they are midway through a channel creation, treat it as anonymous until it completes
|
||||||
|
@ -212,17 +223,6 @@ class PublishPage extends React.PureComponent {
|
||||||
this.setState({ publishStarted: true }, () => publish(publishParams));
|
this.setState({ publishStarted: true }, () => publish(publishParams));
|
||||||
};
|
};
|
||||||
|
|
||||||
onComponentFocused = () => {
|
|
||||||
const { pushDrawerStack, setPlayerVisible } = this.props;
|
|
||||||
|
|
||||||
pushDrawerStack();
|
|
||||||
setPlayerVisible();
|
|
||||||
|
|
||||||
NativeModules.Gallery.canUseCamera().then(canUseCamera => this.setState({ canUseCamera }));
|
|
||||||
NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath }));
|
|
||||||
NativeModules.Gallery.getVideos().then(videos => this.setState({ videos }));
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.onComponentFocused();
|
this.onComponentFocused();
|
||||||
}
|
}
|
||||||
|
|
21
src/page/publishes/index.js
Normal file
21
src/page/publishes/index.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doCheckPendingPublishes, selectMyClaimUrisWithoutChannels, selectIsFetchingClaimListMine } from 'lbry-redux';
|
||||||
|
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||||
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
|
import PublishesPage from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
uris: selectMyClaimUrisWithoutChannels(state),
|
||||||
|
fetching: selectIsFetchingClaimListMine(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
checkPendingPublishes: () => dispatch(doCheckPendingPublishes()),
|
||||||
|
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISHES)),
|
||||||
|
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(PublishesPage);
|
80
src/page/publishes/view.js
Normal file
80
src/page/publishes/view.js
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ActivityIndicator, FlatList, Text, TouchableOpacity, View } from 'react-native';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import Colors from 'styles/colors';
|
||||||
|
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||||
|
import FileListItem from 'component/fileListItem';
|
||||||
|
import FloatingWalletBalance from 'component/floatingWalletBalance';
|
||||||
|
import UriBar from 'component/uriBar';
|
||||||
|
import publishStyle from 'styles/publish';
|
||||||
|
import { __ } from 'utils/helper';
|
||||||
|
|
||||||
|
class PublishesPage extends React.PureComponent {
|
||||||
|
didFocusListener;
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
if (this.didFocusListener) {
|
||||||
|
this.didFocusListener.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onComponentFocused = () => {
|
||||||
|
const { checkPendingPublishes, pushDrawerStack, setPlayerVisible } = this.props;
|
||||||
|
|
||||||
|
pushDrawerStack();
|
||||||
|
setPlayerVisible();
|
||||||
|
checkPendingPublishes();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { fetching, navigation, uris } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={publishStyle.container}>
|
||||||
|
<UriBar navigation={navigation} />
|
||||||
|
{fetching && (
|
||||||
|
<View style={publishStyle.centered}>
|
||||||
|
<ActivityIndicator size={'small'} color={Colors.LbryGreen} />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!fetching && (!uris || uris.length === 0) && (
|
||||||
I usually do this to prevent errors, as there have been cases where the selectors return null or undefined. I will update the corresponding selectors in I usually do this to prevent errors, as there have been cases where the selectors return null or undefined. I will update the corresponding selectors in `lbry-redux`.
|
|||||||
|
<View style={publishStyle.noPublishes}>
|
||||||
|
<Text style={publishStyle.noPublishText}>
|
||||||
|
{__('It looks like you have not published anything to LBRY yet.')}
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
style={publishStyle.publishNowButton}
|
||||||
|
text={__('Publish something new')}
|
||||||
|
onPress={() => navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH })}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{uris && uris.length > 0 && (
|
||||||
|
<FlatList
|
||||||
|
style={publishStyle.publishesList}
|
||||||
|
contentContainerStyle={publishStyle.publishesScrollPadding}
|
||||||
|
initialNumToRender={8}
|
||||||
|
maxToRenderPerBatch={24}
|
||||||
|
removeClippedSubviews
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<FileListItem hideChannel key={item} uri={item} style={publishStyle.listItem} navigation={navigation} />
|
||||||
|
)}
|
||||||
|
data={uris}
|
||||||
|
keyExtractor={(item, index) => item}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<FloatingWalletBalance navigation={navigation} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PublishesPage;
|
|
@ -326,6 +326,49 @@ const publishStyle = StyleSheet.create({
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
marginLeft: 8,
|
marginLeft: 8,
|
||||||
},
|
},
|
||||||
|
centered: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 60,
|
||||||
|
bottom: 0,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
noPublishes: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 60,
|
||||||
|
bottom: 0,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: 16,
|
||||||
|
},
|
||||||
|
noPublishText: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
publishNowButton: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
backgroundColor: Colors.LbryGreen,
|
||||||
|
marginTop: 16,
|
||||||
|
},
|
||||||
|
publishesList: {
|
||||||
|
flex: 1,
|
||||||
|
marginTop: 60,
|
||||||
|
},
|
||||||
|
publishesScrollPadding: {
|
||||||
|
paddingBottom: 16,
|
||||||
|
},
|
||||||
|
listItem: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
marginTop: 8,
|
||||||
|
marginLeft: 8,
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default publishStyle;
|
export default publishStyle;
|
||||||
|
|
Loading…
Reference in a new issue
similar to feedback given in the last PR, I think it makes sense to have it be the responsibility of the selector to return an array, rather than to require components to repeat this check anywhere that selector is used