(
task: Task | Error,
{
message = 'Bulk actions currently being processed.',
doneMessage = 'Bulk action processing complete.',
}: {
message?: string;
doneMessage?: ToastMessage | false;
} = {},
)
| 20 | type ProgressCallback = (message: string) => void; |
| 21 | type Task = Promise<unknown> | ((progress: ProgressCallback) => Promise<unknown>); |
| 22 | export default async function showToast( |
| 23 | task: Task | Error, |
| 24 | { |
| 25 | message = 'Bulk actions currently being processed.', |
| 26 | doneMessage = 'Bulk action processing complete.', |
| 27 | }: { |
| 28 | message?: string; |
| 29 | doneMessage?: ToastMessage | false; |
| 30 | } = {}, |
| 31 | ): Promise<void> { |
| 32 | const iconWrapper = <span className="Toast-icon"> |
| 33 | <ToastSpinner /> |
| 34 | </span>; |
| 35 | const messageWrapper = <span>{message}</span>; |
| 36 | const toast = ( |
| 37 | <div |
| 38 | role="log" |
| 39 | style={{zIndex: 101}} |
| 40 | className="rgh-toast position-fixed bottom-0 right-0 ml-5 tmp-ml-5 mb-5 tmp-mb-5 Toast Toast--loading Toast--animateIn" |
| 41 | > |
| 42 | {iconWrapper} |
| 43 | <span className="Toast-content py-2 tmp-py-2"> |
| 44 | <div style={{fontSize: '10px', color: 'silver', marginBottom: '-0.3em'}}>Refined GitHub</div> |
| 45 | {messageWrapper} |
| 46 | </span> |
| 47 | </div> |
| 48 | ); |
| 49 | let lastRawMessage: ToastMessage = message; |
| 50 | const updateToast = (newMessage: ToastMessage): void => { |
| 51 | lastRawMessage = newMessage; |
| 52 | messageWrapper.textContent = ''; |
| 53 | messageWrapper.append(newMessage); |
| 54 | }; |
| 55 | |
| 56 | const finalUpdateToast = async (newMessage: ToastMessage | Error): Promise<void> => { |
| 57 | if (newMessage instanceof Error && 'richMessage' in newMessage && newMessage.richMessage) { |
| 58 | newMessage = newMessage.richMessage as ToastMessage; |
| 59 | } else if (newMessage instanceof Error) { |
| 60 | newMessage = newMessage.message; |
| 61 | } |
| 62 | |
| 63 | updateToast(newMessage); |
| 64 | |
| 65 | // Without rAF the toast might be removed before the first page paint |
| 66 | // rAF also allows showToast to resolve as soon as task is done |
| 67 | await frame(); |
| 68 | |
| 69 | const displayTime = (typeof newMessage === 'string' ? newMessage.split(' ').length * 300 : 3000) + 2000; |
| 70 | await delay(displayTime); |
| 71 | |
| 72 | // Display time is over, animate out |
| 73 | toast.classList.replace('Toast--animateIn', 'Toast--animateOut'); |
| 74 | await oneEvent(toast, 'animationend'); |
| 75 | toast.remove(); |
| 76 | }; |
| 77 | |
| 78 | document.body.append(toast); |
| 79 | await delay(30); // Without this, the Toast doesn't appear in time |
no test coverage detected