fix publishing bugs

This commit is contained in:
Akinwale Ariwodola 2019-08-11 00:06:10 +01:00
parent ffccc124d0
commit fc412e4282
11 changed files with 148 additions and 55 deletions

View file

@ -12,7 +12,7 @@
"base-64": "^0.1.0",
"@expo/vector-icons": "^8.1.0",
"gfycat-style-urls": "^1.0.3",
"lbry-redux": "lbryio/lbry-redux#4e5e51b99b730cc834747edb9fd7d87d47a7d4f9",
"lbry-redux": "lbryio/lbry-redux#1a8ce5ee1397e101f2a015f1c3a9050c15ca6157",
"lbryinc": "lbryio/lbryinc#430c280789a5031c2e49ca5bf8a7d90ccccc4cdb",
"lodash": ">=4.17.11",
"merge": ">=1.2.1",
@ -20,7 +20,7 @@
"react": "16.8.6",
"react-native": "0.59.10",
"@react-native-community/async-storage": "^1.5.1",
"react-native-camera": "^2.11.0",
"react-native-camera": "^2.11.1",
"react-native-country-picker-modal": "^0.6.2",
"react-native-document-picker": "^2.3.0",
"react-native-exception-handler": "2.9.0",
@ -31,7 +31,7 @@
"react-native-password-strength-meter": "^0.0.2",
"react-native-phone-input": "lbryio/react-native-phone-input",
"react-native-super-grid": "^3.0.4",
"react-native-vector-icons": "^6.4.2",
"react-native-vector-icons": "^6.6.0",
"react-native-video": "lbryio/react-native-video#exoplayer-lbry-android",
"react-navigation": "^3.11.0",
"react-navigation-redux-helpers": "^3.0.2",

View file

@ -41,7 +41,9 @@ export default class ChannelSelector extends React.PureComponent {
this.setState({ showCreateChannel: true });
} else {
this.handleCreateCancel();
this.handleChannelChange(Constants.ITEM_ANONYMOUS === itemValue ? CLAIM_VALUES.CHANNEL_ANONYMOUS : itemValue);
this.handleChannelChange(
Constants.ITEM_ANONYMOUS === itemValue.name ? { name: CLAIM_VALUES.CHANNEL_ANONYMOUS } : itemValue
);
}
this.setState({ currentSelectedValue: itemValue });
};
@ -49,18 +51,18 @@ export default class ChannelSelector extends React.PureComponent {
handleChannelChange = value => {
const { onChannelChange } = this.props;
const { newChannelBid } = this.state;
const channel = value;
const channel = value.name;
if (channel === CLAIM_VALUES.CHANNEL_NEW) {
this.setState({ addingChannel: true });
if (onChannelChange) {
onChannelChange(channel);
onChannelChange(value);
}
this.handleNewChannelBidChange(newChannelBid);
} else {
this.setState({ addingChannel: false });
if (onChannelChange) {
onChannelChange(channel);
onChannelChange(value);
}
}
};
@ -68,14 +70,22 @@ export default class ChannelSelector extends React.PureComponent {
handleNewChannelNameChange = value => {
const { notify } = this.props;
let newChannelName = value;
let newChannelName = value,
newChannelNameError = '';
if (newChannelName.startsWith('@')) {
newChannelName = newChannelName.slice(1);
}
if (newChannelName.trim().length > 0 && !isURIValid(newChannelName)) {
newChannelNameError = 'Your channel name contains invalid characters.';
} else if (this.channelExists(newChannelName)) {
newChannelNameError = 'You have already created a channel with the same name.';
}
this.setState({
newChannelName,
newChannelNameError,
});
};
@ -167,6 +177,7 @@ export default class ChannelSelector extends React.PureComponent {
const pickerItems = [{ name: Constants.ITEM_ANONYMOUS }, { name: Constants.ITEM_CREATE_A_CHANNEL }].concat(
channels
);
const {
newChannelName,
newChannelNameError,
@ -175,6 +186,7 @@ export default class ChannelSelector extends React.PureComponent {
creatingChannel,
createChannelError,
addingChannel,
showCreateChannel,
} = this.state;
return (
@ -186,11 +198,11 @@ export default class ChannelSelector extends React.PureComponent {
onValueChange={this.handlePickerValueChange}
>
{pickerItems.map(item => (
<Picker.Item label={item.name} value={item.name} key={item.name} />
<Picker.Item label={item.name} value={item} key={item.name} />
))}
</Picker>
{this.state.showCreateChannel && (
{showCreateChannel && (
<View style={channelSelectorStyle.createChannelContainer}>
<View style={channelSelectorStyle.channelInputContainer}>
<Text style={channelSelectorStyle.channelAt}>@</Text>
@ -203,11 +215,14 @@ export default class ChannelSelector extends React.PureComponent {
underlineColorAndroid={Colors.NextLbryGreen}
/>
</View>
{newChannelNameError.length > 0 && (
<Text style={channelSelectorStyle.inlineError}>{newChannelNameError}</Text>
)}
<View style={channelSelectorStyle.bidRow}>
<Text style={channelSelectorStyle.label}>Deposit</Text>
<TextInput
style={channelSelectorStyle.bidAmountInput}
value={String(this.state.newChannelBid)}
value={String(newChannelBid)}
onChangeText={this.handleNewChannelBidChange}
placeholder={'0.00'}
keyboardType={'number-pad'}
@ -226,7 +241,7 @@ export default class ChannelSelector extends React.PureComponent {
<Link style={channelSelectorStyle.cancelLink} text="Cancel" onPress={this.handleCreateCancel} />
<Button
style={channelSelectorStyle.createButton}
disabled={!(this.state.newChannelName.trim().length > 0 && this.state.newChannelBid > 0)}
disabled={!(newChannelName.trim().length > 0 && newChannelBid > 0)}
text="Create"
onPress={this.handleCreateChannelClick}
/>

View file

@ -251,22 +251,29 @@ class DiscoverPage extends React.PureComponent {
</View>
);
sectionListFooter = () => (
<View style={discoverStyle.footer}>
<Text style={discoverStyle.footerTitle}>More tags you follow</Text>
<View style={discoverStyle.footerTags}>
{this.state.remainingTags.map(tag => (
<Text
key={tag}
style={[discoverStyle.categoryName, discoverStyle.footerTag]}
onPress={() => this.handleTagPress(tag)}
>
{formatTagTitle(tag)}
</Text>
))}
sectionListFooter = () => {
const { remainingTags } = this.state;
if (remainingTags.length === 0) {
return null;
}
return (
<View style={discoverStyle.footer}>
<Text style={discoverStyle.footerTitle}>More tags you follow</Text>
<View style={discoverStyle.footerTags}>
{remainingTags.map(tag => (
<Text
key={tag}
style={[discoverStyle.categoryName, discoverStyle.footerTag]}
onPress={() => this.handleTagPress(tag)}
>
{formatTagTitle(tag)}
</Text>
))}
</View>
</View>
</View>
);
);
};
renderSectionListItem = ({ item, index, section }) => (
<ClaimList

View file

@ -1,23 +1,28 @@
import { connect } from 'react-redux';
import {
doFileList,
doFetchClaimListMine,
selectFileInfosDownloaded,
selectDownloadedUris,
selectMyClaimsWithoutChannels,
selectIsFetchingClaimListMine,
selectIsFetchingFileList,
} from 'lbry-redux';
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
import { selectCurrentRoute } from 'redux/selectors/drawer';
import Constants from 'constants';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import DownloadsPage from './view';
const select = state => ({
claims: selectMyClaimsWithoutChannels(state),
currentRoute: selectCurrentRoute(state),
fileInfos: selectFileInfosDownloaded(state),
fetching: selectIsFetchingFileList(state),
downloadedUris: selectDownloadedUris(state),
fetching: selectIsFetchingFileList(state) || selectIsFetchingClaimListMine(state),
});
const perform = dispatch => ({
fetchMyClaims: () => dispatch(doFetchClaimListMine()),
fileList: () => dispatch(doFileList()),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_MY_LBRY)),
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),

View file

@ -1,5 +1,5 @@
import React from 'react';
import { Lbry, buildURI } from 'lbry-redux';
import { Lbry, buildURI, normalizeURI } from 'lbry-redux';
import { ActivityIndicator, Button, FlatList, Text, TextInput, View, ScrollView } from 'react-native';
import { navigateToUri, uriFromFileInfo } from 'utils/helper';
import Colors from 'styles/colors';
@ -31,9 +31,10 @@ class DownloadsPage extends React.PureComponent {
}
onComponentFocused = () => {
const { fileList, pushDrawerStack, setPlayerVisible } = this.props;
const { fetchMyClaims, fileList, pushDrawerStack, setPlayerVisible } = this.props;
pushDrawerStack();
setPlayerVisible();
fetchMyClaims();
fileList();
};
@ -49,9 +50,16 @@ class DownloadsPage extends React.PureComponent {
}
}
getFilteredUris = () => {
const { claims, downloadedUris } = this.props;
const claimUris = claims.map(claim => normalizeURI(`${claim.name}#${claim.claim_id}`));
return downloadedUris.filter(uri => !claimUris.includes(uri));
};
render() {
const { fetching, fileInfos, navigation } = this.props;
const hasDownloads = fileInfos && Object.values(fileInfos).length > 0;
const { fetching, claims, downloadedUris, fileInfos, navigation } = this.props;
const filteredUris = this.getFilteredUris();
const hasDownloads = filteredUris && filteredUris.length > 0;
return (
<View style={downloadsStyle.container}>
@ -63,12 +71,12 @@ class DownloadsPage extends React.PureComponent {
</Text>
</View>
)}
{fetching && !hasDownloads && (
{fetching && (
<View style={downloadsStyle.busyContainer}>
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={downloadsStyle.loading} />
</View>
)}
{hasDownloads && (
{!fetching && hasDownloads && (
<View style={downloadsStyle.subContainer}>
<StorageStatsCard fileInfos={fileInfos} />
<FlatList
@ -77,13 +85,13 @@ class DownloadsPage extends React.PureComponent {
renderItem={({ item }) => (
<FileListItem
style={fileListStyle.item}
uri={uriFromFileInfo(item)}
uri={item}
navigation={navigation}
onPress={() => navigateToUri(navigation, uriFromFileInfo(item), { autoplay: true })}
onPress={() => navigateToUri(navigation, item, { autoplay: true })}
/>
)}
data={fileInfos}
keyExtractor={(item, index) => item.outpoint}
data={downloadedUris}
keyExtractor={(item, index) => item}
/>
</View>
)}

View file

@ -114,6 +114,7 @@ class PublishPage extends React.PureComponent {
price: 0,
uri: null,
tags: [],
selectedChannel: null,
uploadedThumbnailUri: null,
// other
@ -210,16 +211,13 @@ class PublishPage extends React.PureComponent {
return;
}
const publishTags = tags.slice();
const publishParams = {
filePath: currentMedia.filePath,
bid: bid || 0.1,
tags: publishTags,
title: title || '',
thumbnail: thumbnail,
thumbnail,
description: description || '',
language,
nsfw: publishTags.some(tag => MATURE_TAGS.includes(tag)),
license,
licenseUrl: '',
otherLicenseDescription: '',
@ -227,9 +225,13 @@ class PublishPage extends React.PureComponent {
contentIsFree: !priceSet,
fee: { currency: 'LBC', price },
uri: uri || undefined,
channel_name: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? undefined : channelName,
channel: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? null : channelName,
isStillEditing: false,
claim: null,
claim: {
value: {
tags,
},
},
};
this.setState({ publishStarted: true }, () => publish(publishParams));
@ -241,7 +243,7 @@ class PublishPage extends React.PureComponent {
componentWillReceiveProps(nextProps) {
const { currentRoute, publishFormValues } = nextProps;
const { currentRoute: prevRoute } = this.props;
const { currentRoute: prevRoute, notify } = this.props;
if (Constants.DRAWER_ROUTE_PUBLISH === currentRoute && currentRoute !== prevRoute) {
this.onComponentFocused();
@ -257,6 +259,7 @@ class PublishPage extends React.PureComponent {
this.setState({ publishStarted: false, currentPhase: Constants.PHASE_PUBLISH });
} else if (publishFormValues.publishError) {
// TODO: Display error if any
notify({ message: 'Your content could not be published at this time. Please try again.' });
}
if (!publishFormValues.publishing && this.state.publishStarted) {
@ -279,7 +282,7 @@ class PublishPage extends React.PureComponent {
}
formatNameForTitle = title => {
return title.replace(regexInvalidURI, '-').toLowerCase();
return title.replace(new RegExp(regexInvalidURI.source, regexInvalidURI.flags + 'g'), '-').toLowerCase();
};
showSelector() {
@ -311,6 +314,7 @@ class PublishPage extends React.PureComponent {
price: 0,
uri: null,
tags: [],
selectedChannel: null,
uploadedThumbnailUri: null,
},
() => {
@ -442,10 +446,10 @@ class PublishPage extends React.PureComponent {
this.setState({ uri });
};
handleChannelChanged = channel => {
this.setState({ channelName: channel });
const uri = this.getNewUri(name, this.state.channelName);
this.setState({ uri });
handleChannelChange = channel => {
const { name } = this.state;
const uri = this.getNewUri(name, channel.name);
this.setState({ uri, channelName: channel.name, selectedChannel: channel });
};
handleAddTag = tag => {
@ -787,6 +791,13 @@ class PublishPage extends React.PureComponent {
/>
</View>
<View style={publishStyle.warning}>
<Text style={publishStyle.warningText}>
Please ensure that you have filled everything correctly as you cannot edit published content in this
release. This feature will be available in a future release.
</Text>
</View>
<View style={publishStyle.actionButtons}>
{(this.state.publishStarted || publishFormValues.publishing) && (
<View style={publishStyle.progress}>
@ -850,6 +861,7 @@ class PublishPage extends React.PureComponent {
{this.state.canUseCamera && this.state.showCameraOverlay && (
<View style={publishStyle.cameraOverlay}>
<RNCamera
captureAudio={this.state.videoRecordingMode}
style={publishStyle.fullCamera}
ref={ref => {
this.camera = ref;
@ -868,6 +880,11 @@ class PublishPage extends React.PureComponent {
buttonPositive: 'OK',
buttonNegative: 'Cancel',
}}
notAuthorizedView={
<View style={publishStyle.fullCentered}>
<Text style={publishStyle.cameraInfo}>Camera not authorized</Text>
</View>
}
/>
<View
style={[
@ -876,7 +893,7 @@ class PublishPage extends React.PureComponent {
]}
>
<View style={publishStyle.controlsRow}>
<TouchableOpacity onPress={this.handleCloseCameraPressed}>
<TouchableOpacity onPress={this.handleCloseCameraPressed} style={publishStyle.backButtonControl}>
<Icon name="arrow-left" size={28} color={Colors.White} />
</TouchableOpacity>

View file

@ -1,5 +1,10 @@
import { connect } from 'react-redux';
import { doCheckPendingPublishes, selectMyClaimUrisWithoutChannels, selectIsFetchingClaimListMine } from 'lbry-redux';
import {
doCheckPendingPublishes,
doFetchClaimListMine,
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';
@ -10,6 +15,7 @@ const select = state => ({
});
const perform = dispatch => ({
fetchMyClaims: () => dispatch(doFetchClaimListMine()),
checkPendingPublishes: () => dispatch(doCheckPendingPublishes()),
pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISHES)),
setPlayerVisible: () => dispatch(doSetPlayerVisible(false)),

View file

@ -28,10 +28,11 @@ class PublishesPage extends React.PureComponent {
}
onComponentFocused = () => {
const { checkPendingPublishes, pushDrawerStack, setPlayerVisible } = this.props;
const { checkPendingPublishes, fetchMyClaims, pushDrawerStack, setPlayerVisible } = this.props;
pushDrawerStack();
setPlayerVisible();
fetchMyClaims();
checkPendingPublishes();
};

View file

@ -88,7 +88,6 @@ export const doNativeSearch = (
dispatch(batchActions(...actions));
})
.catch(e => {
console.log(e);
dispatch({
type: ACTIONS.SEARCH_FAIL,
});

View file

@ -65,6 +65,12 @@ const channelSelectorStyle = StyleSheet.create({
createButton: {
backgroundColor: Colors.NextLbryGreen,
},
inlineError: {
fontFamily: 'Inter-UI-Regular',
fontSize: 12,
color: Colors.Red,
marginTop: 2,
},
});
export default channelSelectorStyle;

View file

@ -229,6 +229,9 @@ const publishStyle = StyleSheet.create({
alignItems: 'center',
justifyContent: 'space-between',
},
backButtonControl: {
flex: 0.1,
},
mainControlsRow: {
flex: 0.8,
flexDirection: 'row',
@ -237,6 +240,7 @@ const publishStyle = StyleSheet.create({
},
switchCameraToggle: {
marginRight: 48,
color: Colors.White,
},
cameraAction: {
width: 72,
@ -267,6 +271,12 @@ const publishStyle = StyleSheet.create({
alignItems: 'center',
justifyContent: 'flex-end',
},
warning: {
marginTop: 24,
marginLeft: 16,
marginRight: 16,
alignItems: 'center',
},
rewardDriverCard: {
alignItems: 'center',
backgroundColor: Colors.BrighterLbryGreen,
@ -336,6 +346,15 @@ const publishStyle = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
},
fullCentered: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
},
noPublishes: {
position: 'absolute',
left: 0,
@ -375,6 +394,16 @@ const publishStyle = StyleSheet.create({
fontFamily: 'Inter-UI-Regular',
fontSize: 16,
},
cameraInfo: {
color: Colors.White,
fontFamily: 'Inter-UI-Regular',
fontSize: 16,
},
warningText: {
fontFamily: 'Inter-UI-Regular',
fontSize: 14,
color: Colors.DescriptionGrey,
},
});
export default publishStyle;