redirect on publish/edit

This commit is contained in:
zeppi 2021-03-29 17:42:07 -04:00
parent f092e8cb7b
commit bd0fe4718f
5 changed files with 204 additions and 160 deletions

View file

@ -20,6 +20,7 @@ import analytics from 'analytics';
import LbcSymbol from 'component/common/lbc-symbol'; import LbcSymbol from 'component/common/lbc-symbol';
import SUPPORTED_LANGUAGES from 'constants/supported_languages'; import SUPPORTED_LANGUAGES from 'constants/supported_languages';
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp'; import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
import { SIMPLE_SITE } from 'config';
const LANG_NONE = 'none'; const LANG_NONE = 'none';
@ -358,7 +359,7 @@ function ChannelForm(props: Props) {
<Card <Card
body={ body={
<TagsSearch <TagsSearch
suggestMature suggestMature={!SIMPLE_SITE}
disableAutoFocus disableAutoFocus
limitSelect={MAX_TAG_SELECT} limitSelect={MAX_TAG_SELECT}
tagsPassedIn={params.tags || []} tagsPassedIn={params.tags || []}

View file

@ -249,6 +249,13 @@ function PublishForm(props: Props) {
} }
}, [name, activeChannelName, resolveUri, updatePublishForm, checkAvailability]); }, [name, activeChannelName, resolveUri, updatePublishForm, checkAvailability]);
useEffect(() => {
// because editingURI is lbry://channel_short/claim_long and that particular shape won't map to the claimId yet
if (editingURI) {
resolveUri(editingURI);
}
}, [editingURI, resolveUri]);
useEffect(() => { useEffect(() => {
updatePublishForm({ updatePublishForm({
isMarkdownPost: mode === PUBLISH_MODES.POST, isMarkdownPost: mode === PUBLISH_MODES.POST,
@ -434,7 +441,7 @@ function PublishForm(props: Props) {
{mode === PUBLISH_MODES.FILE && <PublishDescription disabled={formDisabled} />} {mode === PUBLISH_MODES.FILE && <PublishDescription disabled={formDisabled} />}
<Card actions={<SelectThumbnail />} /> <Card actions={<SelectThumbnail />} />
<TagsSelect <TagsSelect
suggestMature suggestMature={!SIMPLE_SITE}
disableAutoFocus disableAutoFocus
hideHeader hideHeader
label={__('Selected Tags')} label={__('Selected Tags')}

View file

@ -16,6 +16,8 @@ const select = (state) => ({
...selectPublishFormValues(state), ...selectPublishFormValues(state),
myChannels: selectMyChannelClaims(state), myChannels: selectMyChannelClaims(state),
isVid: makeSelectPublishFormValue('fileVid')(state), isVid: makeSelectPublishFormValue('fileVid')(state),
publishSuccess: makeSelectPublishFormValue('publishSuccess')(state),
publishing: makeSelectPublishFormValue('publishing')(state),
isStillEditing: selectIsStillEditing(state), isStillEditing: selectIsStillEditing(state),
ffmpegStatus: selectFfmpegStatus(state), ffmpegStatus: selectFfmpegStatus(state),
enablePublishPreview: makeSelectClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW)(state), enablePublishPreview: makeSelectClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW)(state),

View file

@ -41,17 +41,63 @@ type Props = {
setEnablePublishPreview: (boolean) => void, setEnablePublishPreview: (boolean) => void,
isStillEditing: boolean, isStillEditing: boolean,
myChannels: ?Array<ChannelClaim>, myChannels: ?Array<ChannelClaim>,
publishSuccess: boolean,
publishing: boolean,
}; };
class ModalPublishPreview extends React.PureComponent<Props> { // class ModalPublishPreview extends React.PureComponent<Props> {
onConfirmed() { const ModalPublishPreview = (props: Props) => {
const { filePath, publish, closeModal } = this.props; const {
filePath,
isMarkdownPost,
optimize,
title,
description,
channel,
bid,
uri,
contentIsFree,
fee,
language,
licenseType,
otherLicenseDescription,
licenseUrl,
tags,
isVid,
ffmpegStatus = {},
previewResponse,
enablePublishPreview,
setEnablePublishPreview,
isStillEditing,
myChannels,
publishSuccess,
publishing,
publish,
closeModal,
} = props;
const livestream =
// $FlowFixMe
previewResponse.outputs[0] && previewResponse.outputs[0].value && !previewResponse.outputs[0].value.source;
React.useEffect(() => {
console.log('publishSuccess', publishSuccess);
if (publishing && !livestream) {
console.log('doPublishing');
closeModal();
}
if (publishSuccess && livestream) {
console.log('doPublishSuccess');
closeModal();
}
}, [publishSuccess, publishing, livestream]);
// const waitForSuccess = false;
function onConfirmed() {
// Publish for real: // Publish for real:
publish(this.resolveFilePathName(filePath), false); publish(getFilePathName(filePath), false);
closeModal(); console.log('filePAath', filePath);
} }
resolveFilePathName(filePath: string | WebFile) { function getFilePathName(filePath: string | WebFile) {
if (!filePath) { if (!filePath) {
return NO_FILE; return NO_FILE;
} }
@ -63,7 +109,7 @@ class ModalPublishPreview extends React.PureComponent<Props> {
} }
} }
createRow(label: string, value: any) { function createRow(label: string, value: any) {
return ( return (
<tr> <tr>
<td>{label}</td> <td>{label}</td>
@ -72,54 +118,20 @@ class ModalPublishPreview extends React.PureComponent<Props> {
); );
} }
togglePreviewEnabled() { const txFee = previewResponse ? previewResponse['total_fee'] : null;
const { enablePublishPreview, setEnablePublishPreview } = this.props; // $FlowFixMe add outputs[0] etc to PublishResponse type
setEnablePublishPreview(!enablePublishPreview); const isOptimizeAvail = filePath && filePath !== '' && isVid && ffmpegStatus.available;
let modalTitle;
if (isStillEditing) {
modalTitle = __('Confirm Edit');
} else if (livestream) {
modalTitle = __('Create Livestream');
} else {
modalTitle = __('Confirm Upload');
} }
render() { let confirmBtnText;
const { if (!publishing) {
filePath,
isMarkdownPost,
optimize,
title,
description,
channel,
bid,
uri,
contentIsFree,
fee,
language,
licenseType,
otherLicenseDescription,
licenseUrl,
tags,
isVid,
ffmpegStatus = {},
previewResponse,
closeModal,
enablePublishPreview,
setEnablePublishPreview,
isStillEditing,
myChannels,
} = this.props;
const txFee = previewResponse ? previewResponse['total_fee'] : null;
// $FlowFixMe add outputs[0] etc to PublishResponse type
const livestream =
// $FlowFixMe
previewResponse.outputs[0] && previewResponse.outputs[0].value && !previewResponse.outputs[0].value.source;
const isOptimizeAvail = filePath && filePath !== '' && isVid && ffmpegStatus.available;
let modalTitle;
if (isStillEditing) {
modalTitle = __('Confirm Edit');
} else if (livestream) {
modalTitle = __('Create Livestream');
} else {
modalTitle = __('Confirm Upload');
}
let confirmBtnText;
if (isStillEditing) { if (isStillEditing) {
confirmBtnText = __('Save'); confirmBtnText = __('Save');
} else if (livestream) { } else if (livestream) {
@ -127,110 +139,119 @@ class ModalPublishPreview extends React.PureComponent<Props> {
} else { } else {
confirmBtnText = __('Upload'); confirmBtnText = __('Upload');
} }
const descriptionValue = description ? ( } else {
<div className="media__info-text-preview"> if (isStillEditing) {
<MarkdownPreview content={description} simpleLinks /> confirmBtnText = __('Saving');
</div> } else if (livestream) {
) : null; confirmBtnText = __('Creating');
} else {
const licenseValue = confirmBtnText = __('Uploading');
licenseType === COPYRIGHT ? (
<p>© {otherLicenseDescription}</p>
) : licenseType === OTHER ? (
<p>
{otherLicenseDescription}
<br />
{licenseUrl}
</p>
) : (
<p>{licenseType}</p>
);
const tagsValue =
// Do nothing for onClick(). Setting to 'null' results in "View Tag" action -- we don't want to leave the modal.
tags.map((tag) => <Tag key={tag.name} title={tag.name} name={tag.name} type={'flow'} onClick={() => {}} />);
const depositValue = bid ? <LbcSymbol postfix={`${bid}`} size={14} /> : <p>---</p>;
let priceValue = __('Free');
if (!contentIsFree) {
if (fee.currency === 'LBC') {
priceValue = <LbcSymbol postfix={fee.amount} />;
} else {
priceValue = `${fee.amount} ${fee.currency}`;
}
} }
const channelValue = (channel) => {
const channelClaim = myChannels && myChannels.find((x) => x.name === channel);
return channel ? (
<div className="channel-value">
{channelClaim && <ChannelThumbnail uri={channelClaim.permanent_url} />}
{channel}
</div>
) : (
<div className="channel-value">
<Icon sectionIcon icon={ICONS.ANONYMOUS} />
<i>{__('Anonymous')}</i>
</div>
);
};
return (
<Modal isOpen contentLabel={modalTitle} type="card" onAborted={closeModal}>
<Form onSubmit={() => this.onConfirmed()}>
<Card
title={modalTitle}
body={
<>
<div className="section">
<table className="table table--condensed table--publish-preview">
<tbody>
{!livestream && !isMarkdownPost && this.createRow(__('File'), this.resolveFilePathName(filePath))}
{isOptimizeAvail && this.createRow(__('Transcode'), optimize ? __('Yes') : __('No'))}
{this.createRow(__('Title'), title)}
{this.createRow(__('Description'), descriptionValue)}
{this.createRow(__('Channel'), channelValue(channel))}
{this.createRow(__('URL'), uri)}
{this.createRow(__('Deposit'), depositValue)}
{this.createRow(__('Price'), priceValue)}
{this.createRow(__('Language'), language)}
{this.createRow(__('License'), licenseValue)}
{this.createRow(__('Tags'), tagsValue)}
</tbody>
</table>
</div>
{txFee && (
<div className="section" aria-label={__('Estimated transaction fee:')}>
<b>{__('Est. transaction fee:')}</b>&nbsp;&nbsp;
<em>
<LbcSymbol postfix={txFee} />
</em>
</div>
)}
</>
}
actions={
<>
<div className="section__actions">
<Button autoFocus button="primary" label={confirmBtnText} onClick={() => this.onConfirmed()} />
<Button button="link" label={__('Cancel')} onClick={closeModal} />
</div>
<p className="help">{__('Once the transaction is sent, it cannot be reversed.')}</p>
<FormField
type="checkbox"
name="sync_toggle"
label={__('Skip preview and confirmation')}
checked={!enablePublishPreview}
onChange={() => setEnablePublishPreview(!enablePublishPreview)}
/>
</>
}
/>
</Form>
</Modal>
);
} }
}
const descriptionValue = description ? (
<div className="media__info-text-preview">
<MarkdownPreview content={description} simpleLinks />
</div>
) : null;
const licenseValue =
licenseType === COPYRIGHT ? (
<p>© {otherLicenseDescription}</p>
) : licenseType === OTHER ? (
<p>
{otherLicenseDescription}
<br />
{licenseUrl}
</p>
) : (
<p>{licenseType}</p>
);
const tagsValue =
// Do nothing for onClick(). Setting to 'null' results in "View Tag" action -- we don't want to leave the modal.
tags.map((tag) => <Tag key={tag.name} title={tag.name} name={tag.name} type={'flow'} onClick={() => {}} />);
const depositValue = bid ? <LbcSymbol postfix={`${bid}`} size={14} /> : <p>---</p>;
let priceValue = __('Free');
if (!contentIsFree) {
if (fee.currency === 'LBC') {
priceValue = <LbcSymbol postfix={fee.amount} />;
} else {
priceValue = `${fee.amount} ${fee.currency}`;
}
}
const channelValue = (channel) => {
const channelClaim = myChannels && myChannels.find((x) => x.name === channel);
return channel ? (
<div className="channel-value">
{channelClaim && <ChannelThumbnail uri={channelClaim.permanent_url} />}
{channel}
</div>
) : (
<div className="channel-value">
<Icon sectionIcon icon={ICONS.ANONYMOUS} />
<i>{__('Anonymous')}</i>
</div>
);
};
return (
<Modal isOpen contentLabel={modalTitle} type="card" onAborted={closeModal}>
<Form onSubmit={onConfirmed}>
<Card
title={modalTitle}
body={
<>
<div className="section">
<table className="table table--condensed table--publish-preview">
<tbody>
{!livestream && !isMarkdownPost && createRow(__('File'), getFilePathName(filePath))}
{isOptimizeAvail && createRow(__('Transcode'), optimize ? __('Yes') : __('No'))}
{createRow(__('Title'), title)}
{createRow(__('Description'), descriptionValue)}
{createRow(__('Channel'), channelValue(channel))}
{createRow(__('URL'), uri)}
{createRow(__('Deposit'), depositValue)}
{createRow(__('Price'), priceValue)}
{createRow(__('Language'), language)}
{createRow(__('License'), licenseValue)}
{createRow(__('Tags'), tagsValue)}
</tbody>
</table>
</div>
{txFee && (
<div className="section" aria-label={__('Estimated transaction fee:')}>
<b>{__('Est. transaction fee:')}</b>&nbsp;&nbsp;
<em>
<LbcSymbol postfix={txFee} />
</em>
</div>
)}
</>
}
actions={
<>
<div className="section__actions">
<Button autoFocus button="primary" disabled={publishing} label={confirmBtnText} onClick={onConfirmed} />
<Button button="link" label={__('Cancel')} onClick={closeModal} />
</div>
<p className="help">{__('Once the transaction is sent, it cannot be reversed.')}</p>
<FormField
type="checkbox"
name="sync_toggle"
label={__('Skip preview and confirmation')}
checked={!enablePublishPreview}
onChange={() => setEnablePublishPreview(!enablePublishPreview)}
/>
</>
}
/>
</Form>
</Modal>
);
};
export default ModalPublishPreview; export default ModalPublishPreview;

View file

@ -9,6 +9,8 @@ import {
doCheckPendingClaims, doCheckPendingClaims,
doCheckReflectingFiles, doCheckReflectingFiles,
ACTIONS as LBRY_REDUX_ACTIONS, ACTIONS as LBRY_REDUX_ACTIONS,
makeSelectPublishFormValue,
makeSelectClaimForUri,
} from 'lbry-redux'; } from 'lbry-redux';
import { doError } from 'redux/actions/notifications'; import { doError } from 'redux/actions/notifications';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
@ -24,7 +26,12 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
); );
}; };
const noFile = !filePath || filePath === NO_FILE; const noFileParam = !filePath || filePath === NO_FILE;
const state = getState();
const editingUri = makeSelectPublishFormValue('editingURI')(state) || '';
const claim = makeSelectClaimForUri(editingUri)(state) || {};
const hasSourceFile = claim.value && claim.value.source;
const redirectToLivestream = noFileParam && !hasSourceFile;
const publishSuccess = (successResponse, lbryFirstError) => { const publishSuccess = (successResponse, lbryFirstError) => {
const state = getState(); const state = getState();
@ -41,6 +48,7 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
actions.push({ actions.push({
type: ACTIONS.PUBLISH_SUCCESS, type: ACTIONS.PUBLISH_SUCCESS,
}); });
// We have to fake a temp claim until the new pending one is returned by claim_list_mine // We have to fake a temp claim until the new pending one is returned by claim_list_mine
// We can't rely on claim_list_mine because there might be some delay before the new claims are returned // We can't rely on claim_list_mine because there might be some delay before the new claims are returned
// Doing this allows us to show the pending claim immediately, it will get overwritten by the real one // Doing this allows us to show the pending claim immediately, it will get overwritten by the real one
@ -73,6 +81,9 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
// @if TARGET='app' // @if TARGET='app'
dispatch(doCheckReflectingFiles()); dispatch(doCheckReflectingFiles());
// @endif // @endif
if (redirectToLivestream) {
dispatch(push(`/$/${PAGES.LIVESTREAM}`));
}
}; };
const publishFail = (error) => { const publishFail = (error) => {
@ -93,7 +104,9 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
// on the publishes page. This doesn't exist on desktop so wait until we get a response // on the publishes page. This doesn't exist on desktop so wait until we get a response
// from the SDK // from the SDK
// @if TARGET='web' // @if TARGET='web'
dispatch(push(noFile ? `/$/${PAGES.LIVESTREAM}` : `/$/${PAGES.UPLOADS}`)); if (!redirectToLivestream) {
dispatch(push(`/$/${PAGES.UPLOADS}`));
}
// @endif // @endif
dispatch(doPublish(publishSuccess, publishFail)); dispatch(doPublish(publishSuccess, publishFail));