diff --git a/src/page/channelCreator/index.js b/src/page/channelCreator/index.js index df340c9..b58c369 100644 --- a/src/page/channelCreator/index.js +++ b/src/page/channelCreator/index.js @@ -15,7 +15,7 @@ import { import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { doUpdateChannelFormState, doClearChannelFormState } from 'redux/actions/form'; import { selectDrawerStack } from 'redux/selectors/drawer'; -import { selectChannelFormState } from 'redux/selectors/form'; +import { selectChannelFormState, selectHasChannelFormState } from 'redux/selectors/form'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import ChannelCreator from './view'; @@ -26,6 +26,7 @@ const select = state => ({ drawerStack: selectDrawerStack(state), fetchingChannels: selectFetchingMyChannels(state), balance: selectBalance(state), + hasFormState: selectHasChannelFormState(state), updatingChannel: selectUpdatingChannel(state), updateChannelError: selectUpdateChannelError(state), }); diff --git a/src/page/channelCreator/view.js b/src/page/channelCreator/view.js index 8a4af4a..e41e0dc 100644 --- a/src/page/channelCreator/view.js +++ b/src/page/channelCreator/view.js @@ -35,7 +35,7 @@ export default class ChannelCreator extends React.PureComponent { canSave: false, claimId: null, currentSelectedValue: Constants.ITEM_ANONYMOUS, - currentPhase: Constants.PHASE_LIST, + currentPhase: null, displayName: null, channelNameUserEdited: false, newChannelTitle: '', @@ -110,8 +110,8 @@ export default class ChannelCreator extends React.PureComponent { }; componentWillReceiveProps(nextProps) { - const { currentRoute, drawerStack, updatingChannel, updateChannelError } = nextProps; const { currentRoute: prevRoute, drawerStack: prevDrawerStack, notify } = this.props; + const { currentRoute, drawerStack, updatingChannel, updateChannelError } = nextProps; if (Constants.DRAWER_ROUTE_CHANNEL_CREATOR === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); @@ -148,6 +148,7 @@ export default class ChannelCreator extends React.PureComponent { navigation, pushDrawerStack, setPlayerVisible, + hasFormState, } = this.props; NativeModules.Firebase.setCurrentScreen('Channels').then(result => { @@ -163,15 +164,21 @@ export default class ChannelCreator extends React.PureComponent { DeviceEventEmitter.addListener('onDocumentPickerFilePicked', this.onFilePicked); DeviceEventEmitter.addListener('onDocumentPickerCanceled', this.onPickerCanceled); + let isEditMode = false; if (navigation.state.params) { const { editChannelUrl, displayForm } = navigation.state.params; if (editChannelUrl) { + isEditMode = true; this.setState({ editChannelUrl, currentPhase: Constants.PHASE_CREATE }); - } else if (displayForm) { - this.loadPendingFormState(); - this.setState({ currentPhase: Constants.PHASE_CREATE }); } } + + if (!isEditMode && hasFormState) { + this.loadPendingFormState(); + this.setState({ currentPhase: Constants.PHASE_CREATE }); + } else { + this.setState({ currentPhase: Constants.PHASE_LIST }); + } }); }; @@ -519,7 +526,6 @@ export default class ChannelCreator extends React.PureComponent { handleNewChannelPress = () => { const { pushDrawerStack } = this.props; pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM); - this.loadPendingFormState(); this.setState({ currentPhase: Constants.PHASE_CREATE }); }; diff --git a/src/page/publish/index.js b/src/page/publish/index.js index 564ef70..ffbadf8 100644 --- a/src/page/publish/index.js +++ b/src/page/publish/index.js @@ -8,22 +8,31 @@ import { selectBalance, selectPublishFormValues, } from 'lbry-redux'; -import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; +import { selectDrawerStack } from 'redux/selectors/drawer'; +import { doUpdatePublishFormState, doClearPublishFormState } from 'redux/actions/form'; +import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; +import { selectPublishFormState, selectHasPublishFormState } from 'redux/selectors/form'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import PublishPage from './view'; const select = state => ({ balance: selectBalance(state), + drawerStack: selectDrawerStack(state), + hasFormState: selectHasPublishFormState(state), + publishFormState: selectPublishFormState(state), publishFormValues: selectPublishFormValues(state), }); const perform = dispatch => ({ notify: data => dispatch(doToast(data)), + clearPublishFormState: () => dispatch(doClearPublishFormState()), updatePublishForm: value => dispatch(doUpdatePublishForm(value)), + updatePublishFormState: data => dispatch(doUpdatePublishFormState(data)), uploadThumbnail: (filePath, fsAdapter) => dispatch(doUploadThumbnail(filePath, null, fsAdapter)), publish: (success, fail) => dispatch(doPublish(success, fail)), resolveUri: uri => dispatch(doResolveUri(uri)), - pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH)), + pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), + popDrawerStack: () => dispatch(doPopDrawerStack()), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); diff --git a/src/page/publish/view.js b/src/page/publish/view.js index e8c2b80..5d5d2f2 100644 --- a/src/page/publish/view.js +++ b/src/page/publish/view.js @@ -84,6 +84,7 @@ class PublishPage extends React.PureComponent { titleFocused: false, descriptionFocused: false, loadingVideos: false, + vanityUrl: null, // gallery videos videos: null, @@ -102,7 +103,7 @@ class PublishPage extends React.PureComponent { currentMedia: null, currentThumbnailUri: null, updatingThumbnailUri: false, - currentPhase: Constants.PHASE_SELECTOR, + currentPhase: null, // publish advancedMode: false, @@ -167,12 +168,18 @@ class PublishPage extends React.PureComponent { this.setState({ allThumbnailsChecked: true }); }; - onComponentFocused = () => { - const { balance, pushDrawerStack, setPlayerVisible, navigation } = this.props; - pushDrawerStack(); - setPlayerVisible(); + loadPendingFormState = () => { + const { publishFormState } = this.props; + const advancedMode = publishFormState.license !== null; + this.setState({ ...publishFormState, advancedMode }); + }; + onComponentFocused = () => { + const { balance, hasFormState, pushDrawerStack, setPlayerVisible, navigation } = this.props; NativeModules.Firebase.setCurrentScreen('Publish').then(result => { + pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH, navigation.state.params ? navigation.state.params : null); + setPlayerVisible(); + NativeModules.Gallery.canUseCamera().then(canUseCamera => this.setState({ canUseCamera })); NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath })); this.setState( @@ -186,26 +193,44 @@ class PublishPage extends React.PureComponent { ); // Check if this is an edit action + let isEditMode = false, + vanityUrlSet = false; if (navigation.state.params) { - const { editMode, claimToEdit, vanityUrl } = navigation.state.params; + const { displayForm, editMode, claimToEdit, vanityUrl } = navigation.state.params; if (editMode) { this.prepareEdit(claimToEdit); + isEditMode = true; } else if (vanityUrl) { const { claimName } = parseURI(vanityUrl); + vanityUrlSet = true; this.setState({ name: claimName, hasEditedContentAddress: true, - vanityUrlSet: true, + vanityUrlSet, + vanityUrl: claimName, }); } } + + if (!isEditMode && hasFormState) { + this.loadPendingFormState(); + if (vanityUrlSet) { + // replace name with the specified vanity URL if there was one in the pending state + this.setState({ name: this.state.vanityUrl }); + } + this.setState({ currentPhase: Constants.PHASE_DETAILS }); + } else { + this.setState({ currentPhase: Constants.PHASE_SELECTOR }); + } }); }; prepareEdit = claim => { - let channelName; + const { pushDrawerStack } = this.props; const { amount, name, signing_channel: signingChannel, value } = claim; const { description, fee, languages, license, license_url: licenseUrl, tags, thumbnail, title } = value; + + let channelName; if (signingChannel) { channelName = signingChannel.name; } @@ -256,6 +281,7 @@ class PublishPage extends React.PureComponent { if (channelName) { this.handleChannelChange(channelName); } + pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM); } ); }; @@ -374,8 +400,8 @@ class PublishPage extends React.PureComponent { } componentWillReceiveProps(nextProps) { - const { currentRoute, publishFormValues } = nextProps; - const { currentRoute: prevRoute, notify } = this.props; + const { currentRoute: prevRoute, drawerStack: prevDrawerStack, notify, updatePublishFormState } = this.props; + const { currentRoute, drawerStack, publishFormValues } = nextProps; if (Constants.DRAWER_ROUTE_PUBLISH === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); @@ -383,24 +409,38 @@ class PublishPage extends React.PureComponent { if (publishFormValues) { if (publishFormValues.thumbnail && !this.state.uploadedThumbnailUri) { - this.setState({ - currentThumbnailUri: publishFormValues.thumbnail, - uploadedThumbnailUri: publishFormValues.thumbnail, - }); + const { thumbnail } = publishFormValues; + updatePublishFormState({ currentThumbnailUri: thumbnail, uploadedThumbnailUri: thumbnail }); + this.setState({ currentThumbnailUri: thumbnail, uploadedThumbnailUri: thumbnail }); } } + + if ( + this.state.currentPhase === Constants.PHASE_DETAILS && + prevDrawerStack[prevDrawerStack.length - 1].route === Constants.DRAWER_ROUTE_PUBLISH_FORM && + drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_PUBLISH + ) { + // navigated back from the form + this.showSelector(); + } } setCurrentMedia(media) { + const { pushDrawerStack, updatePublishFormState } = this.props; const name = generateCombination(2, ' ', true); + const newName = this.state.hasEditedContentAddress ? this.state.name : this.formatNameForTitle(name); + updatePublishFormState({ currentMedia: media, name: newName }); this.setState( { currentMedia: media, title: null, // no title autogeneration (user will fill this in) - name: this.state.hasEditedContentAddress ? this.state.name : this.formatNameForTitle(name), + name: newName, currentPhase: Constants.PHASE_DETAILS, }, - () => this.handleNameChange(this.state.name) + () => { + this.handleNameChange(this.state.name); + pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM); + } ); } @@ -416,6 +456,7 @@ class PublishPage extends React.PureComponent { publishStarted: false, documentPickerOpen: false, editMode: false, + vanityUrl: null, currentMedia: null, currentThumbnailUri: null, @@ -505,6 +546,8 @@ class PublishPage extends React.PureComponent { }; handleCameraActionPressed = () => { + const { pushDrawerStack } = this.props; + // check if it's video or photo mode if (this.state.videoRecordingMode) { if (this.state.recordingVideo) { @@ -522,14 +565,17 @@ class PublishPage extends React.PureComponent { duration: 0, }; this.setCurrentMedia(currentMedia); - this.setState({ - currentThumbnailUri: null, - updatingThumbnailUri: false, - currentPhase: Constants.PHASE_DETAILS, - showCameraOverlay: false, - videoRecordingMode: false, - recordingVideo: false, - }); + this.setState( + { + currentThumbnailUri: null, + updatingThumbnailUri: false, + currentPhase: Constants.PHASE_DETAILS, + showCameraOverlay: false, + videoRecordingMode: false, + recordingVideo: false, + }, + () => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM) + ); }); } } else { @@ -543,13 +589,16 @@ class PublishPage extends React.PureComponent { duration: 0, }; this.setCurrentMedia(currentMedia); - this.setState({ - currentPhase: Constants.PHASE_DETAILS, - currentThumbnailUri: null, - updatingThumbnailUri: false, - showCameraOverlay: false, - videoRecordingMode: false, - }); + this.setState( + { + currentPhase: Constants.PHASE_DETAILS, + currentThumbnailUri: null, + updatingThumbnailUri: false, + showCameraOverlay: false, + videoRecordingMode: false, + }, + () => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH) + ); }); } }; @@ -575,15 +624,20 @@ class PublishPage extends React.PureComponent { }; handleBidChange = bid => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ bid }); this.setState({ bid }); }; handlePriceChange = price => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ price }); this.setState({ price }); }; handleNameChange = (name, userInput) => { - const { notify } = this.props; + const { notify, updatePublishFormState } = this.props; + updatePublishFormState({ name }); this.setState({ name }); if (userInput) { this.setState({ hasEditedContentAddress: true }); @@ -599,8 +653,10 @@ class PublishPage extends React.PureComponent { }; handleChannelChange = channel => { + const { updatePublishFormState } = this.props; const { name } = this.state; const uri = this.getNewUri(name, channel); + updatePublishFormState({ uri, channelName: channel, selectedChannel: channel }); this.setState({ uri, channelName: channel, selectedChannel: channel }); }; @@ -609,12 +665,13 @@ class PublishPage extends React.PureComponent { return; } - const { notify } = this.props; + const { notify, updatePublishFormState } = this.props; const { tags } = this.state; const index = tags.indexOf(tag.toLowerCase()); if (index === -1) { const newTags = tags.slice(); newTags.push(tag); + updatePublishFormState({ tags: newTags }); this.setState({ tags: newTags }); } else { notify({ message: __(`You already added the "${tag}" tag.`) }); @@ -626,11 +683,13 @@ class PublishPage extends React.PureComponent { return; } + const { updatePublishFormState } = this.props; const newTags = this.state.tags.slice(); const index = newTags.indexOf(tag.toLowerCase()); if (index > -1) { newTags.splice(index, 1); + updatePublishFormState({ tags: newTags }); this.setState({ tags: newTags }); } }; @@ -678,6 +737,8 @@ class PublishPage extends React.PureComponent { }; handleTitleChange = title => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ title }); this.setState({ title }); if (!this.state.editMode && !this.state.hasEditedContentAddress) { @@ -695,38 +756,46 @@ class PublishPage extends React.PureComponent { }; handleCurrencyValueChange = currency => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ currency }); this.setState({ currency }); }; handleDescriptionChange = description => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ description }); this.setState({ description }); }; handleLanguageValueChange = language => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ language }); this.setState({ language }); }; handleLicenseValueChange = license => { + const { updatePublishFormState } = this.props; + const otherLicenseDescription = [LICENSES.COPYRIGHT, LICENSES.OTHER].includes(license) ? this.state.otherLicenseDescription : ''; - - this.setState({ - otherLicenseDescription, - license, - licenseUrl: LICENSES.CC_LICENSES.reduce((value, item) => { - if (typeof value === 'object') { - value = ''; - } - if (license === item.value) { - value = item.url; - } - return value; - }), + const licenseUrl = LICENSES.CC_LICENSES.reduce((value, item) => { + if (typeof value === 'object') { + value = ''; + } + if (license === item.value) { + value = item.url; + } + return value; }); + + updatePublishFormState({ otherLicenseDescription, license, licenseUrl }); + this.setState({ otherLicenseDescription, license, licenseUrl }); }; handleChangeLicenseDescription = otherLicenseDescription => { + const { updatePublishFormState } = this.props; + updatePublishFormState({ otherLicenseDescription }); this.setState({ otherLicenseDescription }); }; @@ -831,17 +900,17 @@ class PublishPage extends React.PureComponent { resizeMode={FastImage.resizeMode.contain} source={{ uri: currentThumbnailUri }} /> + + {this.state.uploadThumbnailStarted && !this.state.uploadedThumbnailUri && ( + + + Uploading thumbnail... + + )} )} {!this.state.canPublish && } - {this.state.uploadThumbnailStarted && !this.state.uploadedThumbnailUri && ( - - - Uploading thumbnail... - - )} - {(this.state.titleFocused || (this.state.title != null && this.state.title.trim().length > 0)) && ( diff --git a/src/page/publishes/view.js b/src/page/publishes/view.js index 3654cc1..68a3a85 100644 --- a/src/page/publishes/view.js +++ b/src/page/publishes/view.js @@ -157,6 +157,15 @@ class PublishesPage extends React.PureComponent { initialNumToRender={8} maxToRenderPerBatch={24} removeClippedSubviews + ListFooterComponent={ + +