improve ux for insufficient balance for channel creation and publish (#58)

This commit is contained in:
Akinwale Ariwodola 2019-10-15 17:56:22 +01:00 committed by GitHub
parent b258654d60
commit eca6af122b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 48 additions and 21 deletions

View file

@ -9,7 +9,7 @@ class FileRewardsDriver extends React.PureComponent<Props> {
return ( return (
<TouchableOpacity style={filePageStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}> <TouchableOpacity style={filePageStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}>
<Icon name="award" size={16} style={filePageStyle.rewardIcon} /> <Icon name="award" size={16} style={filePageStyle.rewardDriverIcon} />
<Text style={filePageStyle.rewardDriverText}>Earn some credits to access this content.</Text> <Text style={filePageStyle.rewardDriverText}>Earn some credits to access this content.</Text>
</TouchableOpacity> </TouchableOpacity>
); );

View file

@ -138,6 +138,8 @@ const Constants = {
MORE_PLACEHOLDER: '_more', MORE_PLACEHOLDER: '_more',
TRUE_STRING: 'true', TRUE_STRING: 'true',
MINIMUM_TRANSACTION_BALANCE: 0.1,
}; };
export default Constants; export default Constants;

View file

@ -32,9 +32,11 @@ import channelIconStyle from 'styles/channelIcon';
import seedrandom from 'seedrandom'; import seedrandom from 'seedrandom';
export default class ChannelCreator extends React.PureComponent { export default class ChannelCreator extends React.PureComponent {
scrollView = null;
state = { state = {
autoStyle: null, autoStyle: null,
canSave: false, canSave: true,
claimId: null, claimId: null,
currentSelectedValue: Constants.ITEM_ANONYMOUS, currentSelectedValue: Constants.ITEM_ANONYMOUS,
currentPhase: null, currentPhase: null,
@ -161,9 +163,6 @@ export default class ChannelCreator extends React.PureComponent {
if (!fetchingChannels) { if (!fetchingChannels) {
fetchChannelListMine(); fetchChannelListMine();
} }
if (balance >= 0.1) {
this.setState({ canSave: true });
}
DeviceEventEmitter.addListener('onDocumentPickerFilePicked', this.onFilePicked); DeviceEventEmitter.addListener('onDocumentPickerFilePicked', this.onFilePicked);
DeviceEventEmitter.addListener('onDocumentPickerCanceled', this.onPickerCanceled); DeviceEventEmitter.addListener('onDocumentPickerCanceled', this.onPickerCanceled);
@ -392,6 +391,16 @@ export default class ChannelCreator extends React.PureComponent {
website, website,
} = this.state; } = this.state;
if (balance < Constants.MINIMUM_TRANSACTION_BALANCE) {
notify({
message: 'Creating a channel requires credits. Press the blue bar to get some for free.',
});
if (this.scrollView) {
this.scrollView.scrollTo({ x: 0, y: 0, animated: true });
}
return;
}
if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) { if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) {
notify({ message: 'Your channel name contains invalid characters.' }); notify({ message: 'Your channel name contains invalid characters.' });
return; return;
@ -528,9 +537,9 @@ export default class ChannelCreator extends React.PureComponent {
}; };
handleNewChannelPress = () => { handleNewChannelPress = () => {
const { balance, pushDrawerStack } = this.props; const { pushDrawerStack } = this.props;
pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM); pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM);
this.setState({ canSave: balance >= 0.1, currentPhase: Constants.PHASE_CREATE }); this.setState({ currentPhase: Constants.PHASE_CREATE });
}; };
handleCreateCancel = () => { handleCreateCancel = () => {
@ -548,7 +557,7 @@ export default class ChannelCreator extends React.PureComponent {
resetChannelCreator = () => { resetChannelCreator = () => {
this.setState({ this.setState({
canSave: false, canSave: true,
claimId: null, claimId: null,
editMode: false, editMode: false,
displayName: null, displayName: null,
@ -610,7 +619,7 @@ export default class ChannelCreator extends React.PureComponent {
pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM); pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM);
this.setState({ this.setState({
canSave: balance >= 0.1, canSave: true,
claimId: channel.claim_id, claimId: channel.claim_id,
currentPhase: Constants.PHASE_CREATE, currentPhase: Constants.PHASE_CREATE,
displayName: value && value.title ? value.title : channel.name.substring(1), displayName: value && value.title ? value.title : channel.name.substring(1),
@ -841,7 +850,7 @@ export default class ChannelCreator extends React.PureComponent {
)} )}
{currentPhase === Constants.PHASE_CREATE && ( {currentPhase === Constants.PHASE_CREATE && (
<ScrollView style={channelCreatorStyle.createChannelContainer}> <ScrollView ref={ref => (this.scrollView = ref)} style={channelCreatorStyle.createChannelContainer}>
<View style={channelCreatorStyle.imageSelectors}> <View style={channelCreatorStyle.imageSelectors}>
<TouchableOpacity style={channelCreatorStyle.coverImageTouchArea} onPress={this.onCoverImagePress}> <TouchableOpacity style={channelCreatorStyle.coverImageTouchArea} onPress={this.onCoverImagePress}>
<Image <Image
@ -886,7 +895,7 @@ export default class ChannelCreator extends React.PureComponent {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
{balance < 0.1 && <ChannelRewardsDriver navigation={navigation} />} {balance < Constants.MINIMUM_TRANSACTION_BALANCE && <ChannelRewardsDriver navigation={navigation} />}
<View style={channelCreatorStyle.card}> <View style={channelCreatorStyle.card}>
<View style={channelCreatorStyle.textInputLayout}> <View style={channelCreatorStyle.textInputLayout}>
@ -1046,7 +1055,7 @@ export default class ChannelCreator extends React.PureComponent {
<Link style={channelCreatorStyle.cancelLink} text="Cancel" onPress={this.handleCreateCancel} /> <Link style={channelCreatorStyle.cancelLink} text="Cancel" onPress={this.handleCreateCancel} />
<Button <Button
style={channelCreatorStyle.createButton} style={channelCreatorStyle.createButton}
disabled={!canSave || uploadingImage || !newChannelName || newChannelName.trim().length === 0} disabled={!canSave || uploadingImage}
text={editMode ? 'Update' : 'Create'} text={editMode ? 'Update' : 'Create'}
onPress={this.handleCreateChannelClick} onPress={this.handleCreateChannelClick}
/> />

View file

@ -76,8 +76,10 @@ const languages = {
class PublishPage extends React.PureComponent { class PublishPage extends React.PureComponent {
camera = null; camera = null;
scrollView = null;
state = { state = {
canPublish: false, canPublish: true,
canUseCamera: false, canUseCamera: false,
documentPickerOpen: false, documentPickerOpen: false,
editMode: false, editMode: false,
@ -186,7 +188,6 @@ class PublishPage extends React.PureComponent {
NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath })); NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath }));
this.setState( this.setState(
{ {
canPublish: balance >= 0.1,
loadingVideos: true, loadingVideos: true,
}, },
() => { () => {
@ -319,7 +320,7 @@ class PublishPage extends React.PureComponent {
}; };
handlePublishPressed = () => { handlePublishPressed = () => {
const { notify, publish, updatePublishForm } = this.props; const { balance, notify, publish, updatePublishForm } = this.props;
const { const {
editMode, editMode,
bid, bid,
@ -340,6 +341,16 @@ class PublishPage extends React.PureComponent {
uri, uri,
} = this.state; } = this.state;
if (balance < Constants.MINIMUM_TRANSACTION_BALANCE) {
notify({
message: 'Publishing content requires credits. Press the blue bar to get some for free.',
});
if (this.scrollView) {
this.scrollView.scrollTo({ x: 0, y: 0, animated: true });
}
return;
}
if (!title || title.trim().length === 0) { if (!title || title.trim().length === 0) {
notify({ message: 'Please provide a title' }); notify({ message: 'Please provide a title' });
return; return;
@ -961,7 +972,7 @@ class PublishPage extends React.PureComponent {
this.updateThumbnailUriForMedia(currentMedia); this.updateThumbnailUriForMedia(currentMedia);
} }
content = ( content = (
<ScrollView style={publishStyle.publishDetails}> <ScrollView ref={ref => (this.scrollView = ref)} style={publishStyle.publishDetails}>
<TouchableOpacity style={publishStyle.mainThumbnailContainer} onPress={this.handleThumbnailPressed}> <TouchableOpacity style={publishStyle.mainThumbnailContainer} onPress={this.handleThumbnailPressed}>
<FastImage <FastImage
style={publishStyle.mainThumbnail} style={publishStyle.mainThumbnail}
@ -980,7 +991,7 @@ class PublishPage extends React.PureComponent {
</View> </View>
)} )}
</TouchableOpacity> </TouchableOpacity>
{!this.state.canPublish && <PublishRewardsDriver navigation={navigation} />} {balance < Constants.MINIMUM_TRANSACTION_BALANCE && <PublishRewardsDriver navigation={navigation} />}
<View style={publishStyle.card}> <View style={publishStyle.card}>
<View style={publishStyle.textInputLayout}> <View style={publishStyle.textInputLayout}>
@ -1190,7 +1201,7 @@ class PublishPage extends React.PureComponent {
<View style={publishStyle.rightActionButtons}> <View style={publishStyle.rightActionButtons}>
<Button <Button
style={publishStyle.publishButton} style={publishStyle.publishButton}
disabled={!this.state.canPublish || this.state.uploadThumbnailStarted} disabled={this.state.uploadThumbnailStarted}
text={this.state.editMode ? 'Save changes' : 'Publish'} text={this.state.editMode ? 'Save changes' : 'Publish'}
onPress={this.handlePublishPressed} onPress={this.handlePublishPressed}
/> />

View file

@ -19,6 +19,7 @@ const Colors = {
VeryLightGrey: '#f1f1f1', VeryLightGrey: '#f1f1f1',
White: '#ffffff', White: '#ffffff',
UriDescBlue: '#3971db', UriDescBlue: '#3971db',
RewardDriverBlue: '#2196f3',
StatsAudio: '#f6a637', StatsAudio: '#f6a637',
StatsImage: '#ff4a7d', StatsImage: '#ff4a7d',

View file

@ -348,13 +348,17 @@ const filePageStyle = StyleSheet.create({
}, },
rewardDriverCard: { rewardDriverCard: {
alignItems: 'center', alignItems: 'center',
backgroundColor: Colors.BrighterLbryGreen, backgroundColor: Colors.RewardDriverBlue,
flexDirection: 'row', flexDirection: 'row',
paddingLeft: 16, paddingLeft: 16,
paddingRight: 16, paddingRight: 16,
paddingTop: 12, paddingTop: 12,
paddingBottom: 12, paddingBottom: 12,
}, },
rewardDriverIcon: {
color: Colors.White,
marginRight: 8,
},
rewardDriverText: { rewardDriverText: {
fontFamily: 'Inter-UI-Regular', fontFamily: 'Inter-UI-Regular',
color: Colors.White, color: Colors.White,

View file

@ -297,7 +297,7 @@ const publishStyle = StyleSheet.create({
}, },
rewardDriverCard: { rewardDriverCard: {
alignItems: 'center', alignItems: 'center',
backgroundColor: Colors.BrighterLbryGreen, backgroundColor: Colors.RewardDriverBlue,
flexDirection: 'row', flexDirection: 'row',
paddingLeft: 16, paddingLeft: 16,
paddingRight: 16, paddingRight: 16,

View file

@ -198,7 +198,7 @@ const walletStyle = StyleSheet.create({
}, },
rewardDriverCard: { rewardDriverCard: {
alignItems: 'center', alignItems: 'center',
backgroundColor: Colors.BrighterLbryGreen, backgroundColor: Colors.RewardDriverBlue,
flexDirection: 'row', flexDirection: 'row',
padding: 16, padding: 16,
marginLeft: 16, marginLeft: 16,