Notifications.jsx (2220B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import React, { useCallback, useEffect } from "react"; 6 import { useSelector } from "react-redux"; 7 import { actionCreators as ac, actionTypes as at } from "common/Actions.mjs"; 8 import { ReportContentToast } from "./Toasts/ReportContentToast"; 9 10 function Notifications({ dispatch }) { 11 const toastQueue = useSelector(state => state.Notifications.toastQueue); 12 const toastCounter = useSelector(state => state.Notifications.toastCounter); 13 14 /** 15 * Syncs {@link toastQueue} array so it can be used to 16 * remove the toasts wrapper if there are none after a 17 * toast is auto-hidden (animated out) via CSS. 18 */ 19 const syncHiddenToastData = useCallback(() => { 20 const toastId = toastQueue[toastQueue.length - 1]; 21 const queuedToasts = [...toastQueue].slice(1); 22 dispatch( 23 ac.OnlyToOneContent( 24 { 25 type: at.HIDE_TOAST_MESSAGE, 26 data: { 27 toastQueue: queuedToasts, 28 toastCounter: queuedToasts.length, 29 toastId, 30 showNotifications: false, 31 }, 32 }, 33 "ActivityStream:Content" 34 ) 35 ); 36 }, [dispatch, toastQueue]); 37 38 const getToast = useCallback(() => { 39 // Note: This architecture could expand to support multiple toast notifications at once 40 const latestToastItem = toastQueue[toastQueue.length - 1]; 41 42 if (!latestToastItem) { 43 throw new Error("No toast found"); 44 } 45 46 switch (latestToastItem) { 47 case "reportSuccessToast": 48 return ( 49 <ReportContentToast 50 onDismissClick={syncHiddenToastData} 51 onAnimationEnd={syncHiddenToastData} 52 key={toastCounter} 53 /> 54 ); 55 default: 56 throw new Error(`Unexpected toast type: ${latestToastItem}`); 57 } 58 }, [syncHiddenToastData, toastCounter, toastQueue]); 59 60 useEffect(() => { 61 getToast(); 62 }, [toastQueue, getToast]); 63 64 return toastQueue.length ? ( 65 <div className="notification-wrapper">{getToast()}</div> 66 ) : ( 67 "" 68 ); 69 } 70 71 export { Notifications };