edit published content #32
10 changed files with 244 additions and 73 deletions
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -8046,9 +8046,9 @@
|
|||
}
|
||||
},
|
||||
"react-native-document-picker": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-2.3.0.tgz",
|
||||
"integrity": "sha512-bHMyAOzFl+II0ZdfzobKsZKvTErmXfmQGalpxpGbeN8+/uhfhUcdp4WuIMecZhFyX6rbj3h3XXLdA12hVlGgmw=="
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-3.2.4.tgz",
|
||||
"integrity": "sha512-5l0/fkgasUZdIk9jUUkReDtNCQn2yg1+BrMPHMt45c/NVmE15ThnhIuDj8/n8h1F1RlhUb3SzF86ANK4OdZAiQ=="
|
||||
},
|
||||
"react-native-exception-handler": {
|
||||
"version": "2.9.0",
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"@react-native-community/async-storage": "^1.5.1",
|
||||
"react-native-camera": "^2.11.1",
|
||||
"react-native-country-picker-modal": "^0.6.2",
|
||||
"react-native-document-picker": "^2.3.0",
|
||||
"react-native-document-picker": "^3.2.4",
|
||||
"react-native-exception-handler": "2.9.0",
|
||||
"react-native-fast-image": "^6.1.1",
|
||||
"react-native-fs": "^2.13.3",
|
||||
|
|
|
@ -26,12 +26,19 @@ export default class ChannelSelector extends React.PureComponent {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { channels, fetchChannelListMine, fetchingChannels } = this.props;
|
||||
const { channels, channelName, fetchChannelListMine, fetchingChannels } = this.props;
|
||||
if (!channels.length && !fetchingChannels) {
|
||||
fetchChannelListMine();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { channelName } = this.props;
|
||||
if (this.state.currentSelectedValue !== channelName) {
|
||||
this.setState({ currentSelectedValue: channelName });
|
||||
}
|
||||
}
|
||||
|
||||
handleCreateCancel = () => {
|
||||
this.setState({ showCreateChannel: false, newChannelName: '', newChannelBid: 0.1 });
|
||||
};
|
||||
|
@ -171,7 +178,7 @@ export default class ChannelSelector extends React.PureComponent {
|
|||
|
||||
render() {
|
||||
const channel = this.state.addingChannel ? 'new' : this.props.channel;
|
||||
const { fetchingChannels, channels = [] } = this.props;
|
||||
const { enabled, fetchingChannels, channels = [] } = this.props;
|
||||
const pickerItems = [Constants.ITEM_ANONYMOUS, Constants.ITEM_CREATE_A_CHANNEL].concat(channels.map(ch => ch.name));
|
||||
|
||||
const {
|
||||
|
@ -188,6 +195,7 @@ export default class ChannelSelector extends React.PureComponent {
|
|||
return (
|
||||
<View style={channelSelectorStyle.container}>
|
||||
<Picker
|
||||
enabled={enabled}
|
||||
selectedValue={this.state.currentSelectedValue}
|
||||
style={channelSelectorStyle.channelPicker}
|
||||
itemStyle={channelSelectorStyle.channelPickerItem}
|
||||
|
|
|
@ -135,9 +135,11 @@ class UriBar extends React.PureComponent {
|
|||
|
||||
render() {
|
||||
const {
|
||||
allowEdit,
|
||||
belowOverlay,
|
||||
navigation,
|
||||
onExitSelectionMode,
|
||||
onEditActionPressed,
|
||||
onDeleteActionPressed,
|
||||
query,
|
||||
selectedItemCount,
|
||||
|
@ -175,6 +177,19 @@ class UriBar extends React.PureComponent {
|
|||
</View>
|
||||
|
||||
<View style={uriBarStyle.selectionModeActions}>
|
||||
{allowEdit && selectedItemCount === 1 && (
|
||||
<TouchableOpacity
|
||||
style={[uriBarStyle.actionTouchArea, uriBarStyle.leftAction]}
|
||||
onPress={() => {
|
||||
if (onEditActionPressed) {
|
||||
onEditActionPressed();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon name="edit" size={20} style={uriBarStyle.actionIcon} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
<TouchableOpacity
|
||||
style={uriBarStyle.actionTouchArea}
|
||||
onPress={() => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
doFetchFileInfo,
|
||||
doFetchClaimListMine,
|
||||
doFileGet,
|
||||
doPurchaseUri,
|
||||
doDeletePurchasedUri,
|
||||
|
@ -18,6 +19,7 @@ import {
|
|||
makeSelectThumbnailForUri,
|
||||
makeSelectTitleForUri,
|
||||
selectBalance,
|
||||
selectMyClaimUrisWithoutChannels,
|
||||
selectPurchasedUris,
|
||||
selectFailedPurchaseUris,
|
||||
selectPurchaseUriErrorMessage,
|
||||
|
@ -50,14 +52,15 @@ const select = (state, props) => {
|
|||
contentType: makeSelectContentTypeForUri(selectProps.uri)(state),
|
||||
costInfo: makeSelectCostInfoForUri(selectProps.uri)(state),
|
||||
metadata: makeSelectMetadataForUri(selectProps.uri)(state),
|
||||
//obscureNsfw: !selectShowNsfw(state),
|
||||
//tab: makeSelectCurrentParam('tab')(state),
|
||||
// obscureNsfw: !selectShowNsfw(state),
|
||||
// tab: makeSelectCurrentParam('tab')(state),
|
||||
fileInfo: makeSelectFileInfoForUri(selectProps.uri)(state),
|
||||
rewardedContentClaimIds: selectRewardContentClaimIds(state, selectProps),
|
||||
channelUri: makeSelectChannelForClaimUri(selectProps.uri, true)(state),
|
||||
position: makeSelectContentPositionForUri(selectProps.uri)(state),
|
||||
purchasedUris: selectPurchasedUris(state),
|
||||
failedPurchaseUris: selectFailedPurchaseUris(state),
|
||||
myClaimUris: selectMyClaimUrisWithoutChannels(state),
|
||||
purchaseUriErrorMessage: selectPurchaseUriErrorMessage(state),
|
||||
streamingUrl: makeSelectStreamingUrlForUri(selectProps.uri)(state),
|
||||
thumbnail: makeSelectThumbnailForUri(selectProps.uri)(state),
|
||||
|
@ -71,6 +74,7 @@ const perform = dispatch => ({
|
|||
},
|
||||
fetchFileInfo: uri => dispatch(doFetchFileInfo(uri)),
|
||||
fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)),
|
||||
fetchMyClaims: () => dispatch(doFetchClaimListMine()),
|
||||
fileGet: (uri, saveFile) => dispatch(doFileGet(uri, saveFile)),
|
||||
notify: data => dispatch(doToast(data)),
|
||||
popDrawerStack: () => dispatch(doPopDrawerStack()),
|
||||
|
|
|
@ -232,6 +232,11 @@ class FilePage extends React.PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
onEditPressed = () => {
|
||||
const { claim, navigation } = this.props;
|
||||
This seemed easier to do since we only need a snapshot of the claim object, and it's less lines off code. Either way works. This seemed easier to do since we only need a snapshot of the claim object, and it's less lines off code. Either way works.
|
||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH, params: { editMode: true, claimToEdit: claim } });
|
||||
};
|
||||
|
||||
onDeletePressed = () => {
|
||||
const { claim, deleteFile, deletePurchasedUri, fileInfo, navigation } = this.props;
|
||||
|
||||
|
@ -244,11 +249,11 @@ class FilePage extends React.PureComponent {
|
|||
text: 'Yes',
|
||||
onPress: () => {
|
||||
const { uri } = navigation.state.params;
|
||||
|
||||
deleteFile(`${claim.txid}:${claim.nout}`, true);
|
||||
deletePurchasedUri(uri);
|
||||
if (NativeModules.UtilityModule) {
|
||||
NativeModules.UtilityModule.deleteDownload(uri);
|
||||
}
|
||||
|
||||
NativeModules.UtilityModule.deleteDownload(uri);
|
||||
this.setState({
|
||||
downloadPressed: false,
|
||||
fileViewLogged: false,
|
||||
|
@ -571,6 +576,7 @@ class FilePage extends React.PureComponent {
|
|||
rewardedContentClaimIds,
|
||||
isResolvingUri,
|
||||
blackListedOutpoints,
|
||||
myClaimUris,
|
||||
navigation,
|
||||
position,
|
||||
purchaseUri,
|
||||
|
@ -643,19 +649,20 @@ class FilePage extends React.PureComponent {
|
|||
const isPlayable = mediaType === 'video' || mediaType === 'audio';
|
||||
const { height, signing_channel: signingChannel, value } = claim;
|
||||
const channelName = signingChannel && signingChannel.name;
|
||||
const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id;
|
||||
const canSendTip = this.state.tipAmount > 0;
|
||||
const fullUri = `${claim.name}#${claim.claim_id}`;
|
||||
const canEdit = myClaimUris.includes(normalizeURI(fullUri));
|
||||
const showActions =
|
||||
fileInfo &&
|
||||
fileInfo.download_path &&
|
||||
(canEdit || (fileInfo && fileInfo.download_path)) &&
|
||||
!this.state.fullscreenMode &&
|
||||
!this.state.showImageViewer &&
|
||||
!this.state.showWebView;
|
||||
const showFileActions =
|
||||
fileInfo &&
|
||||
fileInfo.download_path &&
|
||||
(completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
|
||||
const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id;
|
||||
const canSendTip = this.state.tipAmount > 0;
|
||||
const fullUri = `${claim.name}#${claim.claim_id}`;
|
||||
canEdit ||
|
||||
(fileInfo &&
|
||||
fileInfo.download_path &&
|
||||
(completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes)));
|
||||
const fullChannelUri =
|
||||
channelClaimId && channelClaimId.trim().length > 0
|
||||
? normalizeURI(`${channelName}#${channelClaimId}`)
|
||||
|
@ -826,6 +833,16 @@ class FilePage extends React.PureComponent {
|
|||
<View style={filePageStyle.actions}>
|
||||
{showFileActions && (
|
||||
<View style={filePageStyle.fileActions}>
|
||||
{canEdit && (
|
||||
<Button
|
||||
style={[filePageStyle.actionButton, filePageStyle.editButton]}
|
||||
theme={'light'}
|
||||
icon={'edit'}
|
||||
text={'Edit'}
|
||||
onPress={this.onEditPressed}
|
||||
/>
|
||||
)}
|
||||
|
||||
{completed && (
|
||||
<Button
|
||||
style={filePageStyle.actionButton}
|
||||
|
|
|
@ -18,15 +18,16 @@ import { FlatGrid } from 'react-native-super-grid';
|
|||
import {
|
||||
isNameValid,
|
||||
buildURI,
|
||||
normalizeURI,
|
||||
regexInvalidURI,
|
||||
CLAIM_VALUES,
|
||||
LICENSES,
|
||||
MATURE_TAGS,
|
||||
THUMBNAIL_STATUSES,
|
||||
} from 'lbry-redux';
|
||||
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker';
|
||||
import { RNCamera } from 'react-native-camera';
|
||||
import { generateCombination } from 'gfycat-style-urls';
|
||||
import DocumentPicker from 'react-native-document-picker';
|
||||
import RNFS from 'react-native-fs';
|
||||
import Button from 'component/button';
|
||||
import ChannelSelector from 'component/channelSelector';
|
||||
|
@ -42,7 +43,7 @@ import Tag from 'component/tag';
|
|||
import TagSearch from 'component/tagSearch';
|
||||
import UriBar from 'component/uriBar';
|
||||
import publishStyle from 'styles/publish';
|
||||
import __ from 'utils/helper';
|
||||
import { __, navigateToUri } from 'utils/helper';
|
||||
|
||||
const languages = {
|
||||
en: 'English',
|
||||
|
@ -76,7 +77,9 @@ class PublishPage extends React.PureComponent {
|
|||
camera = null;
|
||||
|
||||
state = {
|
||||
canPublish: false,
|
||||
canUseCamera: false,
|
||||
editMode: false,
|
||||
titleFocused: false,
|
||||
descriptionFocused: false,
|
||||
loadingVideos: false,
|
||||
|
@ -107,6 +110,7 @@ class PublishPage extends React.PureComponent {
|
|||
priceSet: false,
|
||||
|
||||
// input data
|
||||
hasEditedContentAddress: false,
|
||||
bid: 0.1,
|
||||
description: null,
|
||||
title: null,
|
||||
|
@ -114,7 +118,6 @@ class PublishPage extends React.PureComponent {
|
|||
license: LICENSES.NONE,
|
||||
licenseUrl: '',
|
||||
otherLicenseDescription: '',
|
||||
mature: false,
|
||||
name: null,
|
||||
price: 0,
|
||||
uri: null,
|
||||
|
@ -158,23 +161,89 @@ class PublishPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
onComponentFocused = () => {
|
||||
const { pushDrawerStack, setPlayerVisible } = this.props;
|
||||
const { balance, pushDrawerStack, setPlayerVisible, navigation } = this.props;
|
||||
pushDrawerStack();
|
||||
setPlayerVisible();
|
||||
NativeModules.Firebase.setCurrentScreen('New publish').then(result => {
|
||||
|
||||
NativeModules.Firebase.setCurrentScreen('Publish').then(result => {
|
||||
NativeModules.Gallery.canUseCamera().then(canUseCamera => this.setState({ canUseCamera }));
|
||||
NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath }));
|
||||
this.setState(
|
||||
{
|
||||
canPublish: balance >= 0.1,
|
||||
loadingVideos: true,
|
||||
},
|
||||
() => {
|
||||
NativeModules.Gallery.getVideos().then(videos => this.setState({ videos, loadingVideos: false }));
|
||||
}
|
||||
);
|
||||
|
||||
// Check if this is an edit action
|
||||
if (navigation.state.params) {
|
||||
const { editMode, claimToEdit } = navigation.state.params;
|
||||
if (editMode) {
|
||||
this.prepareEdit(claimToEdit);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
prepareEdit = claim => {
|
||||
let channelName;
|
||||
const { amount, name, signing_channel: signingChannel, value } = claim;
|
||||
const { description, fee, languages, license, license_url: licenseUrl, tags, thumbnail, title } = value;
|
||||
if (signingChannel) {
|
||||
channelName = signingChannel.name;
|
||||
}
|
||||
|
||||
const thumbnailUrl = thumbnail ? thumbnail.url : null;
|
||||
|
||||
// Determine the license
|
||||
let licenseType, otherLicenseDescription;
|
||||
if (!LICENSES.CC_LICENSES.some(({ value }) => value === license)) {
|
||||
if (!license || license === LICENSES.NONE || license === LICENSES.PUBLIC_DOMAIN) {
|
||||
licenseType = license;
|
||||
} else if (license && !licenseUrl && license !== LICENSES.NONE) {
|
||||
licenseType = LICENSES.COPYRIGHT;
|
||||
} else {
|
||||
licenseType = LICENSES.OTHER;
|
||||
}
|
||||
|
||||
otherLicenseDescription = license;
|
||||
} else {
|
||||
licenseType = license;
|
||||
}
|
||||
|
||||
this.setState(
|
||||
{
|
||||
editMode: true,
|
||||
currentPhase: Constants.PHASE_DETAILS,
|
||||
|
||||
hasEditedContentAddress: true,
|
||||
bid: amount,
|
||||
channelName,
|
||||
description,
|
||||
language: languages && languages.length > 0 ? languages[0] : 'en', // default to English
|
||||
license: licenseType,
|
||||
licenseUrl,
|
||||
otherLicenseDescription,
|
||||
name,
|
||||
price: fee && fee.amount ? fee.amount : 0,
|
||||
priceSet: fee && fee.amount > 0,
|
||||
tags: tags && tags.length > 0 ? tags : [],
|
||||
title,
|
||||
currentThumbnailUri: thumbnailUrl,
|
||||
uploadedThumbnailUri: thumbnailUrl,
|
||||
},
|
||||
() => {
|
||||
this.handleNameChange(name);
|
||||
if (channelName) {
|
||||
this.handleChannelChange(channelName);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
getNewUri(name, channel) {
|
||||
const { resolveUri } = this.props;
|
||||
// If they are midway through a channel creation, treat it as anonymous until it completes
|
||||
|
@ -184,7 +253,7 @@ class PublishPage extends React.PureComponent {
|
|||
// We are only going to store the full uri, but we need to resolve the uri with and without the channel name
|
||||
let uri;
|
||||
try {
|
||||
uri = buildURI({ contentName: name, channelName });
|
||||
uri = buildURI({ claimName: name, channelName });
|
||||
} catch (e) {
|
||||
// something wrong with channel or name
|
||||
}
|
||||
|
@ -192,7 +261,7 @@ class PublishPage extends React.PureComponent {
|
|||
if (uri) {
|
||||
if (channelName) {
|
||||
// resolve without the channel name so we know the winning bid for it
|
||||
const uriLessChannel = buildURI({ contentName: name });
|
||||
const uriLessChannel = buildURI({ claimName: name });
|
||||
resolveUri(uriLessChannel);
|
||||
}
|
||||
resolveUri(uri);
|
||||
|
@ -209,6 +278,7 @@ class PublishPage extends React.PureComponent {
|
|||
handlePublishPressed = () => {
|
||||
const { notify, publish, updatePublishForm } = this.props;
|
||||
const {
|
||||
editMode,
|
||||
bid,
|
||||
channelName,
|
||||
currentMedia,
|
||||
|
@ -217,7 +287,6 @@ class PublishPage extends React.PureComponent {
|
|||
license,
|
||||
licenseUrl,
|
||||
otherLicenseDescription,
|
||||
mature,
|
||||
name,
|
||||
price,
|
||||
priceSet,
|
||||
|
@ -237,14 +306,21 @@ class PublishPage extends React.PureComponent {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!currentMedia && !editMode) {
|
||||
// sanity check. normally shouldn't happen
|
||||
notify({ message: 'No file selected. Please select a video or take a photo before publishing.' });
|
||||
return;
|
||||
}
|
||||
|
||||
const publishParams = {
|
||||
filePath: currentMedia.filePath,
|
||||
filePath: currentMedia ? currentMedia.filePath : null,
|
||||
bid: bid || 0.1,
|
||||
title: title || '',
|
||||
thumbnail,
|
||||
description: description || '',
|
||||
language,
|
||||
license,
|
||||
licenseType: license,
|
||||
licenseUrl,
|
||||
otherLicenseDescription,
|
||||
name: name || undefined,
|
||||
|
@ -253,12 +329,9 @@ class PublishPage extends React.PureComponent {
|
|||
uri: uri || undefined,
|
||||
channel: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? null : channelName,
|
||||
isStillEditing: false,
|
||||
claim: {
|
||||
value: {
|
||||
tags,
|
||||
release_time: Math.round(Date.now() / 1000), // set now as the release time
|
||||
},
|
||||
},
|
||||
tags: tags.map(tag => {
|
||||
return { name: tag };
|
||||
}),
|
||||
};
|
||||
|
||||
updatePublishForm(publishParams);
|
||||
|
@ -266,7 +339,11 @@ class PublishPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
handlePublishSuccess = data => {
|
||||
this.setState({ publishStarted: false, currentPhase: Constants.PHASE_PUBLISH });
|
||||
const { navigation, notify } = this.props;
|
||||
notify({
|
||||
message: `Your content was successfully published to ${this.state.uri}. It will be available in a few mintues.`,
|
||||
});
|
||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISHES, params: { publishSuccess: true } });
|
||||
};
|
||||
|
||||
handlePublishFailure = error => {
|
||||
|
@ -302,7 +379,7 @@ class PublishPage extends React.PureComponent {
|
|||
this.setState(
|
||||
{
|
||||
currentMedia: media,
|
||||
title: name,
|
||||
title: null, // no title autogeneration (user will fill this in)
|
||||
name: this.formatNameForTitle(name),
|
||||
currentPhase: Constants.PHASE_DETAILS,
|
||||
},
|
||||
|
@ -320,6 +397,7 @@ class PublishPage extends React.PureComponent {
|
|||
this.setState(
|
||||
{
|
||||
publishStarted: false,
|
||||
editMode: false,
|
||||
|
||||
currentMedia: null,
|
||||
currentThumbnailUri: null,
|
||||
|
@ -334,6 +412,7 @@ class PublishPage extends React.PureComponent {
|
|||
priceSet: false,
|
||||
|
||||
// input data
|
||||
hasEditedContentAddress: false,
|
||||
bid: 0.1,
|
||||
description: null,
|
||||
title: null,
|
||||
|
@ -434,16 +513,16 @@ class PublishPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleUploadPressed = () => {
|
||||
DocumentPicker.show(
|
||||
{
|
||||
filetype: [DocumentPickerUtil.allFiles()],
|
||||
},
|
||||
(error, res) => {
|
||||
if (!error) {
|
||||
// console.log(res);
|
||||
DocumentPicker.pick({ type: [DocumentPicker.types.allFiles] })
|
||||
.then(file => {
|
||||
// console.log(file);
|
||||
})
|
||||
.catch(error => {
|
||||
if (!DocumentPicker.isCancel(error)) {
|
||||
// notify the user
|
||||
// console.log(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
getRandomFileId = () => {
|
||||
|
@ -464,9 +543,13 @@ class PublishPage extends React.PureComponent {
|
|||
this.setState({ price });
|
||||
};
|
||||
|
||||
handleNameChange = name => {
|
||||
handleNameChange = (name, userInput) => {
|
||||
const { notify } = this.props;
|
||||
this.setState({ name });
|
||||
if (userInput) {
|
||||
this.setState({ hasEditedContentAddress: true });
|
||||
}
|
||||
|
||||
if (!isNameValid(name, false)) {
|
||||
notify({ message: 'Your content address contains invalid characters' });
|
||||
return;
|
||||
|
@ -483,7 +566,7 @@ class PublishPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleAddTag = tag => {
|
||||
if (!tag) {
|
||||
if (!tag || !this.state.canPublish || this.state.publishStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -500,7 +583,7 @@ class PublishPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleRemoveTag = tag => {
|
||||
if (!tag) {
|
||||
if (!tag || !this.state.canPublish || this.state.publishStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -556,15 +639,20 @@ class PublishPage extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleTitleChange = title => {
|
||||
this.setState(
|
||||
{
|
||||
title,
|
||||
name: this.formatNameForTitle(title),
|
||||
},
|
||||
() => {
|
||||
this.handleNameChange(this.state.name);
|
||||
}
|
||||
);
|
||||
this.setState({ title });
|
||||
|
||||
if (!this.state.editMode && !this.state.hasEditedContentAddress) {
|
||||
// only autogenerate url if the user has not yet edited the field
|
||||
// also shouldn't change url in edit mode
|
||||
this.setState(
|
||||
{
|
||||
name: this.formatNameForTitle(title),
|
||||
},
|
||||
() => {
|
||||
this.handleNameChange(this.state.name);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
handleDescriptionChange = description => {
|
||||
|
@ -685,9 +773,12 @@ class PublishPage extends React.PureComponent {
|
|||
)}
|
||||
</View>
|
||||
);
|
||||
} else if (Constants.PHASE_DETAILS === this.state.currentPhase && this.state.currentMedia) {
|
||||
} else if (
|
||||
Constants.PHASE_DETAILS === this.state.currentPhase &&
|
||||
(this.state.editMode || this.state.currentMedia)
|
||||
) {
|
||||
const { currentMedia, currentThumbnailUri } = this.state;
|
||||
if (!currentThumbnailUri) {
|
||||
if (!currentThumbnailUri && !this.state.editMode) {
|
||||
this.updateThumbnailUriForMedia(currentMedia);
|
||||
}
|
||||
content = (
|
||||
|
@ -701,7 +792,7 @@ class PublishPage extends React.PureComponent {
|
|||
/>
|
||||
</View>
|
||||
)}
|
||||
{balance < 0.1 && <PublishRewardsDriver navigation={navigation} />}
|
||||
{!this.state.canPublish && <PublishRewardsDriver navigation={navigation} />}
|
||||
|
||||
{this.state.uploadThumbnailStarted && !this.state.uploadedThumbnailUri && (
|
||||
<View style={publishStyle.thumbnailUploadContainer}>
|
||||
|
@ -716,6 +807,7 @@ class PublishPage extends React.PureComponent {
|
|||
<Text style={publishStyle.textInputTitle}>Title</Text>
|
||||
)}
|
||||
<TextInput
|
||||
editable={this.state.canPublish && !this.state.publishStarted}
|
||||
placeholder={this.state.titleFocused ? '' : 'Title'}
|
||||
style={publishStyle.inputText}
|
||||
value={this.state.title}
|
||||
|
@ -733,6 +825,7 @@ class PublishPage extends React.PureComponent {
|
|||
<Text style={publishStyle.textInputTitle}>Description</Text>
|
||||
)}
|
||||
<TextInput
|
||||
editable={this.state.canPublish && !this.state.publishStarted}
|
||||
placeholder={this.state.descriptionFocused ? '' : 'Description'}
|
||||
style={publishStyle.inputText}
|
||||
value={this.state.description}
|
||||
|
@ -764,7 +857,11 @@ class PublishPage extends React.PureComponent {
|
|||
<View style={publishStyle.card}>
|
||||
<Text style={publishStyle.cardTitle}>Channel</Text>
|
||||
|
||||
<ChannelSelector onChannelChange={this.handleChannelChange} />
|
||||
<ChannelSelector
|
||||
enabled={this.state.canPublish && !this.state.publishStarted}
|
||||
channelName={this.state.channelName}
|
||||
onChannelChange={this.handleChannelChange}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={publishStyle.card}>
|
||||
|
@ -782,6 +879,7 @@ class PublishPage extends React.PureComponent {
|
|||
{this.state.priceSet && (
|
||||
<View style={[publishStyle.inputRow, publishStyle.priceInputRow]}>
|
||||
<TextInput
|
||||
editable={this.state.canPublish && !this.state.publishStarted}
|
||||
placeholder={'0.00'}
|
||||
keyboardType={'number-pad'}
|
||||
style={publishStyle.priceInput}
|
||||
|
@ -796,21 +894,25 @@ class PublishPage extends React.PureComponent {
|
|||
</View>
|
||||
|
||||
<View style={publishStyle.card}>
|
||||
<Text style={publishStyle.cardTitle}>Content Address</Text>
|
||||
<Text style={publishStyle.cardTitle}>Content address</Text>
|
||||
<Text style={publishStyle.helpText}>
|
||||
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 &&
|
||||
' You cannot change this address while editing your content. If you wish to use a new address, please republish the content.'}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
editable={!this.state.editMode && this.state.canPublish && !this.state.publishStarted}
|
||||
placeholder={'lbry://'}
|
||||
style={publishStyle.inputText}
|
||||
underlineColorAndroid={Colors.NextLbryGreen}
|
||||
numberOfLines={1}
|
||||
value={this.state.name}
|
||||
onChangeText={this.handleNameChange}
|
||||
onChangeText={value => this.handleNameChange(value, true)}
|
||||
/>
|
||||
<View style={publishStyle.inputRow}>
|
||||
<TextInput
|
||||
editable={this.state.canPublish && !this.state.publishStarted}
|
||||
placeholder={'0.00'}
|
||||
style={publishStyle.priceInput}
|
||||
underlineColorAndroid={Colors.NextLbryGreen}
|
||||
|
@ -830,6 +932,7 @@ class PublishPage extends React.PureComponent {
|
|||
<View>
|
||||
<Text style={publishStyle.cardText}>Language</Text>
|
||||
<Picker
|
||||
enabled={this.state.canPublish && !this.state.publishStarted}
|
||||
selectedValue={this.state.language}
|
||||
style={publishStyle.picker}
|
||||
itemStyle={publishStyle.pickerItem}
|
||||
|
@ -844,6 +947,7 @@ class PublishPage extends React.PureComponent {
|
|||
<View>
|
||||
<Text style={publishStyle.cardText}>License</Text>
|
||||
<Picker
|
||||
enabled={this.state.canPublish && !this.state.publishStarted}
|
||||
selectedValue={this.state.license}
|
||||
style={publishStyle.picker}
|
||||
itemStyle={publishStyle.pickerItem}
|
||||
|
@ -859,6 +963,7 @@ class PublishPage extends React.PureComponent {
|
|||
</Picker>
|
||||
{[LICENSES.COPYRIGHT, LICENSES.OTHER].includes(this.state.license) && (
|
||||
<TextInput
|
||||
editable={this.state.canPublish && !this.state.publishStarted}
|
||||
placeholder={'License description'}
|
||||
style={publishStyle.inputText}
|
||||
underlineColorAndroid={Colors.NextLbryGreen}
|
||||
|
@ -901,8 +1006,8 @@ class PublishPage extends React.PureComponent {
|
|||
<View style={publishStyle.rightActionButtons}>
|
||||
<Button
|
||||
style={publishStyle.publishButton}
|
||||
disabled={balance < 0.1 || !this.state.uploadedThumbnailUri}
|
||||
text="Publish"
|
||||
disabled={!this.state.canPublish || !this.state.uploadedThumbnailUri}
|
||||
text={this.state.editMode ? 'Save changes' : 'Publish'}
|
||||
onPress={this.handlePublishPressed}
|
||||
/>
|
||||
</View>
|
||||
|
@ -917,7 +1022,11 @@ class PublishPage extends React.PureComponent {
|
|||
<Text style={publishStyle.successTitle}>Success!</Text>
|
||||
<Text style={publishStyle.successText}>Congratulations! Your content was successfully uploaded.</Text>
|
||||
<View style={publishStyle.successRow}>
|
||||
<Link style={publishStyle.successUrl} text={this.state.uri} href={this.state.uri} />
|
||||
<Link
|
||||
style={publishStyle.successUrl}
|
||||
text={this.state.uri}
|
||||
onPress={() => navigateToUri(navigation, this.state.uri)}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
Clipboard.setString(this.state.uri);
|
||||
|
|
|
@ -37,10 +37,10 @@ class PublishesPage extends React.PureComponent {
|
|||
const { checkPendingPublishes, fetchMyClaims, pushDrawerStack, setPlayerVisible } = this.props;
|
||||
pushDrawerStack();
|
||||
setPlayerVisible();
|
||||
NativeModules.Firebase.setCurrentScreen('Publishes');
|
||||
|
||||
fetchMyClaims();
|
||||
checkPendingPublishes();
|
||||
NativeModules.Firebase.setCurrentScreen('Publishes').then(result => {
|
||||
fetchMyClaims();
|
||||
checkPendingPublishes();
|
||||
});
|
||||
};
|
||||
|
||||
addOrRemoveItem = (uri, claim) => {
|
||||
|
@ -70,6 +70,16 @@ class PublishesPage extends React.PureComponent {
|
|||
this.setState({ selectionMode: false, selectedUris: [], selectedClaimsMap: {} });
|
||||
};
|
||||
|
||||
onEditActionPressed = () => {
|
||||
const { navigation } = this.props;
|
||||
const { selectedClaimsMap, selectedUris } = this.state;
|
||||
// only 1 item can be edited (and edit button should be visible only if there is a single selection)
|
||||
const claim = selectedClaimsMap[selectedUris[0]];
|
||||
this.onExitSelectionMode();
|
||||
|
||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH, params: { editMode: true, claimToEdit: claim } });
|
||||
};
|
||||
|
||||
onDeleteActionPressed = () => {
|
||||
const { abandonClaim } = this.props;
|
||||
const { selectedClaimsMap } = this.state;
|
||||
|
@ -103,11 +113,13 @@ class PublishesPage extends React.PureComponent {
|
|||
return (
|
||||
<View style={publishStyle.container}>
|
||||
<UriBar
|
||||
allowEdit
|
||||
navigation={navigation}
|
||||
selectionMode={selectionMode}
|
||||
selectedItemCount={selectedUris.length}
|
||||
onExitSelectionMode={this.onExitSelectionMode}
|
||||
onDeleteActionPressed={this.onDeleteActionPressed}
|
||||
onEditActionPressed={this.onEditActionPressed}
|
||||
onExitSelectionMode={this.onExitSelectionMode}
|
||||
/>
|
||||
{fetching && (
|
||||
<View style={publishStyle.centered}>
|
||||
|
@ -138,7 +150,6 @@ class PublishesPage extends React.PureComponent {
|
|||
removeClippedSubviews
|
||||
renderItem={({ item }) => (
|
||||
<FileListItem
|
||||
hideChannel
|
||||
key={item}
|
||||
uri={item}
|
||||
style={publishStyle.listItem}
|
||||
|
|
|
@ -194,6 +194,10 @@ const filePageStyle = StyleSheet.create({
|
|||
},
|
||||
fileActions: {
|
||||
alignSelf: 'flex-end',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
editButton: {
|
||||
marginRight: 8,
|
||||
},
|
||||
socialActions: {
|
||||
alignSelf: 'flex-start',
|
||||
|
|
|
@ -98,6 +98,9 @@ const uriBarStyle = StyleSheet.create({
|
|||
height: '100%',
|
||||
alignItems: 'center',
|
||||
},
|
||||
leftAction: {
|
||||
marginRight: 16,
|
||||
},
|
||||
actionTouchArea: {
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
|
|
Loading…
Reference in a new issue
would it make more sense to pass the claim id here rather than the whole object?
the publish component should be able to select the claim just from the id