empty state views. fix publishing state.
This commit is contained in:
parent
c08d5879fb
commit
e1ed6e1477
17 changed files with 161 additions and 63 deletions
BIN
src/assets/gerbil-happy.png
Normal file
BIN
src/assets/gerbil-happy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 265 KiB |
BIN
src/assets/gerbil-sad.png
Normal file
BIN
src/assets/gerbil-sad.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 278 KiB |
4
src/component/emptyStateView/index.js
Normal file
4
src/component/emptyStateView/index.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { connect } from 'react-redux';
|
||||
import EmptyStateView from './view';
|
||||
|
||||
export default connect()(EmptyStateView);
|
26
src/component/emptyStateView/view.js
Normal file
26
src/component/emptyStateView/view.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import React from 'react';
|
||||
import { NativeModules, Text, View, Image, TouchableOpacity } from 'react-native';
|
||||
import Button from '../button';
|
||||
import emptyStateStyle from 'styles/emptyState';
|
||||
|
||||
class EmptyStateView extends React.PureComponent {
|
||||
render() {
|
||||
const { message, buttonText, inner, onButtonPress } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[emptyStateStyle.container, inner ? emptyStateStyle.innerContainer : emptyStateStyle.outerContainer]}
|
||||
>
|
||||
<Image style={emptyStateStyle.image} resizeMode={'stretch'} source={require('../../assets/gerbil-happy.png')} />
|
||||
<Text style={emptyStateStyle.message}>{message}</Text>
|
||||
{buttonText && (
|
||||
<View style={emptyStateStyle.buttonContainer}>
|
||||
<Button style={emptyStateStyle.button} text={buttonText} onPress={onButtonPress} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EmptyStateView;
|
|
@ -46,6 +46,7 @@ import isEqual from 'utils/deep-equal';
|
|||
|
||||
const globalExceptionHandler = (error, isFatal) => {
|
||||
if (error && NativeModules.Firebase) {
|
||||
console.log(error);
|
||||
NativeModules.Firebase.logException(isFatal, error.message ? error.message : 'No message', JSON.stringify(error));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { makeSelectClaimForUri, selectMyChannelClaims } from 'lbry-redux';
|
||||
import { doAbandonClaim, doFetchChannelListMine, makeSelectClaimForUri, selectMyChannelClaims } from 'lbry-redux';
|
||||
import { doPopDrawerStack } from 'redux/actions/drawer';
|
||||
import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings';
|
||||
import { selectDrawerStack } from 'redux/selectors/drawer';
|
||||
|
@ -15,6 +15,8 @@ const select = (state, props) => ({
|
|||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)),
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
popDrawerStack: () => dispatch(doPopDrawerStack()),
|
||||
setSortByItem: item => dispatch(doSetSortByItem(item)),
|
||||
setTimeItem: item => dispatch(doSetTimeItem(item)),
|
||||
|
|
|
@ -47,7 +47,9 @@ class ChannelPage extends React.PureComponent {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { fetchChannelListMine } = this.props;
|
||||
NativeModules.Firebase.setCurrentScreen('Channel');
|
||||
fetchChannelListMine();
|
||||
}
|
||||
|
||||
handleSortByItemSelected = item => {
|
||||
|
@ -266,7 +268,7 @@ class ChannelPage extends React.PureComponent {
|
|||
)}
|
||||
{ownedChannel && (
|
||||
<Button
|
||||
style={channelPageStyle.deleteButton}
|
||||
style={[channelPageStyle.actionButton, channelPageStyle.deleteButton]}
|
||||
theme={'light'}
|
||||
icon={'trash-alt'}
|
||||
text={'Delete'}
|
||||
|
|
|
@ -19,6 +19,7 @@ import Button from 'component/button';
|
|||
import ChannelIconItem from 'component/channelIconItem';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import EmptyStateView from 'component/emptyStateView';
|
||||
import FloatingWalletBalance from 'component/floatingWalletBalance';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||
import Link from 'component/link';
|
||||
|
@ -175,10 +176,8 @@ export default class ChannelCreator extends React.PureComponent {
|
|||
|
||||
if (!isEditMode && hasFormState) {
|
||||
this.loadPendingFormState();
|
||||
this.setState({ currentPhase: Constants.PHASE_CREATE });
|
||||
} else {
|
||||
this.setState({ currentPhase: Constants.PHASE_LIST });
|
||||
}
|
||||
this.setState({ currentPhase: isEditMode || hasFormState ? Constants.PHASE_CREATE : Constants.PHASE_LIST });
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -747,6 +746,8 @@ export default class ChannelCreator extends React.PureComponent {
|
|||
uploadingImage,
|
||||
} = this.state;
|
||||
|
||||
const hasChannels = channels && channels.length > 0;
|
||||
|
||||
return (
|
||||
<View style={channelCreatorStyle.container}>
|
||||
<UriBar
|
||||
|
@ -759,26 +760,25 @@ export default class ChannelCreator extends React.PureComponent {
|
|||
onExitSelectionMode={this.onExitSelectionMode}
|
||||
/>
|
||||
|
||||
{fetchingChannels && (
|
||||
<View style={channelCreatorStyle.loading}>
|
||||
<ActivityIndicator size={'large'} color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
)}
|
||||
|
||||
{currentPhase === Constants.PHASE_LIST && !fetchingChannels && !hasChannels && (
|
||||
<EmptyStateView
|
||||
message={'You have not created a channel.\nStart now by creating a new channel!'}
|
||||
buttonText={'Create a channel'}
|
||||
onButtonPress={this.handleNewChannelPress}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentPhase === Constants.PHASE_LIST && (
|
||||
<FlatList
|
||||
extraData={this.state}
|
||||
ListHeaderComponent={
|
||||
fetchingChannels ? (
|
||||
<View style={channelCreatorStyle.listHeader}>
|
||||
<ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
) : null
|
||||
}
|
||||
ListEmptyComponent={
|
||||
fetchingChannels ? null : (
|
||||
<View style={channelCreatorStyle.listEmpty}>
|
||||
<Text style={channelCreatorStyle.listEmptyText}>
|
||||
You have not created a channel. Start now by creating a new channel!
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
ListFooterComponent={
|
||||
!channels || channels.length === 0 ? null : (
|
||||
<View style={channelCreatorStyle.listFooter}>
|
||||
<Button
|
||||
style={channelCreatorStyle.createChannelButton}
|
||||
|
@ -786,6 +786,7 @@ export default class ChannelCreator extends React.PureComponent {
|
|||
onPress={this.handleNewChannelPress}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
style={channelCreatorStyle.scrollContainer}
|
||||
contentContainerStyle={channelCreatorStyle.scrollPadding}
|
||||
|
|
|
@ -15,6 +15,7 @@ import { __, navigateToUri, uriFromFileInfo } from 'utils/helper';
|
|||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import PageHeader from 'component/pageHeader';
|
||||
import EmptyStateView from 'component/emptyStateView';
|
||||
import FileListItem from 'component/fileListItem';
|
||||
import FloatingWalletBalance from 'component/floatingWalletBalance';
|
||||
import StorageStatsCard from 'component/storageStatsCard';
|
||||
|
@ -154,6 +155,10 @@ class DownloadsPage extends React.PureComponent {
|
|||
onDeleteActionPressed={this.onDeleteActionPressed}
|
||||
/>
|
||||
|
||||
{!fetching && !hasDownloads && (
|
||||
<EmptyStateView message={'You do not have any\ndownloaded content on this device.'} />
|
||||
)}
|
||||
|
||||
<View style={downloadsStyle.subContainer}>
|
||||
{hasDownloads && <StorageStatsCard fileInfos={this.getFilteredFileInfos()} />}
|
||||
{fetching && (
|
||||
|
@ -161,11 +166,7 @@ class DownloadsPage extends React.PureComponent {
|
|||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={downloadsStyle.loading} />
|
||||
</View>
|
||||
)}
|
||||
{!fetching && !hasDownloads && (
|
||||
<View style={downloadsStyle.busyContainer}>
|
||||
<Text style={downloadsStyle.noDownloadsText}>You do not have any downloaded content on this device.</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{!fetching && hasDownloads && (
|
||||
<FlatList
|
||||
extraData={this.state}
|
||||
|
|
|
@ -22,6 +22,7 @@ import { navigateBack, navigateToUri } from 'utils/helper';
|
|||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||
import Button from 'component/button';
|
||||
import EmptyStateView from 'component/emptyStateView';
|
||||
import Tag from 'component/tag';
|
||||
import ChannelPage from 'page/channel';
|
||||
import Colors from 'styles/colors';
|
||||
|
@ -100,7 +101,7 @@ class FilePage extends React.PureComponent {
|
|||
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
|
||||
DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted);
|
||||
|
||||
const { fetchChannelListMine, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
|
||||
const { fetchMyClaims, fileInfo, isResolvingUri, resolveUri, navigation } = this.props;
|
||||
const { uri, uriVars } = navigation.state.params;
|
||||
this.setState({ uri, uriVars });
|
||||
|
||||
|
@ -108,7 +109,7 @@ class FilePage extends React.PureComponent {
|
|||
|
||||
this.fetchFileInfo(this.props);
|
||||
this.fetchCostInfo(this.props);
|
||||
fetchChannelListMine();
|
||||
fetchMyClaims();
|
||||
|
||||
if (NativeModules.Firebase) {
|
||||
NativeModules.Firebase.track('open_file_page', { uri: uri });
|
||||
|
@ -590,14 +591,15 @@ class FilePage extends React.PureComponent {
|
|||
} = this.props;
|
||||
const { uri, autoplay } = navigation.state.params;
|
||||
|
||||
const { isChannel } = parseURI(uri);
|
||||
const myChannelUris = channels ? channels.map(channel => channel.permanent_url) : [];
|
||||
const ownedClaim = myClaimUris.includes(uri) || myChannelUris.includes(uri);
|
||||
const { isChannel } = parseURI(uri);
|
||||
|
||||
let innerContent = null;
|
||||
if ((isResolvingUri && !claim) || !claim) {
|
||||
return (
|
||||
<View style={filePageStyle.container}>
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
{isResolvingUri && (
|
||||
<View style={filePageStyle.busyContainer}>
|
||||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} />
|
||||
|
@ -607,16 +609,29 @@ class FilePage extends React.PureComponent {
|
|||
{claim === null && !isResolvingUri && (
|
||||
<View style={filePageStyle.container}>
|
||||
{ownedClaim && (
|
||||
<Text style={filePageStyle.emptyClaimText}>
|
||||
{isChannel
|
||||
<EmptyStateView
|
||||
message={
|
||||
isChannel
|
||||
? 'It looks like you just created this channel. It will appear in a few minutes.'
|
||||
: 'It looks you just published this content. It will appear in a few minutes.'}
|
||||
</Text>
|
||||
: 'It looks you just published this content. It will appear in a few minutes.'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{!ownedClaim && (
|
||||
<EmptyStateView
|
||||
message={"There's nothing at this location."}
|
||||
buttonText={'Publish something here'}
|
||||
onButtonPress={() =>
|
||||
navigation.navigate({
|
||||
routeName: Constants.DRAWER_ROUTE_PUBLISH,
|
||||
params: { vanityUrl: uri.trim() },
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{!ownedClaim && <Text style={filePageStyle.emptyClaimText}>There's nothing at this location.</Text>}
|
||||
</View>
|
||||
)}
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
<FloatingWalletBalance navigation={navigation} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -199,9 +199,6 @@ class PublishPage extends React.PureComponent {
|
|||
vanityUrlSet = false;
|
||||
if (navigation.state.params) {
|
||||
const { displayForm, editMode, claimToEdit, vanityUrl } = navigation.state.params;
|
||||
console.log('editMode=' + editMode);
|
||||
console.log('***claimToEdit***');
|
||||
console.log(claimToEdit);
|
||||
if (editMode) {
|
||||
this.prepareEdit(claimToEdit);
|
||||
isEditMode = true;
|
||||
|
@ -259,6 +256,7 @@ class PublishPage extends React.PureComponent {
|
|||
this.setState(
|
||||
{
|
||||
editMode: true,
|
||||
publishStarted: false,
|
||||
currentPhase: Constants.PHASE_DETAILS,
|
||||
|
||||
hasEditedContentAddress: true,
|
||||
|
@ -390,6 +388,7 @@ class PublishPage extends React.PureComponent {
|
|||
message: `Your content was successfully published to ${this.state.uri}. It will be available in a few mintues.`,
|
||||
});
|
||||
clearPublishFormState();
|
||||
this.setState({ publishStarted: false });
|
||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISHES, params: { publishSuccess: true } });
|
||||
};
|
||||
|
||||
|
@ -1174,17 +1173,17 @@ class PublishPage extends React.PureComponent {
|
|||
</View>
|
||||
|
||||
<View style={publishStyle.actionButtons}>
|
||||
{(this.state.publishStarted || publishFormValues.publishing) && (
|
||||
{this.state.publishStarted && (
|
||||
<View style={publishStyle.progress}>
|
||||
<ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />
|
||||
</View>
|
||||
)}
|
||||
|
||||
{!publishFormValues.publishing && !this.state.publishStarted && (
|
||||
{!this.state.publishStarted && (
|
||||
<Link style={publishStyle.cancelLink} text="Cancel" onPress={() => this.showSelector()} />
|
||||
)}
|
||||
|
||||
{!publishFormValues.publishing && !this.state.publishStarted && (
|
||||
{!this.state.publishStarted && (
|
||||
<View style={publishStyle.rightActionButtons}>
|
||||
<Button
|
||||
style={publishStyle.publishButton}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { ActivityIndicator, Alert, FlatList, NativeModules, Text, TouchableOpaci
|
|||
import Button from 'component/button';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import EmptyStateView from 'component/emptyStateView';
|
||||
import FileListItem from 'component/fileListItem';
|
||||
import FloatingWalletBalance from 'component/floatingWalletBalance';
|
||||
import UriBar from 'component/uriBar';
|
||||
|
@ -137,16 +138,11 @@ class PublishesPage extends React.PureComponent {
|
|||
)}
|
||||
|
||||
{!fetching && (!uris || uris.length === 0) && (
|
||||
<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 })}
|
||||
<EmptyStateView
|
||||
message={__('It looks like you have not\npublished any content to LBRY yet.')}
|
||||
buttonText={__('Publish something new')}
|
||||
onButtonPress={() => navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH })}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{uris && uris.length > 0 && (
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||
import { ActivityIndicator, NativeModules, View, ScrollView, Text } from 'react-native';
|
||||
import Colors from 'styles/colors';
|
||||
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
|
||||
import EmptyStateView from 'component/emptyStateView';
|
||||
import TransactionList from 'component/transactionList';
|
||||
import UriBar from 'component/uriBar';
|
||||
import walletStyle from 'styles/wallet';
|
||||
|
@ -53,11 +54,9 @@ class TransactionHistoryPage extends React.PureComponent {
|
|||
<Text style={walletStyle.loadingText}>Loading transactions...</Text>
|
||||
</View>
|
||||
)}
|
||||
{!fetchingTransactions && transactions.length === 0 && <EmptyStateView message={'No transactions to list.'} />}
|
||||
<ScrollView style={walletStyle.transactionHistoryScroll}>
|
||||
<View style={walletStyle.historyList}>
|
||||
{!fetchingTransactions && transactions.length === 0 && (
|
||||
<Text style={walletStyle.infoText}>No transactions to list.</Text>
|
||||
)}
|
||||
{!fetchingTransactions && transactions && transactions.length > 0 && (
|
||||
<TransactionList navigation={navigation} transactions={transactions} />
|
||||
)}
|
||||
|
|
|
@ -121,7 +121,7 @@ const channelCreatorStyle = StyleSheet.create({
|
|||
height: '100%',
|
||||
},
|
||||
listFooter: {
|
||||
marginTop: 24,
|
||||
marginTop: 8,
|
||||
},
|
||||
createChannelButton: {
|
||||
backgroundColor: Colors.LbryGreen,
|
||||
|
@ -254,6 +254,15 @@ const channelCreatorStyle = StyleSheet.create({
|
|||
fontSize: 12,
|
||||
marginLeft: 4,
|
||||
},
|
||||
loading: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default channelCreatorStyle;
|
||||
|
|
|
@ -169,6 +169,9 @@ const channelPageStyle = StyleSheet.create({
|
|||
actionButton: {
|
||||
backgroundColor: Colors.White,
|
||||
},
|
||||
deleteButton: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default channelPageStyle;
|
||||
|
|
40
src/styles/emptyState.js
Normal file
40
src/styles/emptyState.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
import Colors from './colors';
|
||||
|
||||
const emptyStateStyle = StyleSheet.create({
|
||||
container: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
paddingLeft: 24,
|
||||
paddingRight: 24,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
zIndex: 99,
|
||||
},
|
||||
outerContainer: {
|
||||
top: 60,
|
||||
},
|
||||
innerContainer: {
|
||||
top: 0,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: Colors.LbryGreen,
|
||||
fontSize: 18,
|
||||
},
|
||||
image: {
|
||||
width: 128,
|
||||
height: 170,
|
||||
},
|
||||
message: {
|
||||
marginTop: 24,
|
||||
textAlign: 'center',
|
||||
fontFamily: 'Inter-UI-Regular',
|
||||
fontSize: 18,
|
||||
lineHeight: 28,
|
||||
marginBottom: 24,
|
||||
},
|
||||
});
|
||||
|
||||
export default emptyStateStyle;
|
|
@ -437,7 +437,7 @@ const publishStyle = StyleSheet.create({
|
|||
color: Colors.DescriptionGrey,
|
||||
},
|
||||
publishesFooter: {
|
||||
marginTop: 16,
|
||||
marginTop: 2,
|
||||
marginLeft: 16,
|
||||
marginRight: 16,
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue