updates for patch release #106

Merged
akinwale merged 1 commit from patch-release into master 2020-01-03 18:53:18 +01:00
9 changed files with 130 additions and 47 deletions

View file

@ -30,7 +30,6 @@ class FileDownloadButton extends React.PureComponent {
fileInfo, fileInfo,
downloading, downloading,
uri, uri,
purchaseUri,
costInfo, costInfo,
isPlayable, isPlayable,
isViewable, isViewable,

View file

@ -36,5 +36,5 @@ const perform = dispatch => ({
export default connect( export default connect(
select, select,
perform perform,
)(FileListItem); )(FileListItem);

View file

@ -6,6 +6,7 @@ import Colors from 'styles/colors';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import DateTime from 'component/dateTime'; import DateTime from 'component/dateTime';
import FileItemMedia from 'component/fileItemMedia'; import FileItemMedia from 'component/fileItemMedia';
import FilePrice from 'component/filePrice';
import Icon from 'react-native-vector-icons/FontAwesome5'; import Icon from 'react-native-vector-icons/FontAwesome5';
import Link from 'component/link'; import Link from 'component/link';
import NsfwOverlay from 'component/nsfwOverlay'; import NsfwOverlay from 'component/nsfwOverlay';
@ -42,7 +43,6 @@ class FileListItem extends React.PureComponent {
componentDidMount() { componentDidMount() {
const { claim, resolveUri, uri, batchResolve } = this.props; const { claim, resolveUri, uri, batchResolve } = this.props;
if (!claim && !batchResolve) { if (!claim && !batchResolve) {
console.log('resolving on componentDidMount?');
resolveUri(uri); resolveUri(uri);
} }
} }
@ -50,7 +50,6 @@ class FileListItem extends React.PureComponent {
componentDidUpdate() { componentDidUpdate() {
const { claim, resolveUri, uri, batchResolve } = this.props; const { claim, resolveUri, uri, batchResolve } = this.props;
if (!claim && uri !== this.state.url && !batchResolve) { if (!claim && uri !== this.state.url && !batchResolve) {
console.log('resolving on componentDidUpdate?');
this.setState({ url: uri }, () => resolveUri(uri)); this.setState({ url: uri }, () => resolveUri(uri));
} }
} }
@ -168,6 +167,7 @@ class FileListItem extends React.PureComponent {
size={16} size={16}
/> />
)} )}
<FilePrice uri={uri} style={fileListStyle.filePriceContainer} textStyle={fileListStyle.filePriceText} />
<View style={fileListStyle.detailsContainer}> <View style={fileListStyle.detailsContainer}>
{featuredResult && ( {featuredResult && (
<Text style={fileListStyle.featuredUri} numberOfLines={1}> <Text style={fileListStyle.featuredUri} numberOfLines={1}>

View file

@ -46,7 +46,7 @@ class UriBar extends React.PureComponent {
const { currentRoute: prevRoute } = this.props; const { currentRoute: prevRoute } = this.props;
if (Constants.DRAWER_ROUTE_SEARCH === currentRoute && currentRoute !== prevRoute) { if (Constants.DRAWER_ROUTE_SEARCH === currentRoute && currentRoute !== prevRoute) {
this.setState({ currentValue: query, inputText: query }); this.setState({ currentValue: query, inputText: query }, () => this.setCaretPosition(query));
} }
} }
@ -75,7 +75,9 @@ class UriBar extends React.PureComponent {
} }
}, UriBar.INPUT_TIMEOUT); }, UriBar.INPUT_TIMEOUT);
} }
this.setState({ inputText: newValue, currentValue: newValue, changeTextTimeout: timeout }); this.setState({ inputText: newValue, currentValue: newValue, changeTextTimeout: timeout }, () =>
this.setCaretPosition(newValue),
);
}; };
handleItemPress = item => { handleItemPress = item => {
@ -85,7 +87,7 @@ class UriBar extends React.PureComponent {
Keyboard.dismiss(); Keyboard.dismiss();
if (SEARCH_TYPES.SEARCH === type) { if (SEARCH_TYPES.SEARCH === type) {
this.setState({ currentValue: value }); this.setState({ currentValue: value }, () => this.setCaretPosition(value));
updateSearchQuery(value); updateSearchQuery(value);
if (onSearchSubmitted) { if (onSearchSubmitted) {
@ -129,6 +131,12 @@ class UriBar extends React.PureComponent {
} }
} }
setCaretPosition(text) {
if (this.textInput && text && text.length > 0) {
this.textInput.setNativeProps({ selection: { start: text.length, end: text.length } });
}
}
handleSubmitEditing = () => { handleSubmitEditing = () => {
const { navigation, onSearchSubmitted, updateSearchQuery } = this.props; const { navigation, onSearchSubmitted, updateSearchQuery } = this.props;
if (this.state.inputText) { if (this.state.inputText) {
@ -179,7 +187,7 @@ class UriBar extends React.PureComponent {
value, value,
} = this.props; } = this.props;
if (this.state.currentValue === null) { if (this.state.currentValue === null) {
this.setState({ currentValue: value }); this.setState({ currentValue: value }, () => this.setCaretPosition(value));
} }
let style = [ let style = [
@ -253,7 +261,9 @@ class UriBar extends React.PureComponent {
autoCorrect={false} autoCorrect={false}
style={uriBarStyle.uriText} style={uriBarStyle.uriText}
onLayout={() => { onLayout={() => {
if (!this.state.focused) {
this.setSelection(); this.setSelection();
}
}} }}
selectTextOnFocus selectTextOnFocus
placeholder={__('Search movies, music, and more')} placeholder={__('Search movies, music, and more')}

View file

@ -38,9 +38,10 @@ class WalletSend extends React.PureComponent<Props> {
handleSend = () => { handleSend = () => {
const { balance, sendToAddress, notify } = this.props; const { balance, sendToAddress, notify } = this.props;
const { address, amount } = this.state; const { address, amount } = this.state;
if (address && !regexAddress.test(address)) { if (address && (!regexAddress.test(address) || address.substring(0, 1) === 'r')) {
notify({ notify({
message: __('The recipient address is not a valid LBRY address.'), message: __('The recipient address is not a valid LBRY address.'),
isError: true,
}); });
return; return;
} }
@ -48,6 +49,7 @@ class WalletSend extends React.PureComponent<Props> {
if (amount > balance) { if (amount > balance) {
notify({ notify({
message: __('Insufficient credits'), message: __('Insufficient credits'),
isError: true,
}); });
return; return;
} }
@ -72,6 +74,7 @@ class WalletSend extends React.PureComponent<Props> {
const { notify } = this.props; const { notify } = this.props;
notify({ notify({
message: __('The recipient address is not a valid LBRY address.'), message: __('The recipient address is not a valid LBRY address.'),
isError: true,
}); });
} }
}; };
@ -97,9 +100,10 @@ class WalletSend extends React.PureComponent<Props> {
this.setState({ this.setState({
address: value, address: value,
addressChanged: true, addressChanged: true,
addressValid: value.trim().length === 0 || regexAddress.test(value), addressValid: value.trim().length === 0 || (regexAddress.test(value) && !value.startsWith('r')),
}) })
} }
numberOfLines={1}
onBlur={this.handleAddressInputBlur} onBlur={this.handleAddressInputBlur}
onSubmitEditing={this.handleAddressInputSubmit} onSubmitEditing={this.handleAddressInputSubmit}
placeholder={'bbFxRyXXXXXXXXXXXZD8nE7XTLUxYnddTs'} placeholder={'bbFxRyXXXXXXXXXXXZD8nE7XTLUxYnddTs'}

View file

@ -113,8 +113,8 @@ class FilePage extends React.PureComponent {
if (!isResolvingUri && !claim) resolveUri(uri); if (!isResolvingUri && !claim) resolveUri(uri);
this.fetchFileInfo(this.props); this.fetchFileInfo(uri, this.props);
this.fetchCostInfo(this.props); this.fetchCostInfo(uri, this.props);
fetchMyClaims(); fetchMyClaims();
@ -259,21 +259,26 @@ class FilePage extends React.PureComponent {
// attempt to retrieve images and html/text automatically once the claim is loaded, and it's free // attempt to retrieve images and html/text automatically once the claim is loaded, and it's free
const mediaType = Lbry.getMediaType(contentType); const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
const isViewable = mediaType === 'image' || mediaType === 'text'; const isViewable = mediaType === 'image' || mediaType === 'text';
if (claim && costInfo && costInfo.cost === 0 && !this.state.autoGetAttempted && isViewable) { if (claim && costInfo && costInfo.cost === 0 && !this.state.autoGetAttempted && isViewable) {
this.setState({ autoGetAttempted: true }, () => this.checkStoragePermissionForDownload()); this.setState({ autoGetAttempted: true }, () => this.checkStoragePermissionForDownload());
} }
if (((costInfo && costInfo.cost > 0) || !isPlayable) && !this.state.showRecommended) {
this.setState({ showRecommended: true });
}
} }
fetchFileInfo(props) { fetchFileInfo(uri, props) {
if (props.fileInfo === undefined) { if (props.fileInfo === undefined) {
props.fetchFileInfo(props.navigation.state.params.uri); props.fetchFileInfo(uri);
} }
} }
fetchCostInfo(props) { fetchCostInfo(uri, props) {
if (props.costInfo === undefined) { if (props.costInfo === undefined) {
props.fetchCostInfo(props.navigation.state.params.uri); props.fetchCostInfo(uri);
} }
} }
@ -308,12 +313,12 @@ class FilePage extends React.PureComponent {
const { abandonClaim, claim, deleteFile, deletePurchasedUri, myClaimUris, fileInfo, navigation } = this.props; const { abandonClaim, claim, deleteFile, deletePurchasedUri, myClaimUris, fileInfo, navigation } = this.props;
Alert.alert( Alert.alert(
'Delete file', __('Delete file'),
'Are you sure you want to remove this file from your device?', __('Are you sure you want to remove this file from your device?'),
[ [
{ text: 'No' }, { text: __('No') },
{ {
text: 'Yes', text: __('Yes'),
onPress: () => { onPress: () => {
const { uri } = navigation.state.params; const { uri } = navigation.state.params;
@ -598,6 +603,38 @@ class FilePage extends React.PureComponent {
)); ));
}; };
confirmPurchaseUri = (uri, costInfo, download) => {
const { notify, purchaseUri, title } = this.props;
const { cost } = costInfo;
if (!costInfo) {
notify({ message: __('This content cannot be viewed at this time. Please try again in a bit.'), isError: true });
return;
}
if (costInfo.cost > 0) {
Alert.alert(
__('Confirm Purchase'),
__(
cost === 1
? 'This will purchase "%title%" for %amount% credit'
: 'This will purchase "%title%" for %amount% credits',
{ title, amount: cost },
),
[
{
text: __('OK'),
onPress: () => purchaseUri(uri, costInfo, download),
},
{ text: __('Cancel') },
],
);
} else {
// Free content. Just call purchaseUri directly.
purchaseUri(uri, costInfo, download);
}
};
onFileDownloadButtonPressed = () => { onFileDownloadButtonPressed = () => {
const { claim, costInfo, contentType, purchaseUri, setPlayerVisible } = this.props; const { claim, costInfo, contentType, purchaseUri, setPlayerVisible } = this.props;
const mediaType = Lbry.getMediaType(contentType); const mediaType = Lbry.getMediaType(contentType);
@ -610,7 +647,7 @@ class FilePage extends React.PureComponent {
if (!isPlayable) { if (!isPlayable) {
this.checkStoragePermissionForDownload(); this.checkStoragePermissionForDownload();
} else { } else {
purchaseUri(uri, costInfo, !isPlayable); this.confirmPurchaseUri(uri, costInfo, !isPlayable);
} }
if (isPlayable) { if (isPlayable) {
@ -648,7 +685,7 @@ class FilePage extends React.PureComponent {
stopDownloadConfirmed: false, stopDownloadConfirmed: false,
}, },
() => { () => {
purchaseUri(claim.permanent_url, costInfo, true); this.confirmPurchaseUri(claim.permanent_url, costInfo, true);
NativeModules.UtilityModule.checkDownloads(); NativeModules.UtilityModule.checkDownloads();
}, },
); );
@ -862,7 +899,7 @@ class FilePage extends React.PureComponent {
if (!isPlayable) { if (!isPlayable) {
this.checkStoragePermissionForDownload(); this.checkStoragePermissionForDownload();
} else { } else {
purchaseUri(claim.permanent_url, costInfo, !isPlayable); this.confirmPurchaseUri(claim.permanent_url, costInfo, !isPlayable);
} }
NativeModules.UtilityModule.checkDownloads(); NativeModules.UtilityModule.checkDownloads();
}); });
@ -950,7 +987,11 @@ class FilePage extends React.PureComponent {
/> />
)} )}
{!fileInfo && ( {!fileInfo && (
<FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} /> <FilePrice
uri={claim && claim.permanent_url ? claim.permanent_url : uri}
style={filePageStyle.filePriceContainer}
textStyle={filePageStyle.filePriceText}
/>
)} )}
<TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}> <TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}>

View file

@ -196,7 +196,7 @@ class PublishPage extends React.PureComponent {
}, },
() => { () => {
NativeModules.Gallery.getVideos().then(videos => this.setState({ videos, loadingVideos: false })); NativeModules.Gallery.getVideos().then(videos => this.setState({ videos, loadingVideos: false }));
} },
); );
// Check if this is an edit action // Check if this is an edit action
@ -288,7 +288,7 @@ class PublishPage extends React.PureComponent {
this.handleChannelChange(channelName); this.handleChannelChange(channelName);
} }
pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM); pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM);
} },
); );
}; };
@ -356,18 +356,26 @@ class PublishPage extends React.PureComponent {
} }
if (!title || title.trim().length === 0) { if (!title || title.trim().length === 0) {
notify({ message: __('Please provide a title') }); notify({ message: __('Please provide a title'), isError: true });
return; return;
} }
if (!name) { if (!name) {
notify({ message: __('Please specify an address where people can find your content.') }); notify({ message: __('Please specify an address where people can find your content.'), isError: true });
return;
}
if (!isNameValid(name, false)) {
notify({ message: __('Your content address contains invalid characters.'), isError: true });
return; return;
} }
if (!currentMedia && !editMode) { if (!currentMedia && !editMode) {
// sanity check. normally shouldn't happen // sanity check. normally shouldn't happen
notify({ message: __('No file selected. Please select a video or take a photo before publishing.') }); notify({
message: __('No file selected. Please select a video or take a photo before publishing.'),
isError: true,
});
return; return;
} }
@ -456,7 +464,7 @@ class PublishPage extends React.PureComponent {
() => { () => {
this.handleNameChange(this.state.name); this.handleNameChange(this.state.name);
pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM); pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM);
} },
); );
} }
@ -510,7 +518,7 @@ class PublishPage extends React.PureComponent {
clearPublishFormState(); clearPublishFormState();
// reset thumbnail // reset thumbnail
updatePublishForm({ thumbnail: null }); updatePublishForm({ thumbnail: null });
} },
); );
} }
@ -537,7 +545,7 @@ class PublishPage extends React.PureComponent {
}, },
() => { () => {
NativeModules.UtilityModule.openDocumentPicker('*/*'); NativeModules.UtilityModule.openDocumentPicker('*/*');
} },
); );
}; };
@ -583,7 +591,7 @@ class PublishPage extends React.PureComponent {
() => { () => {
// upload a new thumbnail // upload a new thumbnail
uploadImageAsset(fileUrl, this.handleThumbnailUploadSuccess, this.handleThumbnailUploadFailure); uploadImageAsset(fileUrl, this.handleThumbnailUploadSuccess, this.handleThumbnailUploadFailure);
} },
); );
} }
} else { } else {
@ -634,7 +642,7 @@ class PublishPage extends React.PureComponent {
videoRecordingMode: false, videoRecordingMode: false,
recordingVideo: false, recordingVideo: false,
}, },
() => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM) () => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM),
); );
}); });
} }
@ -658,7 +666,7 @@ class PublishPage extends React.PureComponent {
showCameraOverlay: false, showCameraOverlay: false,
videoRecordingMode: false, videoRecordingMode: false,
}, },
() => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH) () => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH),
); );
}); });
} }
@ -777,8 +785,8 @@ class PublishPage extends React.PureComponent {
uploadImageAsset( uploadImageAsset(
this.getFilePathFromUri(uri), this.getFilePathFromUri(uri),
this.handleThumbnailUploadSuccess, this.handleThumbnailUploadSuccess,
this.handleThumbnailUploadFailure this.handleThumbnailUploadFailure,
) ),
); );
} }
} else if (mediaType === 'image' || mediaType === 'video') { } else if (mediaType === 'image' || mediaType === 'video') {
@ -791,7 +799,7 @@ class PublishPage extends React.PureComponent {
this.setState({ currentThumbnailUri: `file://${path}`, updatingThumbnailUri: false }); this.setState({ currentThumbnailUri: `file://${path}`, updatingThumbnailUri: false });
if (!this.state.uploadedThumbnailUri) { if (!this.state.uploadedThumbnailUri) {
this.setState({ uploadThumbnailStarted: true }, () => this.setState({ uploadThumbnailStarted: true }, () =>
uploadImageAsset(path, this.handleThumbnailUploadSuccess, this.handleThumbnailUploadFailure) uploadImageAsset(path, this.handleThumbnailUploadSuccess, this.handleThumbnailUploadFailure),
); );
} }
}) })
@ -817,7 +825,7 @@ class PublishPage extends React.PureComponent {
}, },
() => { () => {
this.handleNameChange(this.state.name); this.handleNameChange(this.state.name);
} },
); );
} }
}; };
@ -881,7 +889,7 @@ class PublishPage extends React.PureComponent {
}, },
() => { () => {
NativeModules.UtilityModule.openDocumentPicker('image/*'); NativeModules.UtilityModule.openDocumentPicker('image/*');
} },
); );
}; };
@ -1112,7 +1120,7 @@ class PublishPage extends React.PureComponent {
{__('The address where people can find your content (ex. lbry://myvideo). ')} {__('The address where people can find your content (ex. lbry://myvideo). ')}
{this.state.editMode && {this.state.editMode &&
__( __(
'You cannot change this address while editing your content. If you wish to use a new address, please republish the content.' 'You cannot change this address while editing your content. If you wish to use a new address, please republish the content.',
)} )}
</Text> </Text>
@ -1262,7 +1270,7 @@ class PublishPage extends React.PureComponent {
</View> </View>
<Text style={publishStyle.successText}> <Text style={publishStyle.successText}>
{__( {__(
'Your content will be live in a few minutes. In the mean time, feel free to publish more content or explore the app.' 'Your content will be live in a few minutes. In the mean time, feel free to publish more content or explore the app.',
)} )}
</Text> </Text>
</View> </View>

View file

@ -120,6 +120,22 @@ const fileListStyle = StyleSheet.create({
marginLeft: 4, marginLeft: 4,
marginTop: 4, marginTop: 4,
}, },
filePriceContainer: {
backgroundColor: Colors.NextLbryGreen,
justifyContent: 'center',
position: 'absolute',
left: thumbnailWidth - 64,
top: 8,
width: 56,
height: 24,
borderRadius: 4,
},
filePriceText: {
fontFamily: 'Inter-UI-Bold',
fontSize: 12,
textAlign: 'center',
color: '#0c604b',
},
}); });
export default fileListStyle; export default fileListStyle;

View file

@ -27,11 +27,16 @@ const walletStyle = StyleSheet.create({
}, },
address: { address: {
fontFamily: 'Inter-UI-Regular', fontFamily: 'Inter-UI-Regular',
letterSpacing: 0.8,
borderWidth: 1, borderWidth: 1,
borderRadius: 16,
borderStyle: 'dashed', borderStyle: 'dashed',
borderColor: '#cccccc', borderColor: '#e1e1e1',
backgroundColor: '#f9f9f9', backgroundColor: '#f9f9f9',
padding: 8, paddingTop: 8,
paddingLeft: 8,
paddingRight: 8,
paddingBottom: 6,
width: '85%', width: '85%',
}, },
button: { button: {