Thumbnail upload fixes (#6860)
more improvements, fix url, do the same for cover remember url, error if invalid unneeded addition Fix delayed message Lint Allow empty values (placeholder and Gerbil) Fix filepath crash Fix button
This commit is contained in:
parent
ef5701bb38
commit
b256a4396b
9 changed files with 97 additions and 109 deletions
|
@ -22,6 +22,8 @@ import SUPPORTED_LANGUAGES from 'constants/supported_languages';
|
||||||
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
|
import WalletSpendableBalanceHelp from 'component/walletSpendableBalanceHelp';
|
||||||
import { SIMPLE_SITE } from 'config';
|
import { SIMPLE_SITE } from 'config';
|
||||||
import { sortLanguageMap } from 'util/default-languages';
|
import { sortLanguageMap } from 'util/default-languages';
|
||||||
|
import ThumbnailBrokenImage from 'component/selectThumbnail/thumbnail-broken.png';
|
||||||
|
import Gerbil from 'component/channelThumbnail/gerbil.png';
|
||||||
|
|
||||||
const LANG_NONE = 'none';
|
const LANG_NONE = 'none';
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ type Props = {
|
||||||
onDone: () => void,
|
onDone: () => void,
|
||||||
openModal: (
|
openModal: (
|
||||||
id: string,
|
id: string,
|
||||||
{ onUpdate: (string) => void, assetName: string, helpText: string, currentValue: string, title: string }
|
{ onUpdate: (string, boolean) => void, assetName: string, helpText: string, currentValue: string, title: string }
|
||||||
) => void,
|
) => void,
|
||||||
uri: string,
|
uri: string,
|
||||||
disabled: boolean,
|
disabled: boolean,
|
||||||
|
@ -90,7 +92,9 @@ function ChannelForm(props: Props) {
|
||||||
} = props;
|
} = props;
|
||||||
const [nameError, setNameError] = React.useState(undefined);
|
const [nameError, setNameError] = React.useState(undefined);
|
||||||
const [bidError, setBidError] = React.useState('');
|
const [bidError, setBidError] = React.useState('');
|
||||||
|
const [isUpload, setIsUpload] = React.useState({ cover: false, thumbnail: false });
|
||||||
const [coverError, setCoverError] = React.useState(false);
|
const [coverError, setCoverError] = React.useState(false);
|
||||||
|
const [thumbError, setThumbError] = React.useState(false);
|
||||||
const { claim_id: claimId } = claim || {};
|
const { claim_id: claimId } = claim || {};
|
||||||
const [params, setParams]: [any, (any) => void] = React.useState(getChannelParams());
|
const [params, setParams]: [any, (any) => void] = React.useState(getChannelParams());
|
||||||
const { channelName } = parseURI(uri);
|
const { channelName } = parseURI(uri);
|
||||||
|
@ -112,10 +116,12 @@ function ChannelForm(props: Props) {
|
||||||
creatingChannel ||
|
creatingChannel ||
|
||||||
updatingChannel ||
|
updatingChannel ||
|
||||||
nameError ||
|
nameError ||
|
||||||
|
thumbError ||
|
||||||
|
coverError ||
|
||||||
bidError ||
|
bidError ||
|
||||||
(isNewChannel && !params.name)
|
(isNewChannel && !params.name)
|
||||||
);
|
);
|
||||||
}, [isClaimingInitialRewards, creatingChannel, updatingChannel, nameError, bidError, isNewChannel, params]);
|
}, [isClaimingInitialRewards, creatingChannel, updatingChannel, nameError, thumbError, coverError, bidError, isNewChannel, params.name]);
|
||||||
|
|
||||||
function getChannelParams() {
|
function getChannelParams() {
|
||||||
// fill this in with sdk data
|
// fill this in with sdk data
|
||||||
|
@ -195,12 +201,16 @@ function ChannelForm(props: Props) {
|
||||||
setParams({ ...params, languages: langs });
|
setParams({ ...params, languages: langs });
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleThumbnailChange(thumbnailUrl: string) {
|
function handleThumbnailChange(thumbnailUrl: string, uploadSelected: boolean) {
|
||||||
setParams({ ...params, thumbnailUrl });
|
setParams({ ...params, thumbnailUrl });
|
||||||
|
setIsUpload({ ...isUpload, thumbnail: uploadSelected });
|
||||||
|
setThumbError(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCoverChange(coverUrl: string) {
|
function handleCoverChange(coverUrl: string, uploadSelected: boolean) {
|
||||||
setParams({ ...params, coverUrl });
|
setParams({ ...params, coverUrl });
|
||||||
|
setIsUpload({ ...isUpload, cover: uploadSelected });
|
||||||
|
setCoverError(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
|
@ -225,6 +235,9 @@ function ChannelForm(props: Props) {
|
||||||
if (errorMsg && errorMsg.includes(LIMIT_ERR_PARTIAL_MSG)) {
|
if (errorMsg && errorMsg.includes(LIMIT_ERR_PARTIAL_MSG)) {
|
||||||
errorMsg = __('Transaction limit reached. Try reducing the Description length.');
|
errorMsg = __('Transaction limit reached. Try reducing the Description length.');
|
||||||
}
|
}
|
||||||
|
if ((!isUpload.thumbnail && thumbError) || (!isUpload.cover && coverError)) {
|
||||||
|
errorMsg = __('Invalid %error_type%', { error_type: (thumbError && 'thumbnail') || (coverError && 'cover image') });
|
||||||
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let nameError;
|
let nameError;
|
||||||
|
@ -247,6 +260,17 @@ function ChannelForm(props: Props) {
|
||||||
}
|
}
|
||||||
}, [hasClaimedInitialRewards, claimInitialRewards]);
|
}, [hasClaimedInitialRewards, claimInitialRewards]);
|
||||||
|
|
||||||
|
const coverSrc = coverError ? ThumbnailBrokenImage : params.coverUrl;
|
||||||
|
|
||||||
|
let thumbnailPreview;
|
||||||
|
if (!params.thumbnailUrl) {
|
||||||
|
thumbnailPreview = Gerbil;
|
||||||
|
} else if (thumbError) {
|
||||||
|
thumbnailPreview = ThumbnailBrokenImage;
|
||||||
|
} else {
|
||||||
|
thumbnailPreview = params.thumbnailUrl;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO clear and bail after submit
|
// TODO clear and bail after submit
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -258,7 +282,7 @@ function ChannelForm(props: Props) {
|
||||||
title={__('Cover')}
|
title={__('Cover')}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openModal(MODALS.IMAGE_UPLOAD, {
|
openModal(MODALS.IMAGE_UPLOAD, {
|
||||||
onUpdate: (coverUrl) => handleCoverChange(coverUrl),
|
onUpdate: (coverUrl, isUpload) => handleCoverChange(coverUrl, isUpload),
|
||||||
title: __('Edit Cover Image'),
|
title: __('Edit Cover Image'),
|
||||||
helpText: __('(6.25:1)'),
|
helpText: __('(6.25:1)'),
|
||||||
assetName: __('Cover Image'),
|
assetName: __('Cover Image'),
|
||||||
|
@ -270,11 +294,16 @@ function ChannelForm(props: Props) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{params.coverUrl &&
|
{params.coverUrl &&
|
||||||
(coverError ? (
|
(coverError && isUpload.cover ? (
|
||||||
<div className="channel-cover__custom--waiting">{__('This will be visible in a few minutes.')}</div>
|
<div className="channel-cover__custom--waiting">{__('This will be visible in a few minutes.')}</div>
|
||||||
) : (
|
) : (
|
||||||
<img className="channel-cover__custom" src={params.coverUrl} onError={() => setCoverError(true)} />
|
<img
|
||||||
))}
|
className="channel-cover__custom"
|
||||||
|
src={coverSrc}
|
||||||
|
onError={() => setCoverError(true)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
<div className="channel__primary-info">
|
<div className="channel__primary-info">
|
||||||
<div className="channel__edit-thumb">
|
<div className="channel__edit-thumb">
|
||||||
<Button
|
<Button
|
||||||
|
@ -282,7 +311,7 @@ function ChannelForm(props: Props) {
|
||||||
title={__('Edit')}
|
title={__('Edit')}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openModal(MODALS.IMAGE_UPLOAD, {
|
openModal(MODALS.IMAGE_UPLOAD, {
|
||||||
onUpdate: (v) => handleThumbnailChange(v),
|
onUpdate: (thumbnailUrl, isUpload) => handleThumbnailChange(thumbnailUrl, isUpload),
|
||||||
title: __('Edit Thumbnail Image'),
|
title: __('Edit Thumbnail Image'),
|
||||||
helpText: __('(1:1)'),
|
helpText: __('(1:1)'),
|
||||||
assetName: __('Thumbnail'),
|
assetName: __('Thumbnail'),
|
||||||
|
@ -296,9 +325,11 @@ function ChannelForm(props: Props) {
|
||||||
<ChannelThumbnail
|
<ChannelThumbnail
|
||||||
className="channel__thumbnail--channel-page"
|
className="channel__thumbnail--channel-page"
|
||||||
uri={uri}
|
uri={uri}
|
||||||
thumbnailPreview={params.thumbnailUrl}
|
thumbnailPreview={thumbnailPreview}
|
||||||
allowGifs
|
allowGifs
|
||||||
showDelayedMessage
|
showDelayedMessage={isUpload.thumbnail}
|
||||||
|
setThumbError={(v) => setThumbError(v)}
|
||||||
|
thumbError={thumbError}
|
||||||
/>
|
/>
|
||||||
<h1 className="channel__title">
|
<h1 className="channel__title">
|
||||||
{params.title || (channelName && '@' + channelName) || (params.name && '@' + params.name)}
|
{params.title || (channelName && '@' + channelName) || (params.name && '@' + params.name)}
|
||||||
|
|
|
@ -23,6 +23,10 @@ type Props = {
|
||||||
showDelayedMessage?: boolean,
|
showDelayedMessage?: boolean,
|
||||||
noLazyLoad?: boolean,
|
noLazyLoad?: boolean,
|
||||||
hideStakedIndicator?: boolean,
|
hideStakedIndicator?: boolean,
|
||||||
|
xsmall?: boolean,
|
||||||
|
noOptimization?: boolean,
|
||||||
|
setThumbError: (boolean) => void,
|
||||||
|
thumbError: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ChannelThumbnail(props: Props) {
|
function ChannelThumbnail(props: Props) {
|
||||||
|
@ -41,15 +45,15 @@ function ChannelThumbnail(props: Props) {
|
||||||
showDelayedMessage = false,
|
showDelayedMessage = false,
|
||||||
noLazyLoad,
|
noLazyLoad,
|
||||||
hideStakedIndicator = false,
|
hideStakedIndicator = false,
|
||||||
|
setThumbError,
|
||||||
} = props;
|
} = props;
|
||||||
const [thumbError, setThumbError] = React.useState(false);
|
|
||||||
const shouldResolve = claim === undefined;
|
const shouldResolve = claim === undefined;
|
||||||
const thumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://');
|
const thumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://');
|
||||||
const thumbnailPreview = rawThumbnailPreview && rawThumbnailPreview.trim().replace(/^http:\/\//i, 'https://');
|
const thumbnailPreview = rawThumbnailPreview && rawThumbnailPreview.trim().replace(/^http:\/\//i, 'https://');
|
||||||
const channelThumbnail = thumbnail || thumbnailPreview;
|
const defaultAvater = AVATAR_DEFAULT || Gerbil;
|
||||||
|
const channelThumbnail = thumbnailPreview || thumbnail || defaultAvater;
|
||||||
const isGif = channelThumbnail && channelThumbnail.endsWith('gif');
|
const isGif = channelThumbnail && channelThumbnail.endsWith('gif');
|
||||||
const showThumb = (!obscure && !!thumbnail) || thumbnailPreview;
|
const showThumb = (!obscure && !!thumbnail) || thumbnailPreview;
|
||||||
const defaultAvater = AVATAR_DEFAULT || Gerbil;
|
|
||||||
|
|
||||||
// Generate a random color class based on the first letter of the channel name
|
// Generate a random color class based on the first letter of the channel name
|
||||||
const { channelName } = parseURI(uri);
|
const { channelName } = parseURI(uri);
|
||||||
|
@ -75,6 +79,7 @@ function ChannelThumbnail(props: Props) {
|
||||||
</FreezeframeWrapper>
|
</FreezeframeWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classnames('channel-thumbnail', className, {
|
className={classnames('channel-thumbnail', className, {
|
||||||
|
@ -84,30 +89,17 @@ function ChannelThumbnail(props: Props) {
|
||||||
'channel-thumbnail--resolving': isResolving,
|
'channel-thumbnail--resolving': isResolving,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{!showThumb && (
|
{showDelayedMessage ? (
|
||||||
|
<div className="channel-thumbnail--waiting">{__('This will be visible in a few minutes.')}</div>
|
||||||
|
) : (
|
||||||
<OptimizedImage
|
<OptimizedImage
|
||||||
alt={__('Channel profile picture')}
|
alt={__('Channel profile picture')}
|
||||||
className="channel-thumbnail__default"
|
className={!channelThumbnail ? 'channel-thumbnail__default' : 'channel-thumbnail__custom'}
|
||||||
src={!thumbError && channelThumbnail ? channelThumbnail : defaultAvater}
|
src={channelThumbnail}
|
||||||
loading={noLazyLoad ? undefined : 'lazy'}
|
loading={noLazyLoad ? undefined : 'lazy'}
|
||||||
onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil.
|
onError={() => setThumbError(true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showThumb && (
|
|
||||||
<>
|
|
||||||
{showDelayedMessage && thumbError ? (
|
|
||||||
<div className="chanel-thumbnail--waiting">{__('This will be visible in a few minutes.')}</div>
|
|
||||||
) : (
|
|
||||||
<OptimizedImage
|
|
||||||
alt={__('Channel profile picture')}
|
|
||||||
className="channel-thumbnail__custom"
|
|
||||||
src={!thumbError && channelThumbnail ? channelThumbnail : defaultAvater}
|
|
||||||
loading={noLazyLoad ? undefined : 'lazy'}
|
|
||||||
onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil.
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{!hideStakedIndicator && <ChannelStakedIndicator uri={uri} claim={claim} />}
|
{!hideStakedIndicator && <ChannelStakedIndicator uri={uri} claim={claim} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { FormField } from 'component/common/form';
|
||||||
type Props = {
|
type Props = {
|
||||||
type: string,
|
type: string,
|
||||||
currentPath?: ?string,
|
currentPath?: ?string,
|
||||||
onFileChosen: WebFile => void,
|
onFileChosen: (WebFile) => void,
|
||||||
label?: string,
|
label?: string,
|
||||||
placeholder?: string,
|
placeholder?: string,
|
||||||
accept?: string,
|
accept?: string,
|
||||||
|
@ -19,17 +19,6 @@ type Props = {
|
||||||
class FileSelector extends React.PureComponent<Props> {
|
class FileSelector extends React.PureComponent<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
};
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps: Props) {
|
|
||||||
// If the form has just been cleared,
|
|
||||||
// clear the file input
|
|
||||||
if (prevProps.currentPath && !this.props.currentPath) {
|
|
||||||
this.fileInput.current.value = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
type: 'file',
|
type: 'file',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,6 +28,7 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
super();
|
super();
|
||||||
this.fileInput = React.createRef();
|
this.fileInput = React.createRef();
|
||||||
this.handleFileInputSelection = this.handleFileInputSelection.bind(this);
|
this.handleFileInputSelection = this.handleFileInputSelection.bind(this);
|
||||||
|
this.handleDirectoryInputSelection = this.handleDirectoryInputSelection.bind(this);
|
||||||
this.fileInputButton = this.fileInputButton.bind(this);
|
this.fileInputButton = this.fileInputButton.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +43,7 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
if (this.props.onFileChosen) {
|
if (this.props.onFileChosen) {
|
||||||
this.props.onFileChosen(file);
|
this.props.onFileChosen(file);
|
||||||
}
|
}
|
||||||
|
this.fileInput.current.value = null; // clear the file input
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDirectoryInputSelection = () => {
|
handleDirectoryInputSelection = () => {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FileSelector from 'component/common/file-selector';
|
import FileSelector from 'component/common/file-selector';
|
||||||
import { SPEECH_URLS } from 'lbry-redux';
|
import { SPEECH_URLS } from 'lbry-redux';
|
||||||
|
@ -8,7 +7,6 @@ import Button from 'component/button';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
import { generateThumbnailName } from 'util/generate-thumbnail-name';
|
import { generateThumbnailName } from 'util/generate-thumbnail-name';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import classnames from 'classnames';
|
|
||||||
|
|
||||||
const accept = '.png, .jpg, .jpeg, .gif';
|
const accept = '.png, .jpg, .jpeg, .gif';
|
||||||
const SPEECH_READY = 'READY';
|
const SPEECH_READY = 'READY';
|
||||||
|
@ -17,7 +15,7 @@ const SPEECH_UPLOADING = 'UPLOADING';
|
||||||
type Props = {
|
type Props = {
|
||||||
assetName: string,
|
assetName: string,
|
||||||
currentValue: ?string,
|
currentValue: ?string,
|
||||||
onUpdate: (string) => void,
|
onUpdate: (string, boolean) => void,
|
||||||
recommended: string,
|
recommended: string,
|
||||||
title: string,
|
title: string,
|
||||||
onDone?: () => void,
|
onDone?: () => void,
|
||||||
|
@ -25,27 +23,14 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function SelectAsset(props: Props) {
|
function SelectAsset(props: Props) {
|
||||||
const { onUpdate, onDone, assetName, recommended, title, inline } = props;
|
const { onUpdate, onDone, assetName, currentValue, recommended, title, inline } = props;
|
||||||
const [pathSelected, setPathSelected] = React.useState('');
|
const [pathSelected, setPathSelected] = React.useState('');
|
||||||
const [fileSelected, setFileSelected] = React.useState<any>(null);
|
const [fileSelected, setFileSelected] = React.useState<any>(null);
|
||||||
const [uploadStatus, setUploadStatus] = React.useState(SPEECH_READY);
|
const [uploadStatus, setUploadStatus] = React.useState(SPEECH_READY);
|
||||||
const [useUrl, setUseUrl] = usePersistedState('thumbnail-upload:mode', false);
|
const [useUrl, setUseUrl] = usePersistedState('thumbnail-upload:mode', false);
|
||||||
const [url, setUrl] = React.useState('');
|
const [url, setUrl] = React.useState(currentValue);
|
||||||
const [error, setError] = React.useState();
|
const [error, setError] = React.useState();
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (pathSelected && fileSelected) {
|
|
||||||
doUploadAsset();
|
|
||||||
}
|
|
||||||
}, [pathSelected, fileSelected]);
|
|
||||||
|
|
||||||
function handleToggleMode(useUrl) {
|
|
||||||
setPathSelected('');
|
|
||||||
setFileSelected(null);
|
|
||||||
setUrl('');
|
|
||||||
setUseUrl(useUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
function doUploadAsset() {
|
function doUploadAsset() {
|
||||||
const uploadError = (error = '') => {
|
const uploadError = (error = '') => {
|
||||||
setError(error);
|
setError(error);
|
||||||
|
@ -53,7 +38,7 @@ function SelectAsset(props: Props) {
|
||||||
|
|
||||||
const onSuccess = (thumbnailUrl) => {
|
const onSuccess = (thumbnailUrl) => {
|
||||||
setUploadStatus(SPEECH_READY);
|
setUploadStatus(SPEECH_READY);
|
||||||
onUpdate(thumbnailUrl);
|
onUpdate(thumbnailUrl, !useUrl);
|
||||||
|
|
||||||
if (onDone) {
|
if (onDone) {
|
||||||
onDone();
|
onDone();
|
||||||
|
@ -93,30 +78,6 @@ function SelectAsset(props: Props) {
|
||||||
}
|
}
|
||||||
const formBody = (
|
const formBody = (
|
||||||
<>
|
<>
|
||||||
<div className={'section__header--actions'}>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
className={classnames('button-toggle', {
|
|
||||||
'button-toggle--active': useUrl, // disable on upload status
|
|
||||||
})}
|
|
||||||
label={__('URL')}
|
|
||||||
onClick={() => {
|
|
||||||
handleToggleMode(true);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
className={classnames('button-toggle', {
|
|
||||||
'button-toggle--active': !useUrl, // disable on upload status
|
|
||||||
})}
|
|
||||||
label={__('Upload')}
|
|
||||||
onClick={() => {
|
|
||||||
handleToggleMode(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<fieldset-section>
|
<fieldset-section>
|
||||||
{error && <div className="error__text">{error}</div>}
|
{error && <div className="error__text">{error}</div>}
|
||||||
{useUrl ? (
|
{useUrl ? (
|
||||||
|
@ -129,7 +90,7 @@ function SelectAsset(props: Props) {
|
||||||
value={url}
|
value={url}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setUrl(e.target.value);
|
setUrl(e.target.value);
|
||||||
onUpdate(e.target.value);
|
onUpdate(e.target.value, !useUrl);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
@ -151,6 +112,25 @@ function SelectAsset(props: Props) {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</fieldset-section>
|
</fieldset-section>
|
||||||
|
|
||||||
|
<div className="section__actions">
|
||||||
|
{onDone && (
|
||||||
|
<Button
|
||||||
|
button="primary"
|
||||||
|
type="submit"
|
||||||
|
label={__('Done')}
|
||||||
|
disabled={!useUrl && ((uploadStatus === SPEECH_UPLOADING) || !pathSelected || !fileSelected)}
|
||||||
|
onClick={() => doUploadAsset()}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<FormField
|
||||||
|
name="toggle-upload"
|
||||||
|
type="checkbox"
|
||||||
|
label={__('Use a URL')}
|
||||||
|
checked={useUrl}
|
||||||
|
onChange={() => setUseUrl(!useUrl)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,7 @@ class SelectThumbnail extends React.PureComponent<Props> {
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
src={thumbnailSrc}
|
src={thumbnailSrc}
|
||||||
alt={__('Thumbnail Preview')}
|
alt={__('Thumbnail Preview')}
|
||||||
onError={(e) => {
|
onError={() => updatePublishForm({ thumbnailError: true })}
|
||||||
updatePublishForm({ thumbnailError: true });
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="column__item">
|
<div className="column__item">
|
||||||
|
@ -130,12 +128,7 @@ class SelectThumbnail extends React.PureComponent<Props> {
|
||||||
)}
|
)}
|
||||||
{status === THUMBNAIL_STATUSES.COMPLETE && thumbnail && (
|
{status === THUMBNAIL_STATUSES.COMPLETE && thumbnail && (
|
||||||
<div className="column column--space-between">
|
<div className="column column--space-between">
|
||||||
<div
|
<div className="column__item thumbnail-preview" style={{ backgroundImage: `url(${thumbnail})` }} />
|
||||||
className="column__item thumbnail-preview"
|
|
||||||
// style={{ backgroundImage: `url(${thumbnail})` }}
|
|
||||||
>
|
|
||||||
{__('This will be visible in a few minutes.')}
|
|
||||||
</div>
|
|
||||||
<div className="column__item">
|
<div className="column__item">
|
||||||
<p>{__('Upload complete.')}</p>
|
<p>{__('Upload complete.')}</p>
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
|
|
|
@ -13,13 +13,16 @@ type Props = {
|
||||||
class ModalConfirmThumbnailUpload extends React.PureComponent<Props> {
|
class ModalConfirmThumbnailUpload extends React.PureComponent<Props> {
|
||||||
upload() {
|
upload() {
|
||||||
const { upload, updatePublishForm, closeModal, file } = this.props;
|
const { upload, updatePublishForm, closeModal, file } = this.props;
|
||||||
upload(file);
|
if (file) {
|
||||||
updatePublishForm({ thumbnailPath: file.path });
|
upload(file);
|
||||||
closeModal();
|
updatePublishForm({ thumbnailPath: file.path });
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { closeModal, file } = this.props;
|
const { closeModal, file } = this.props;
|
||||||
|
const filePath = file && (file.path || file.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -33,7 +36,7 @@ class ModalConfirmThumbnailUpload extends React.PureComponent<Props> {
|
||||||
>
|
>
|
||||||
<label>{__('Are you sure you want to upload this thumbnail to %domain%', { domain: DOMAIN })}?</label>
|
<label>{__('Are you sure you want to upload this thumbnail to %domain%', { domain: DOMAIN })}?</label>
|
||||||
|
|
||||||
<blockquote>{file.path || file.name}</blockquote>
|
<blockquote>{filePath}</blockquote>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@ import { connect } from 'react-redux';
|
||||||
import { doHideModal } from 'redux/actions/app';
|
import { doHideModal } from 'redux/actions/app';
|
||||||
import ModalImageUpload from './view';
|
import ModalImageUpload from './view';
|
||||||
|
|
||||||
const perform = dispatch => () => ({
|
const perform = dispatch => ({
|
||||||
closeModal: () => {
|
closeModal: () => dispatch(doHideModal()),
|
||||||
dispatch(doHideModal());
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, perform)(ModalImageUpload);
|
export default connect(null, perform)(ModalImageUpload);
|
||||||
|
|
|
@ -8,7 +8,7 @@ type Props = {
|
||||||
currentValue: string,
|
currentValue: string,
|
||||||
title: string,
|
title: string,
|
||||||
helpText: string,
|
helpText: string,
|
||||||
onUpdate: string => void,
|
onUpdate: (string, boolean) => void,
|
||||||
assetName: string,
|
assetName: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ function ModalImageUpload(props: Props) {
|
||||||
return (
|
return (
|
||||||
<Modal isOpen type="card" onAborted={closeModal} contentLabel={title}>
|
<Modal isOpen type="card" onAborted={closeModal} contentLabel={title}>
|
||||||
<SelectAsset
|
<SelectAsset
|
||||||
onUpdate={v => onUpdate(v)}
|
onUpdate={(a, b) => onUpdate(a, b)}
|
||||||
currentValue={currentValue}
|
currentValue={currentValue}
|
||||||
assetName={assetName}
|
assetName={assetName}
|
||||||
recommended={helpText}
|
recommended={helpText}
|
||||||
|
|
|
@ -84,7 +84,7 @@ $actions-z-index: 2;
|
||||||
margin-right: var(--spacing-xs);
|
margin-right: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chanel-thumbnail--waiting {
|
.channel-thumbnail--waiting {
|
||||||
background-color: var(--color-gray-5);
|
background-color: var(--color-gray-5);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
padding-top: 4rem;
|
padding-top: 4rem;
|
||||||
|
|
Loading…
Add table
Reference in a new issue