Add toast for sticker creator for invalid file formats
This commit is contained in:
parent
cb4fac7bb4
commit
80fb55fed0
@ -308,6 +308,10 @@
|
||||
"message": "Link copied",
|
||||
"description": "Text for the toast when a link for sharing is copied from the Sticker Creator"
|
||||
},
|
||||
"StickerCreator--Toasts--unsupportedFormat": {
|
||||
"message": "Can’t add this image because the format is not supported",
|
||||
"description": "Text for the toast when an image cannot be processed because it uses an unsupported file format"
|
||||
},
|
||||
"StickerCreator--StickerPreview--light": {
|
||||
"message": "My sticker in light theme",
|
||||
"description": "Text for the sticker preview for the light theme"
|
||||
|
||||
@ -38,7 +38,7 @@ export type OnPickEmojiOptions = Readonly<{
|
||||
emoji: EmojiData;
|
||||
}>;
|
||||
|
||||
export type Props = Partial<Pick<DropZoneProps, 'onDrop'>> &
|
||||
export type Props = Partial<Pick<DropZoneProps, 'onDrop' | 'onDropRejected'>> &
|
||||
Readonly<{
|
||||
artType: ArtType;
|
||||
id?: string;
|
||||
@ -65,6 +65,7 @@ export const ArtFrame = memo(function ArtFrame({
|
||||
onRemove,
|
||||
onPickEmoji,
|
||||
onDrop,
|
||||
onDropRejected,
|
||||
}: Props) {
|
||||
const i18n = useI18n();
|
||||
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false);
|
||||
@ -187,10 +188,11 @@ export const ArtFrame = memo(function ArtFrame({
|
||||
onMouseLeave={handleMouseEnter}
|
||||
/>
|
||||
) : null}
|
||||
{mode === 'add' && onDrop ? (
|
||||
{mode === 'add' && onDrop && onDropRejected ? (
|
||||
<DropZone
|
||||
label={i18n(`StickerCreator--DropStage--dragDrop--${artType}`)}
|
||||
onDrop={onDrop}
|
||||
onDropRejected={onDropRejected}
|
||||
inner
|
||||
onDragActive={setDragActive}
|
||||
/>
|
||||
|
||||
@ -124,12 +124,17 @@ export function ArtGrid({ mode, showGuide }: Props): JSX.Element {
|
||||
[dispatch, artType]
|
||||
);
|
||||
|
||||
const handleDropRejected = useCallback(() => {
|
||||
dispatch(addToast({ key: 'StickerCreator--Toasts--unsupportedFormat' }));
|
||||
}, [dispatch]);
|
||||
|
||||
if (list.length === 0) {
|
||||
return (
|
||||
<div className={styles.drop}>
|
||||
<DropZone
|
||||
label={i18n('StickerCreator--DropStage--dragDrop')}
|
||||
onDrop={handleDrop}
|
||||
onDropRejected={handleDropRejected}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -144,6 +149,7 @@ export function ArtGrid({ mode, showGuide }: Props): JSX.Element {
|
||||
showGuide={showGuide}
|
||||
mode="add"
|
||||
onDrop={handleDrop}
|
||||
onDropRejected={handleDropRejected}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -11,8 +11,9 @@ import { useStickerDropzone } from '../util/useStickerDropzone';
|
||||
export type Props = {
|
||||
readonly inner?: boolean;
|
||||
readonly label: string;
|
||||
onDrop(files: ReadonlyArray<File>): unknown;
|
||||
onDragActive?(active: boolean): unknown;
|
||||
onDrop: (files: ReadonlyArray<File>) => void;
|
||||
onDragActive?: (active: boolean) => void;
|
||||
onDropRejected: () => void;
|
||||
};
|
||||
|
||||
const getClassName = ({ inner }: Props, isDragActive: boolean) => {
|
||||
@ -28,7 +29,7 @@ const getClassName = ({ inner }: Props, isDragActive: boolean) => {
|
||||
};
|
||||
|
||||
export function DropZone(props: Props): JSX.Element {
|
||||
const { inner, label, onDrop, onDragActive } = props;
|
||||
const { inner, label, onDrop, onDragActive, onDropRejected } = props;
|
||||
const i18n = useI18n();
|
||||
|
||||
const handleDrop = useCallback(
|
||||
@ -40,8 +41,10 @@ export function DropZone(props: Props): JSX.Element {
|
||||
[onDrop]
|
||||
);
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } =
|
||||
useStickerDropzone(handleDrop);
|
||||
const { getRootProps, getInputProps, isDragActive } = useStickerDropzone(
|
||||
handleDrop,
|
||||
onDropRejected
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (onDragActive) {
|
||||
|
||||
@ -11,7 +11,13 @@ import { useStickerDropzone } from '../../util/useStickerDropzone';
|
||||
import { H2, Text } from '../../elements/Typography';
|
||||
import { LabeledInput } from '../../elements/LabeledInput';
|
||||
import { ConfirmModal } from '../../components/ConfirmModal';
|
||||
import { setCover, removeImage, setTitle, setAuthor } from '../../slices/art';
|
||||
import {
|
||||
setCover,
|
||||
removeImage,
|
||||
setTitle,
|
||||
setAuthor,
|
||||
addToast,
|
||||
} from '../../slices/art';
|
||||
import {
|
||||
useArtType,
|
||||
useAllDataValid,
|
||||
@ -47,8 +53,14 @@ export function MetaStage(): JSX.Element {
|
||||
[dispatch, artType]
|
||||
);
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } =
|
||||
useStickerDropzone(onDrop);
|
||||
const onDropRejected = useCallback(() => {
|
||||
dispatch(addToast({ key: 'StickerCreator--Toasts--errorProcessing' }));
|
||||
}, [dispatch]);
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useStickerDropzone(
|
||||
onDrop,
|
||||
onDropRejected
|
||||
);
|
||||
|
||||
const onNext = useCallback(() => {
|
||||
setConfirming(true);
|
||||
|
||||
@ -5,10 +5,12 @@ import type { DropzoneOptions } from 'react-dropzone';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
|
||||
export const useStickerDropzone = (
|
||||
onDrop: DropzoneOptions['onDrop']
|
||||
onDrop: NonNullable<DropzoneOptions['onDrop']>,
|
||||
onDropRejected: NonNullable<DropzoneOptions['onDropRejected']>
|
||||
): ReturnType<typeof useDropzone> =>
|
||||
useDropzone({
|
||||
onDrop,
|
||||
onDropRejected,
|
||||
accept: {
|
||||
'image/png': ['.png'],
|
||||
'image/webp': ['.webp'],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user