Sticker Creator: New toaster implementation, better error handling

This commit is contained in:
Ken Powers
2020-01-06 21:20:16 -05:00
committed by Scott Nonnenberg
parent 4b3d63c82e
commit f7568810ea
11 changed files with 167 additions and 90 deletions
+7 -2
View File
@@ -51,8 +51,13 @@ const InnerGrid = SortableContainer(
actions.initializeStickers(paths);
paths.forEach(path => {
queue.add(async () => {
const webp = await convertToWebp(path);
actions.addWebp(webp);
try {
const webp = await convertToWebp(path);
actions.addWebp(webp);
} catch (e) {
actions.removeSticker(path);
actions.addToast('StickerCreator--Toasts--errorProcessing');
}
});
});
},
@@ -0,0 +1,31 @@
import * as React from 'react';
import { debounce, dropRight } from 'lodash';
import { StoryRow } from '../elements/StoryRow';
import { Toaster } from './Toaster';
import { storiesOf } from '@storybook/react';
import { text as textKnob } from '@storybook/addon-knobs';
storiesOf('Sticker Creator/components', module).add('Toaster', () => {
const inputText = textKnob('Slices', ['error 1', 'error 2'].join('|'));
const initialState = React.useMemo(() => inputText.split('|'), [inputText]);
const [state, setState] = React.useState(initialState);
const handleDismiss = React.useCallback(
// Debounce is required here since auto-dismiss is asynchronously called
// from multiple rendered instances (multiple themes)
debounce(() => {
setState(dropRight);
}, 10),
[setState]
);
return (
<StoryRow>
<Toaster
loaf={state.map((text, id) => ({ id, text }))}
onDismiss={handleDismiss}
/>
</StoryRow>
);
});
+43
View File
@@ -0,0 +1,43 @@
import * as React from 'react';
import { last, noop } from 'lodash';
import { Toast } from '../elements/Toast';
export type Props = React.HTMLProps<HTMLDivElement> & {
loaf: Array<{ id: number; text: string }>;
onDismiss: () => unknown;
};
const DEFAULT_DISMISS = 1e4;
export const Toaster = React.memo(({ loaf, onDismiss, className }: Props) => {
const slice = last(loaf);
React.useEffect(
() => {
if (!slice) {
return noop;
}
const timer = setTimeout(() => {
onDismiss();
}, DEFAULT_DISMISS);
return () => {
clearTimeout(timer);
};
},
[slice, onDismiss]
);
if (!slice) {
return null;
}
return (
<div className={className}>
<Toast key={slice.id} onClick={onDismiss} tabIndex={0}>
{slice.text}
</Toast>
</div>
);
});