update to sdk 0.38.0. add tags / tag selection to publish.
This commit is contained in:
parent
44c58eb8c7
commit
2beb83d076
28 changed files with 546 additions and 113 deletions
|
@ -25,7 +25,7 @@ build apk:
|
||||||
- cp -f $CI_PROJECT_DIR/scripts/mangled-glibc-syscalls.h ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21/arch-arm/usr/include/crystax/bionic/libc/include/sys/mangled-glibc-syscalls.h
|
- cp -f $CI_PROJECT_DIR/scripts/mangled-glibc-syscalls.h ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21/arch-arm/usr/include/crystax/bionic/libc/include/sys/mangled-glibc-syscalls.h
|
||||||
- rm ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz
|
- rm ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz
|
||||||
- git secret reveal
|
- git secret reveal
|
||||||
- mv buildozer.spec.travis buildozer.spec
|
- mv buildozer.spec.ci buildozer.spec
|
||||||
- "./release.sh | grep -Fv -e 'working:' -e 'copy' -e 'Compiling' --line-buffered"
|
- "./release.sh | grep -Fv -e 'working:' -e 'copy' -e 'Compiling' --line-buffered"
|
||||||
- cp $CI_PROJECT_DIR/bin/browser-$BUILD_VERSION-release.apk /dev/null
|
- cp $CI_PROJECT_DIR/bin/browser-$BUILD_VERSION-release.apk /dev/null
|
||||||
|
|
||||||
|
|
4
app/package-lock.json
generated
4
app/package-lock.json
generated
|
@ -5558,8 +5558,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lbry-redux": {
|
"lbry-redux": {
|
||||||
"version": "github:lbryio/lbry-redux#b998577698d703714b0aa0c0e80c991902725a5c",
|
"version": "github:lbryio/lbry-redux#9a676ee311d573b84d11f402d918aeee77be76e1",
|
||||||
"from": "github:lbryio/lbry-redux#publishing",
|
"from": "github:lbryio/lbry-redux",
|
||||||
"requires": {
|
"requires": {
|
||||||
"proxy-polyfill": "0.1.6",
|
"proxy-polyfill": "0.1.6",
|
||||||
"reselect": "^3.0.0",
|
"reselect": "^3.0.0",
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"base-64": "^0.1.0",
|
"base-64": "^0.1.0",
|
||||||
"@expo/vector-icons": "^8.1.0",
|
"@expo/vector-icons": "^8.1.0",
|
||||||
"gfycat-style-urls": "^1.0.3",
|
"gfycat-style-urls": "^1.0.3",
|
||||||
"lbry-redux": "lbryio/lbry-redux#publishing",
|
"lbry-redux": "lbryio/lbry-redux",
|
||||||
"lbryinc": "lbryio/lbryinc",
|
"lbryinc": "lbryio/lbryinc",
|
||||||
"lodash": ">=4.17.11",
|
"lodash": ">=4.17.11",
|
||||||
"merge": ">=1.2.1",
|
"merge": ">=1.2.1",
|
||||||
|
|
|
@ -74,13 +74,7 @@ export default class ChannelSelector extends React.PureComponent {
|
||||||
newChannelName = newChannelName.slice(1);
|
newChannelName = newChannelName.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let newChannelNameError;
|
|
||||||
if (newChannelName.length > 1 && !isNameValid(newChannelName.substr(1), false)) {
|
|
||||||
notify({ message: 'LBRY channel names must contain only letters, numbers and dashes.' });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
newChannelNameError,
|
|
||||||
newChannelName,
|
newChannelName,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -88,8 +82,8 @@ export default class ChannelSelector extends React.PureComponent {
|
||||||
handleNewChannelBidChange = newChannelBid => {
|
handleNewChannelBidChange = newChannelBid => {
|
||||||
const { balance, notify } = this.props;
|
const { balance, notify } = this.props;
|
||||||
let newChannelBidError;
|
let newChannelBidError;
|
||||||
if (newChannelBid === 0) {
|
if (newChannelBid <= 0) {
|
||||||
newChannelBidError = __('Your deposit cannot be 0');
|
newChannelBidError = __('Please enter a deposit above 0');
|
||||||
} else if (newChannelBid === balance) {
|
} else if (newChannelBid === balance) {
|
||||||
newChannelBidError = __('Please decrease your deposit to account for transaction fees');
|
newChannelBidError = __('Please decrease your deposit to account for transaction fees');
|
||||||
} else if (newChannelBid > balance) {
|
} else if (newChannelBid > balance) {
|
||||||
|
@ -109,7 +103,7 @@ export default class ChannelSelector extends React.PureComponent {
|
||||||
const { newChannelBid, newChannelName } = this.state;
|
const { newChannelBid, newChannelName } = this.state;
|
||||||
|
|
||||||
if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) {
|
if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) {
|
||||||
notify({ message: 'LBRY channel names must contain only letters, numbers and dashes.' });
|
notify({ message: 'Your channel name contains invalid characters.' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +192,9 @@ export default class ChannelSelector extends React.PureComponent {
|
||||||
|
|
||||||
{this.state.showCreateChannel && (
|
{this.state.showCreateChannel && (
|
||||||
<View style={channelSelectorStyle.createChannelContainer}>
|
<View style={channelSelectorStyle.createChannelContainer}>
|
||||||
|
<View style={channelSelectorStyle.channelInputContainer}>
|
||||||
|
<Text style={channelSelectorStyle.channelAt}>@</Text>
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
style={channelSelectorStyle.channelNameInput}
|
style={channelSelectorStyle.channelNameInput}
|
||||||
value={this.state.newChannelName}
|
value={this.state.newChannelName}
|
||||||
|
@ -205,6 +202,7 @@ export default class ChannelSelector extends React.PureComponent {
|
||||||
placeholder={'Channel name'}
|
placeholder={'Channel name'}
|
||||||
underlineColorAndroid={Colors.NextLbryGreen}
|
underlineColorAndroid={Colors.NextLbryGreen}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
<View style={channelSelectorStyle.bidRow}>
|
<View style={channelSelectorStyle.bidRow}>
|
||||||
<Text style={channelSelectorStyle.label}>Deposit</Text>
|
<Text style={channelSelectorStyle.label}>Deposit</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
|
@ -62,7 +62,8 @@ class FileItem extends React.PureComponent {
|
||||||
const uri = normalizeURI(this.props.uri);
|
const uri = normalizeURI(this.props.uri);
|
||||||
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
||||||
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
|
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
|
||||||
const channelName = claim ? claim.channel_name : null;
|
const signingChannel = claim ? claim.signing_channel : null;
|
||||||
|
const channelName = signingChannel ? signingChannel.name : null;
|
||||||
const channelClaimId =
|
const channelClaimId =
|
||||||
claim && claim.value && claim.value.publisherSignature && claim.value.publisherSignature.certificateId;
|
claim && claim.value && claim.value.publisherSignature && claim.value.publisherSignature.certificateId;
|
||||||
const fullChannelUri = channelClaimId ? `${channelName}#${channelClaimId}` : channelName;
|
const fullChannelUri = channelClaimId ? `${channelName}#${channelClaimId}` : channelName;
|
||||||
|
|
|
@ -63,7 +63,8 @@ class FileListItem extends React.PureComponent {
|
||||||
let name, channel, height, channelClaimId, fullChannelUri;
|
let name, channel, height, channelClaimId, fullChannelUri;
|
||||||
if (claim) {
|
if (claim) {
|
||||||
name = claim.name;
|
name = claim.name;
|
||||||
channel = claim.channel_name;
|
signingChannel = claim.signing_channel;
|
||||||
|
channel = signingChannel ? signingChannel.name : null;
|
||||||
height = claim.height;
|
height = claim.height;
|
||||||
channelClaimId = claim.value && claim.value.publisherSignature && claim.value.publisherSignature.certificateId;
|
channelClaimId = claim.value && claim.value.publisherSignature && claim.value.publisherSignature.certificateId;
|
||||||
fullChannelUri = channelClaimId ? `${channel}#${channelClaimId}` : channel;
|
fullChannelUri = channelClaimId ? `${channel}#${channelClaimId}` : channel;
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import Gallery from './view';
|
|
||||||
|
|
||||||
export default connect()(Gallery);
|
|
|
@ -1,7 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
class Gallery extends React.PureComponent {
|
|
||||||
render() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Gallery;
|
|
4
app/src/component/publishRewardsDriver/index.js
Normal file
4
app/src/component/publishRewardsDriver/index.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import PublishRewardsDriver from './view';
|
||||||
|
|
||||||
|
export default connect()(PublishRewardsDriver);
|
20
app/src/component/publishRewardsDriver/view.js
Normal file
20
app/src/component/publishRewardsDriver/view.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, TouchableOpacity } from 'react-native';
|
||||||
|
import Colors from 'styles/colors';
|
||||||
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
import publishStyle from 'styles/publish';
|
||||||
|
|
||||||
|
class PublishRewadsDriver extends React.PureComponent<Props> {
|
||||||
|
render() {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity style={publishStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}>
|
||||||
|
<Icon name="award" size={16} style={publishStyle.rewardIcon} />
|
||||||
|
<Text style={publishStyle.rewardDriverText}>Earn some credits to be able to publish your content.</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PublishRewadsDriver;
|
4
app/src/component/tag/index.js
Normal file
4
app/src/component/tag/index.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import Tag from './view';
|
||||||
|
|
||||||
|
export default connect()(Tag);
|
55
app/src/component/tag/view.js
Normal file
55
app/src/component/tag/view.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, TouchableOpacity, View } from 'react-native';
|
||||||
|
import tagStyle from 'styles/tag';
|
||||||
|
import Colors from 'styles/colors';
|
||||||
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
|
||||||
|
export default class Tag extends React.PureComponent {
|
||||||
|
onPressDefault = () => {
|
||||||
|
const { name, navigation, type, onAddPress, onRemovePress } = this.props;
|
||||||
|
if ('add' === type) {
|
||||||
|
if (onAddPress) {
|
||||||
|
onAddPress(name);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('remove' === type) {
|
||||||
|
if (onRemovePress) {
|
||||||
|
onRemovePress(name);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigation) {
|
||||||
|
// navigate to tag page
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { name, onPress, style, type } = this.props;
|
||||||
|
|
||||||
|
let styles = [];
|
||||||
|
if (style) {
|
||||||
|
if (style.length) {
|
||||||
|
styles = styles.concat(style);
|
||||||
|
} else {
|
||||||
|
styles.push(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
styles.push({
|
||||||
|
backgroundColor: Colors.TagGreen,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 4,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity style={styles} onPress={onPress || this.onPressDefault}>
|
||||||
|
<View style={tagStyle.content}>
|
||||||
|
<Text style={tagStyle.text}>{name}</Text>
|
||||||
|
{type && <Icon style={tagStyle.icon} name={type === 'add' ? 'plus' : 'times'} size={8} />}
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
12
app/src/component/tagSearch/index.js
Normal file
12
app/src/component/tagSearch/index.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { selectUnfollowedTags } from 'lbry-redux';
|
||||||
|
import TagSearch from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
unfollowedTags: selectUnfollowedTags(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
null
|
||||||
|
)(TagSearch);
|
81
app/src/component/tagSearch/view.js
Normal file
81
app/src/component/tagSearch/view.js
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||||
|
import Tag from 'component/tag';
|
||||||
|
import tagStyle from 'styles/tag';
|
||||||
|
import Colors from 'styles/colors';
|
||||||
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
|
||||||
|
export default class TagSearch extends React.PureComponent {
|
||||||
|
state = {
|
||||||
|
tag: null,
|
||||||
|
tagResults: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { selectedTags = [] } = this.props;
|
||||||
|
this.updateTagResults(this.state.tag, selectedTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
const { selectedTags: prevSelectedTags = [] } = this.props;
|
||||||
|
const { selectedTags = [] } = nextProps;
|
||||||
|
|
||||||
|
if (selectedTags.length !== prevSelectedTags.length) {
|
||||||
|
this.updateTagResults(this.state.tag, selectedTags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddTagPress = tag => {
|
||||||
|
const { handleAddTag } = this.props;
|
||||||
|
if (handleAddTag) {
|
||||||
|
handleAddTag(tag);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleTagChange = tag => {
|
||||||
|
const { selectedTags = [] } = this.props;
|
||||||
|
this.setState({ tag });
|
||||||
|
this.updateTagResults(tag, selectedTags);
|
||||||
|
};
|
||||||
|
|
||||||
|
updateTagResults = (tag, selectedTags = []) => {
|
||||||
|
const { unfollowedTags } = this.props;
|
||||||
|
|
||||||
|
// the search term should always be the first result
|
||||||
|
let results = [];
|
||||||
|
const tagNotSelected = name => selectedTags.indexOf(name.toLowerCase()) === -1;
|
||||||
|
const suggestedTagsSet = new Set(unfollowedTags.map(tag => tag.name));
|
||||||
|
const suggestedTags = Array.from(suggestedTagsSet).filter(tagNotSelected);
|
||||||
|
if (tag && tag.trim().length > 0) {
|
||||||
|
results.push(tag.toLowerCase());
|
||||||
|
const doesTagMatch = name => name.toLowerCase().includes(tag.toLowerCase());
|
||||||
|
results = results.concat(suggestedTags.filter(doesTagMatch).slice(0, 5));
|
||||||
|
} else {
|
||||||
|
results = results.concat(suggestedTags.slice(0, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ tagResults: results });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { name, style, type, selectedTags = [] } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<TextInput
|
||||||
|
style={tagStyle.searchInput}
|
||||||
|
placeholder={'Search for more tags'}
|
||||||
|
underlineColorAndroid={Colors.NextLbryGreen}
|
||||||
|
value={this.state.tag}
|
||||||
|
numberOfLines={1}
|
||||||
|
onChangeText={this.handleTagChange}
|
||||||
|
/>
|
||||||
|
<View style={tagStyle.tagResultsList}>
|
||||||
|
{this.state.tagResults.map(tag => (
|
||||||
|
<Tag key={tag} name={tag} style={tagStyle.tag} type="add" onAddPress={name => this.onAddTagPress(name)} />
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import {
|
||||||
notificationsReducer,
|
notificationsReducer,
|
||||||
publishReducer,
|
publishReducer,
|
||||||
searchReducer,
|
searchReducer,
|
||||||
|
tagsReducer,
|
||||||
walletReducer,
|
walletReducer,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import {
|
import {
|
||||||
|
@ -41,7 +42,6 @@ import thunk from 'redux-thunk';
|
||||||
|
|
||||||
const globalExceptionHandler = (error, isFatal) => {
|
const globalExceptionHandler = (error, isFatal) => {
|
||||||
if (error && NativeModules.Firebase) {
|
if (error && NativeModules.Firebase) {
|
||||||
console.log(error);
|
|
||||||
NativeModules.Firebase.logException(isFatal, error.message ? error.message : 'No message', JSON.stringify(error));
|
NativeModules.Firebase.logException(isFatal, error.message ? error.message : 'No message', JSON.stringify(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -97,6 +97,7 @@ const reducers = combineReducers({
|
||||||
search: searchReducer,
|
search: searchReducer,
|
||||||
subscriptions: subscriptionsReducer,
|
subscriptions: subscriptionsReducer,
|
||||||
sync: syncReducer,
|
sync: syncReducer,
|
||||||
|
tags: tagsReducer,
|
||||||
user: userReducer,
|
user: userReducer,
|
||||||
wallet: walletReducer,
|
wallet: walletReducer,
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { navigateBack, navigateToUri } from 'utils/helper';
|
||||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import Tag from 'component/tag';
|
||||||
import ChannelPage from 'page/channel';
|
import ChannelPage from 'page/channel';
|
||||||
import Colors from 'styles/colors';
|
import Colors from 'styles/colors';
|
||||||
import Constants from 'constants';
|
import Constants from 'constants';
|
||||||
|
@ -502,11 +503,7 @@ class FilePage extends React.PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
renderTags = tags => {
|
renderTags = tags => {
|
||||||
return tags.map((tag, i) => (
|
return tags.map((tag, i) => <Tag style={filePageStyle.tagItem} key={`${tag}-${i}`} name={tag} />);
|
||||||
<Text style={filePageStyle.tagItem} key={`${tag}-${i}`}>
|
|
||||||
{tag}
|
|
||||||
</Text>
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onFileDownloadButtonPlayed = () => {
|
onFileDownloadButtonPlayed = () => {
|
||||||
|
@ -618,7 +615,8 @@ class FilePage extends React.PureComponent {
|
||||||
const description = metadata.description ? metadata.description : null;
|
const description = metadata.description ? metadata.description : null;
|
||||||
const mediaType = Lbry.getMediaType(contentType);
|
const mediaType = Lbry.getMediaType(contentType);
|
||||||
const isPlayable = mediaType === 'video' || mediaType === 'audio';
|
const isPlayable = mediaType === 'video' || mediaType === 'audio';
|
||||||
const { height, channel_name: channelName, value } = claim;
|
const { height, signing_channel: signingChannel, value } = claim;
|
||||||
|
const channelName = signingChannel && signingChannel.name;
|
||||||
const showActions =
|
const showActions =
|
||||||
fileInfo &&
|
fileInfo &&
|
||||||
fileInfo.download_path &&
|
fileInfo.download_path &&
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doPublish, doResolveUri, doToast, doUploadThumbnail, selectPublishFormValues } from 'lbry-redux';
|
import {
|
||||||
|
doPublish,
|
||||||
|
doResolveUri,
|
||||||
|
doToast,
|
||||||
|
doUploadThumbnail,
|
||||||
|
selectBalance,
|
||||||
|
selectPublishFormValues,
|
||||||
|
} from 'lbry-redux';
|
||||||
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
|
||||||
import Constants from 'constants';
|
import Constants from 'constants';
|
||||||
import PublishPage from './view';
|
import PublishPage from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
balance: selectBalance(state),
|
||||||
publishFormValues: selectPublishFormValues(state),
|
publishFormValues: selectPublishFormValues(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,47 @@ import FloatingWalletBalance from 'component/floatingWalletBalance';
|
||||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
import Feather from 'react-native-vector-icons/Feather';
|
import Feather from 'react-native-vector-icons/Feather';
|
||||||
import Link from 'component/link';
|
import Link from 'component/link';
|
||||||
|
import PublishRewardsDriver from 'component/publishRewardsDriver';
|
||||||
|
import Tag from 'component/tag';
|
||||||
|
import TagSearch from 'component/tagSearch';
|
||||||
import UriBar from 'component/uriBar';
|
import UriBar from 'component/uriBar';
|
||||||
import publishStyle from 'styles/publish';
|
import publishStyle from 'styles/publish';
|
||||||
|
|
||||||
|
const languages = {
|
||||||
|
en: 'English',
|
||||||
|
zh: 'Chinese',
|
||||||
|
fr: 'French',
|
||||||
|
de: 'German',
|
||||||
|
jp: 'Japanese',
|
||||||
|
ru: 'Russian',
|
||||||
|
es: 'Spanish',
|
||||||
|
id: 'Indonesian',
|
||||||
|
it: 'Italian',
|
||||||
|
nl: 'Dutch',
|
||||||
|
tr: 'Turkish',
|
||||||
|
pl: 'Polish',
|
||||||
|
ms: 'Malay',
|
||||||
|
pt: 'Portuguese',
|
||||||
|
vi: 'Vietnamese',
|
||||||
|
th: 'Thai',
|
||||||
|
ar: 'Arabic',
|
||||||
|
cs: 'Czech',
|
||||||
|
hr: 'Croatian',
|
||||||
|
km: 'Cambodian',
|
||||||
|
ko: 'Korean',
|
||||||
|
no: 'Norwegian',
|
||||||
|
ro: 'Romanian',
|
||||||
|
hi: 'Hindi',
|
||||||
|
el: 'Greek',
|
||||||
|
};
|
||||||
|
|
||||||
class PublishPage extends React.PureComponent {
|
class PublishPage extends React.PureComponent {
|
||||||
camera = null;
|
camera = null;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
canUseCamera: false,
|
canUseCamera: false,
|
||||||
|
titleFocused: false,
|
||||||
|
descriptionFocused: false,
|
||||||
|
|
||||||
// gallery videos
|
// gallery videos
|
||||||
videos: null,
|
videos: null,
|
||||||
|
@ -64,9 +97,13 @@ class PublishPage extends React.PureComponent {
|
||||||
bid: 0.1,
|
bid: 0.1,
|
||||||
description: null,
|
description: null,
|
||||||
title: null,
|
title: null,
|
||||||
|
language: 'en',
|
||||||
|
license: LICENSES.NONE,
|
||||||
|
mature: false,
|
||||||
name: null,
|
name: null,
|
||||||
price: 0,
|
price: 0,
|
||||||
uri: null,
|
uri: null,
|
||||||
|
tags: [],
|
||||||
uploadedThumbnailUri: null,
|
uploadedThumbnailUri: null,
|
||||||
|
|
||||||
// other
|
// other
|
||||||
|
@ -124,9 +161,13 @@ class PublishPage extends React.PureComponent {
|
||||||
channelName,
|
channelName,
|
||||||
currentMedia,
|
currentMedia,
|
||||||
description,
|
description,
|
||||||
|
language,
|
||||||
|
license,
|
||||||
|
mature,
|
||||||
name,
|
name,
|
||||||
price,
|
price,
|
||||||
priceSet,
|
priceSet,
|
||||||
|
tags,
|
||||||
title,
|
title,
|
||||||
uploadedThumbnailUri: thumbnail,
|
uploadedThumbnailUri: thumbnail,
|
||||||
uri,
|
uri,
|
||||||
|
@ -142,22 +183,28 @@ class PublishPage extends React.PureComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publishTags = tags.slice();
|
||||||
|
if (mature) {
|
||||||
|
publishTags.push('nsfw');
|
||||||
|
}
|
||||||
|
|
||||||
const publishParams = {
|
const publishParams = {
|
||||||
filePath: currentMedia.filePath,
|
filePath: currentMedia.filePath,
|
||||||
bid: bid || 0.1,
|
bid: bid || 0.1,
|
||||||
|
tags: publishTags,
|
||||||
title: title || '',
|
title: title || '',
|
||||||
thumbnail: thumbnail,
|
thumbnail: thumbnail,
|
||||||
description: description || '',
|
description: description || '',
|
||||||
language: 'en',
|
language,
|
||||||
nsfw: false,
|
nsfw: mature,
|
||||||
license: '',
|
license,
|
||||||
licenseUrl: '',
|
licenseUrl: '',
|
||||||
otherLicenseDescription: '',
|
otherLicenseDescription: '',
|
||||||
name: name || undefined,
|
name: name || undefined,
|
||||||
contentIsFree: !priceSet,
|
contentIsFree: !priceSet,
|
||||||
fee: { currency: 'LBC', price },
|
fee: { currency: 'LBC', price },
|
||||||
uri: uri || undefined,
|
uri: uri || undefined,
|
||||||
channel: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? undefined : channelName,
|
channel_name: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? undefined : channelName,
|
||||||
isStillEditing: false,
|
isStillEditing: false,
|
||||||
claim: null,
|
claim: null,
|
||||||
};
|
};
|
||||||
|
@ -189,7 +236,6 @@ class PublishPage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (publishFormValues) {
|
if (publishFormValues) {
|
||||||
// TODO: Check thumbnail upload progress after thumbnail starts uploading
|
|
||||||
if (publishFormValues.thumbnail && !this.state.uploadedThumbnailUri) {
|
if (publishFormValues.thumbnail && !this.state.uploadedThumbnailUri) {
|
||||||
this.setState({ uploadedThumbnailUri: publishFormValues.thumbnail });
|
this.setState({ uploadedThumbnailUri: publishFormValues.thumbnail });
|
||||||
}
|
}
|
||||||
|
@ -242,9 +288,12 @@ class PublishPage extends React.PureComponent {
|
||||||
bid: 0.1,
|
bid: 0.1,
|
||||||
description: null,
|
description: null,
|
||||||
title: null,
|
title: null,
|
||||||
|
language: 'en',
|
||||||
|
license: LICENSES.NONE,
|
||||||
name: null,
|
name: null,
|
||||||
price: 0,
|
price: 0,
|
||||||
uri: null,
|
uri: null,
|
||||||
|
tags: [],
|
||||||
uploadedThumbnailUri: null,
|
uploadedThumbnailUri: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -334,11 +383,8 @@ class PublishPage extends React.PureComponent {
|
||||||
filetype: [DocumentPickerUtil.allFiles()],
|
filetype: [DocumentPickerUtil.allFiles()],
|
||||||
},
|
},
|
||||||
(error, res) => {
|
(error, res) => {
|
||||||
console.log(error);
|
|
||||||
console.log('***');
|
|
||||||
console.log(res);
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
console.log(res);
|
//console.log(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -366,7 +412,7 @@ class PublishPage extends React.PureComponent {
|
||||||
const { notify } = this.props;
|
const { notify } = this.props;
|
||||||
this.setState({ name });
|
this.setState({ name });
|
||||||
if (!isNameValid(name, false)) {
|
if (!isNameValid(name, false)) {
|
||||||
notify({ message: 'LBRY names must contain only letters, numbers and dashes.' });
|
notify({ message: 'Your content address contains invalid characters' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,6 +426,37 @@ class PublishPage extends React.PureComponent {
|
||||||
this.setState({ uri });
|
this.setState({ uri });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleAddTag = tag => {
|
||||||
|
if (!tag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { notify } = this.props;
|
||||||
|
const { tags } = this.state;
|
||||||
|
const index = tags.indexOf(tag.toLowerCase());
|
||||||
|
if (index === -1) {
|
||||||
|
const newTags = tags.slice();
|
||||||
|
newTags.push(tag);
|
||||||
|
this.setState({ tags: newTags });
|
||||||
|
} else {
|
||||||
|
notify({ message: `You already added the "${tag}" tag.` });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleRemoveTag = tag => {
|
||||||
|
if (!tag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTags = this.state.tags.slice();
|
||||||
|
const index = newTags.indexOf(tag.toLowerCase());
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
newTags.splice(index, 1);
|
||||||
|
this.setState({ tags: newTags });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
updateThumbnailUriForMedia = media => {
|
updateThumbnailUriForMedia = media => {
|
||||||
if (this.state.updatingThumbnailUri) {
|
if (this.state.updatingThumbnailUri) {
|
||||||
return;
|
return;
|
||||||
|
@ -400,7 +477,7 @@ class PublishPage extends React.PureComponent {
|
||||||
|
|
||||||
// upload the thumbnail
|
// upload the thumbnail
|
||||||
if (!this.state.uploadedThumbnailUri) {
|
if (!this.state.uploadedThumbnailUri) {
|
||||||
uploadThumbnail(this.getFilePathFromUri(uri), RNFS);
|
//this.setState({ uploadThumbnailStarted: true }, () => uploadThumbnail(this.getFilePathFromUri(uri), RNFS));
|
||||||
}
|
}
|
||||||
} else if ('image' === mediaType || 'video' === mediaType) {
|
} else if ('image' === mediaType || 'video' === mediaType) {
|
||||||
const create =
|
const create =
|
||||||
|
@ -411,7 +488,7 @@ class PublishPage extends React.PureComponent {
|
||||||
.then(path => {
|
.then(path => {
|
||||||
this.setState({ currentThumbnailUri: `file://${path}`, updatingThumbnailUri: false });
|
this.setState({ currentThumbnailUri: `file://${path}`, updatingThumbnailUri: false });
|
||||||
if (!this.state.uploadedThumbnailUri) {
|
if (!this.state.uploadedThumbnailUri) {
|
||||||
uploadThumbnail(path, RNFS);
|
//this.setState({ uploadThumbnailStarted: true }, () => uploadThumbnail(path, RNFS));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
@ -435,7 +512,7 @@ class PublishPage extends React.PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { navigation, notify, publishFormValues } = this.props;
|
const { balance, navigation, notify, publishFormValues } = this.props;
|
||||||
const { thumbnailPath } = this.state;
|
const { thumbnailPath } = this.state;
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
|
@ -443,11 +520,9 @@ class PublishPage extends React.PureComponent {
|
||||||
content = (
|
content = (
|
||||||
<View style={publishStyle.gallerySelector}>
|
<View style={publishStyle.gallerySelector}>
|
||||||
<View style={publishStyle.actionsView}>
|
<View style={publishStyle.actionsView}>
|
||||||
{this.state.canUseCamera &&
|
{this.state.canUseCamera && (
|
||||||
<RNCamera
|
<RNCamera style={publishStyle.cameraPreview} type={RNCamera.Constants.Type.back} />
|
||||||
style={publishStyle.cameraPreview}
|
)}
|
||||||
type={RNCamera.Constants.Type.back} />
|
|
||||||
}
|
|
||||||
<View style={publishStyle.actionsSubView}>
|
<View style={publishStyle.actionsSubView}>
|
||||||
<TouchableOpacity style={publishStyle.record} onPress={this.handleRecordVideoPressed}>
|
<TouchableOpacity style={publishStyle.record} onPress={this.handleRecordVideoPressed}>
|
||||||
<Icon name="video" size={48} color={Colors.White} />
|
<Icon name="video" size={48} color={Colors.White} />
|
||||||
|
@ -458,10 +533,12 @@ class PublishPage extends React.PureComponent {
|
||||||
<Icon name="camera" size={48} color={Colors.White} />
|
<Icon name="camera" size={48} color={Colors.White} />
|
||||||
<Text style={publishStyle.actionText}>Take a photo</Text>
|
<Text style={publishStyle.actionText}>Take a photo</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
{false && (
|
||||||
<TouchableOpacity style={publishStyle.upload} onPress={this.handleUploadPressed}>
|
<TouchableOpacity style={publishStyle.upload} onPress={this.handleUploadPressed}>
|
||||||
<Icon name="file-upload" size={48} color={Colors.White} />
|
<Icon name="file-upload" size={48} color={Colors.White} />
|
||||||
<Text style={publishStyle.actionText}>Upload a file</Text>
|
<Text style={publishStyle.actionText}>Upload a file</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@ -507,34 +584,68 @@ class PublishPage extends React.PureComponent {
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
{balance < 0.1 && <PublishRewardsDriver navigation={navigation} />}
|
||||||
|
|
||||||
|
{this.state.uploadThumbnailStarted && !this.state.uploadedThumbnailUri && (
|
||||||
|
<View style={publishStyle.thumbnailUploadContainer}>
|
||||||
|
<ActivityIndicator size={'small'} color={Colors.LbryGreen} />
|
||||||
|
<Text style={publishStyle.thumbnailUploadText}>Uploading thumbnail...</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
<View style={publishStyle.card}>
|
<View style={publishStyle.card}>
|
||||||
<Text style={publishStyle.cardTitle}>Title</Text>
|
<View style={publishStyle.textInputLayout}>
|
||||||
|
{(this.state.titleFocused || (this.state.title != null && this.state.title.trim().length > 0)) && (
|
||||||
|
<Text style={publishStyle.textInputTitle}>Title</Text>
|
||||||
|
)}
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder={'Title'}
|
placeholder={this.state.titleFocused ? '' : 'Title'}
|
||||||
style={publishStyle.inputText}
|
style={publishStyle.inputText}
|
||||||
value={this.state.title}
|
value={this.state.title}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
underlineColorAndroid={Colors.NextLbryGreen}
|
underlineColorAndroid={Colors.NextLbryGreen}
|
||||||
onChangeText={this.state.handleTitleChange}
|
onChangeText={this.handleTitleChange}
|
||||||
|
onFocus={() => this.setState({ titleFocused: true })}
|
||||||
|
onBlur={() => this.setState({ titleFocused: false })}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={publishStyle.card}>
|
<View style={publishStyle.textInputLayout}>
|
||||||
<Text style={publishStyle.cardTitle}>Description</Text>
|
{(this.state.descriptionFocused ||
|
||||||
|
(this.state.description != null && this.state.description.trim().length > 0)) && (
|
||||||
|
<Text style={publishStyle.textInputTitle}>Description</Text>
|
||||||
|
)}
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder={'Description'}
|
placeholder={this.state.descriptionFocused ? '' : 'Description'}
|
||||||
style={publishStyle.inputText}
|
style={publishStyle.inputText}
|
||||||
value={this.state.description}
|
value={this.state.description}
|
||||||
underlineColorAndroid={Colors.NextLbryGreen}
|
underlineColorAndroid={Colors.NextLbryGreen}
|
||||||
onChangeText={this.state.handleDescriptionChange}
|
onChangeText={this.handleDescriptionChange}
|
||||||
|
onFocus={() => this.setState({ descriptionFocused: true })}
|
||||||
|
onBlur={() => this.setState({ descriptionFocused: false })}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
<View style={publishStyle.card}>
|
<View style={publishStyle.card}>
|
||||||
<View style={publishStyle.titleRow}>
|
<Text style={publishStyle.cardTitle}>Tags</Text>
|
||||||
<Text style={publishStyle.cardTitle}>Channel</Text>
|
<View style={publishStyle.tagList}>
|
||||||
|
{this.state.tags &&
|
||||||
|
this.state.tags.map(tag => (
|
||||||
|
<Tag
|
||||||
|
key={tag}
|
||||||
|
name={tag}
|
||||||
|
type={'remove'}
|
||||||
|
style={publishStyle.tag}
|
||||||
|
onRemovePress={this.handleRemoveTag}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
<TagSearch handleAddTag={this.handleAddTag} selectedTags={this.state.tags} />
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={publishStyle.card}>
|
||||||
|
<Text style={publishStyle.cardTitle}>Channel</Text>
|
||||||
|
|
||||||
<ChannelSelector onChannelChange={this.handleChannelChange} />
|
<ChannelSelector onChannelChange={this.handleChannelChange} />
|
||||||
</View>
|
</View>
|
||||||
|
@ -600,11 +711,54 @@ class PublishPage extends React.PureComponent {
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{this.state.advancedMode && (
|
||||||
|
<View style={publishStyle.card}>
|
||||||
|
<Text style={publishStyle.cardTitle}>Additional Options</Text>
|
||||||
|
<View style={publishStyle.toggleField}>
|
||||||
|
<Switch value={this.state.mature} onValueChange={value => this.setState({ mature: value })} />
|
||||||
|
<Text style={publishStyle.toggleText}>Mature content</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View>
|
||||||
|
<Text style={publishStyle.cardText}>Language</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={this.state.language}
|
||||||
|
style={publishStyle.picker}
|
||||||
|
itemStyle={publishStyle.pickerItem}
|
||||||
|
onValueChange={this.handleLanguageValueChange}
|
||||||
|
>
|
||||||
|
{Object.keys(languages).map(lang => (
|
||||||
|
<Picker.Item label={languages[lang]} value={lang} key={lang} />
|
||||||
|
))}
|
||||||
|
</Picker>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View>
|
||||||
|
<Text style={publishStyle.cardText}>License</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={this.state.license}
|
||||||
|
style={publishStyle.picker}
|
||||||
|
itemStyle={publishStyle.pickerItem}
|
||||||
|
onValueChange={this.handleLicenseValueChange}
|
||||||
|
>
|
||||||
|
<Picker.Item label={'None'} value={LICENSES.NONE} key={LICENSES.NONE} />
|
||||||
|
<Picker.Item label={'Public Domain'} value={LICENSES.PUBLIC_DOMAIN} key={LICENSES.PUBLIC_DOMAIN} />
|
||||||
|
{LICENSES.CC_LICENSES.map(({ value, url }) => (
|
||||||
|
<Picker.Item label={value} value={value} key={value} />
|
||||||
|
))}
|
||||||
|
<Picker.Item label={'Copyrighted...'} value={LICENSES.COPYRIGHT} key={LICENSES.COPYRIGHT} />
|
||||||
|
<Picker.Item label={'Other...'} value={LICENSES.OTHER} key={LICENSES.OTHER} />
|
||||||
|
</Picker>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
<View style={publishStyle.toggleContainer}>
|
<View style={publishStyle.toggleContainer}>
|
||||||
<Link
|
<Link
|
||||||
text={this.state.advancedMode ? 'Hide extra fields' : 'Show extra fields'}
|
text={this.state.advancedMode ? 'Hide extra fields' : 'Show extra fields'}
|
||||||
onPress={this.handleModePressed}
|
onPress={this.handleModePressed}
|
||||||
style={publishStyle.modeLink} />
|
style={publishStyle.modeLink}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={publishStyle.actionButtons}>
|
<View style={publishStyle.actionButtons}>
|
||||||
|
@ -626,7 +780,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.uploadedThumbnailUri}
|
disabled={balance < 0.1 || !this.state.uploadedThumbnailUri}
|
||||||
text="Publish"
|
text="Publish"
|
||||||
onPress={this.handlePublishPressed}
|
onPress={this.handlePublishPressed}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -23,6 +23,7 @@ const channelSelectorStyle = StyleSheet.create({
|
||||||
channelNameInput: {
|
channelNameInput: {
|
||||||
fontFamily: 'Inter-UI-Regular',
|
fontFamily: 'Inter-UI-Regular',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
|
paddingLeft: 20,
|
||||||
},
|
},
|
||||||
bidAmountInput: {
|
bidAmountInput: {
|
||||||
fontFamily: 'Inter-UI-Regular',
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
@ -40,6 +41,13 @@ const channelSelectorStyle = StyleSheet.create({
|
||||||
marginLeft: 8,
|
marginLeft: 8,
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
},
|
},
|
||||||
|
channelAt: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 4,
|
||||||
|
top: 13,
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
buttonContainer: {
|
buttonContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
|
|
|
@ -9,6 +9,7 @@ const Colors = {
|
||||||
LbryGreen: '#2f9176',
|
LbryGreen: '#2f9176',
|
||||||
BrighterLbryGreen: '#40b887',
|
BrighterLbryGreen: '#40b887',
|
||||||
NextLbryGreen: '#38d9a9',
|
NextLbryGreen: '#38d9a9',
|
||||||
|
TagGreen: '#e3f6f1',
|
||||||
LightGrey: '#cccccc',
|
LightGrey: '#cccccc',
|
||||||
LighterGrey: '#e5e5e5',
|
LighterGrey: '#e5e5e5',
|
||||||
Orange: '#ffbb00',
|
Orange: '#ffbb00',
|
||||||
|
|
|
@ -322,14 +322,16 @@ const filePageStyle = StyleSheet.create({
|
||||||
tagTitle: {
|
tagTitle: {
|
||||||
fontFamily: 'Inter-UI-SemiBold',
|
fontFamily: 'Inter-UI-SemiBold',
|
||||||
flex: 0.2,
|
flex: 0.2,
|
||||||
|
marginTop: 4,
|
||||||
},
|
},
|
||||||
tagList: {
|
tagList: {
|
||||||
fontFamily: 'Inter-UI-Regular',
|
fontFamily: 'Inter-UI-Regular',
|
||||||
flex: 0.8,
|
flex: 0.8,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
},
|
},
|
||||||
tagItem: {
|
tagItem: {
|
||||||
marginRight: 16,
|
marginRight: 4,
|
||||||
},
|
},
|
||||||
rewardDriverCard: {
|
rewardDriverCard: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|
|
@ -45,8 +45,9 @@ const publishStyle = StyleSheet.create({
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
modeLink: {
|
modeLink: {
|
||||||
backgroundColor: Colors.NextLbryGreen,
|
color: Colors.LbryGreen,
|
||||||
alignSelf: 'flex-end'
|
alignSelf: 'flex-end',
|
||||||
|
marginRight: 16,
|
||||||
},
|
},
|
||||||
publishButton: {
|
publishButton: {
|
||||||
backgroundColor: Colors.LbryGreen,
|
backgroundColor: Colors.LbryGreen,
|
||||||
|
@ -81,7 +82,7 @@ const publishStyle = StyleSheet.create({
|
||||||
},
|
},
|
||||||
photo: {
|
photo: {
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
height: 120,
|
height: 240,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
@ -263,8 +264,68 @@ const publishStyle = StyleSheet.create({
|
||||||
toggleContainer: {
|
toggleContainer: {
|
||||||
marginTop: 24,
|
marginTop: 24,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'flex-end'
|
justifyContent: 'flex-end',
|
||||||
}
|
},
|
||||||
|
rewardDriverCard: {
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: Colors.BrighterLbryGreen,
|
||||||
|
flexDirection: 'row',
|
||||||
|
paddingLeft: 16,
|
||||||
|
paddingRight: 16,
|
||||||
|
paddingTop: 12,
|
||||||
|
paddingBottom: 12,
|
||||||
|
},
|
||||||
|
rewardDriverText: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
color: Colors.White,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
rewardIcon: {
|
||||||
|
color: Colors.White,
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
marginRight: 4,
|
||||||
|
marginBottom: 4,
|
||||||
|
},
|
||||||
|
tagList: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
},
|
||||||
|
textInputLayout: {
|
||||||
|
marginBottom: 4,
|
||||||
|
},
|
||||||
|
textInputTitle: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 12,
|
||||||
|
marginBottom: -10,
|
||||||
|
marginLeft: 4,
|
||||||
|
},
|
||||||
|
thumbnailUploadContainer: {
|
||||||
|
marginTop: 16,
|
||||||
|
marginLeft: 16,
|
||||||
|
marginRight: 16,
|
||||||
|
paddingLeft: 2,
|
||||||
|
paddingRight: 2,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
thumbnailUploadText: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 14,
|
||||||
|
marginLeft: 8,
|
||||||
|
},
|
||||||
|
toggleField: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginTop: 4,
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
toggleText: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 14,
|
||||||
|
marginLeft: 8,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default publishStyle;
|
export default publishStyle;
|
||||||
|
|
35
app/src/styles/tag.js
Normal file
35
app/src/styles/tag.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import Colors from './colors';
|
||||||
|
|
||||||
|
const tagStyle = StyleSheet.create({
|
||||||
|
tag: {
|
||||||
|
marginRight: 4,
|
||||||
|
marginBottom: 4,
|
||||||
|
},
|
||||||
|
tagSearchInput: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
paddingLeft: 8,
|
||||||
|
paddingTop: 4,
|
||||||
|
paddingBottom: 4,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 14,
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
|
tagResultsList: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default tagStyle;
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, git+https://github.com/lbryio/lbry.git@v0.37.4#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git@a404269d91cff5358bcffb8067b0fd1d9c6842d3#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, git+https://github.com/lbryio/torba@v0.5.4a0#egg=torba, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, git+https://github.com/lbryio/aioupnp.git@a404269d91cff5358bcffb8067b0fd1d9c6842d3#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.38.0#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.38.0#egg=torba&subdirectory=torba"
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, git+https://github.com/lbryio/lbry.git@v0.37.4#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git@a404269d91cff5358bcffb8067b0fd1d9c6842d3#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, git+https://github.com/lbryio/torba@v0.5.4a0#egg=torba, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, git+https://github.com/lbryio/aioupnp.git@a404269d91cff5358bcffb8067b0fd1d9c6842d3#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.38.0#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.38.0#egg=torba&subdirectory=torba"
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
|
|
@ -272,3 +272,4 @@ warn_on_root = 1
|
||||||
# Then, invoke the command line with the "demo" profile:
|
# Then, invoke the command line with the "demo" profile:
|
||||||
#
|
#
|
||||||
#buildozer --profile demo android debug
|
#buildozer --profile demo android debug
|
||||||
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, git+https://github.com/lbryio/aioupnp.git@a404269d91cff5358bcffb8067b0fd1d9c6842d3#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.38.0#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.38.0#egg=torba&subdirectory=torba"
|
|
@ -600,9 +600,9 @@ def run_pymodules_install(ctx, modules):
|
||||||
venv = sh.Command(ctx.virtualenv)
|
venv = sh.Command(ctx.virtualenv)
|
||||||
with current_directory(join(ctx.build_dir)):
|
with current_directory(join(ctx.build_dir)):
|
||||||
shprint(venv,
|
shprint(venv,
|
||||||
'--python=python{}'.format(
|
'--python=python{}.{}'.format(
|
||||||
ctx.python_recipe.major_minor_version_string.
|
ctx.python_recipe.major_minor_version_string.partition(".")[0],
|
||||||
partition(".")[0]
|
ctx.python_recipe.major_minor_version_string.partition(".")[2]
|
||||||
),
|
),
|
||||||
'venv'
|
'venv'
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,13 +6,12 @@ import platform
|
||||||
import sys
|
import sys
|
||||||
from jnius import autoclass
|
from jnius import autoclass
|
||||||
from keyring.backend import KeyringBackend
|
from keyring.backend import KeyringBackend
|
||||||
from lbrynet import __version__ as lbrynet_version, build_type
|
from lbry import __version__ as lbrynet_version, build_type
|
||||||
from lbrynet.conf import Config
|
from lbry.conf import Config
|
||||||
from lbrynet.extras.daemon.loggly_handler import get_loggly_handler
|
from lbry.extras.daemon.loggly_handler import get_loggly_handler
|
||||||
from lbrynet.extras.daemon.Components import DHT_COMPONENT, HASH_ANNOUNCER_COMPONENT, PEER_PROTOCOL_SERVER_COMPONENT
|
from lbry.extras.daemon.Components import DHT_COMPONENT, HASH_ANNOUNCER_COMPONENT, PEER_PROTOCOL_SERVER_COMPONENT
|
||||||
from lbrynet.extras.daemon.Daemon import Daemon
|
from lbry.extras.daemon.Daemon import Daemon
|
||||||
from lbrynet.extras.daemon.loggly_handler import get_loggly_handler
|
from lbry.extras.daemon.loggly_handler import get_loggly_handler
|
||||||
from lbrynet.utils import check_connection
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
|
@ -52,24 +51,24 @@ def configure_logging(conf):
|
||||||
conf.log_file_path, maxBytes=2097152, backupCount=5
|
conf.log_file_path, maxBytes=2097152, backupCount=5
|
||||||
)
|
)
|
||||||
file_handler.setFormatter(default_formatter)
|
file_handler.setFormatter(default_formatter)
|
||||||
logging.getLogger('lbrynet').addHandler(file_handler)
|
logging.getLogger('lbry').addHandler(file_handler)
|
||||||
logging.getLogger('torba').addHandler(file_handler)
|
logging.getLogger('torba').addHandler(file_handler)
|
||||||
|
|
||||||
handler = logging.StreamHandler()
|
handler = logging.StreamHandler()
|
||||||
handler.setFormatter(default_formatter)
|
handler.setFormatter(default_formatter)
|
||||||
|
|
||||||
log.addHandler(handler)
|
log.addHandler(handler)
|
||||||
logging.getLogger('lbrynet').addHandler(handler)
|
logging.getLogger('lbry').addHandler(handler)
|
||||||
logging.getLogger('torba').addHandler(handler)
|
logging.getLogger('torba').addHandler(handler)
|
||||||
|
|
||||||
logging.getLogger('aioupnp').setLevel(logging.WARNING)
|
logging.getLogger('aioupnp').setLevel(logging.WARNING)
|
||||||
logging.getLogger('aiohttp').setLevel(logging.CRITICAL)
|
logging.getLogger('aiohttp').setLevel(logging.CRITICAL)
|
||||||
logging.getLogger('lbrynet').setLevel(logging.DEBUG if lbrynet_android_utils.isDebug() else logging.INFO)
|
logging.getLogger('lbry').setLevel(logging.DEBUG if lbrynet_android_utils.isDebug() else logging.INFO)
|
||||||
logging.getLogger('torba').setLevel(logging.INFO)
|
logging.getLogger('torba').setLevel(logging.INFO)
|
||||||
|
|
||||||
loggly_handler = get_loggly_handler()
|
loggly_handler = get_loggly_handler()
|
||||||
loggly_handler.setLevel(logging.ERROR)
|
loggly_handler.setLevel(logging.ERROR)
|
||||||
logging.getLogger('lbrynet').addHandler(loggly_handler)
|
logging.getLogger('lbry').addHandler(loggly_handler)
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
keyring.set_keyring(LbryAndroidKeyring())
|
keyring.set_keyring(LbryAndroidKeyring())
|
||||||
|
|
Loading…
Reference in a new issue