Add toast for sticker creator for invalid file formats

This commit is contained in:
Jamie 2026-06-17 11:51:16 -07:00 committed by GitHub
parent cb4fac7bb4
commit 80fb55fed0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 40 additions and 11 deletions

View File

@ -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": "Cant 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"

View File

@ -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}
/>

View File

@ -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}
/>
);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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'],