diff --git a/components/modal.js b/components/modal.js index 7ae025c5..68d52acb 100644 --- a/components/modal.js +++ b/components/modal.js @@ -35,19 +35,20 @@ export default function useModal () { setModalStack(modalStack.slice(0, -1)) modalOptions?.onClose?.() return setModalContent(previousModalContent) - }, [modalStack, setModalStack]) + }, [modalStack, setModalStack, modalOptions?.onClose]) + // this is called on every navigation due to below useEffect const onClose = useCallback(() => { setModalContent(null) - setModalStack([]) + setModalStack(ms => ms.length > 0 ? [] : ms) modalOptions?.onClose?.() - }, [modalOptions?.onClose]) + }, [setModalStack, setModalContent, modalOptions?.onClose]) const router = useRouter() useEffect(() => { router.events.on('routeChangeStart', onClose) return () => router.events.off('routeChangeStart', onClose) - }, [router, onClose]) + }, [router.events, onClose]) const modal = useMemo(() => { if (modalContent === null) { @@ -76,7 +77,7 @@ export default function useModal () { ) - }, [modalContent, onClose]) + }, [modalContent, onClose, modalOptions, onBack, modalStack]) const showModal = useCallback( (getContent, options) => { diff --git a/components/notifications.js b/components/notifications.js index 01f50408..5e251b1f 100644 --- a/components/notifications.js +++ b/components/notifications.js @@ -531,7 +531,7 @@ export default function Notifications ({ ssrData }) { } }, router.asPath, { ...router.options, shallow: true }) } - }, [router, lastChecked]) + }, [router?.query?.checkedAt, lastChecked]) if (!dat) return @@ -540,7 +540,7 @@ export default function Notifications ({ ssrData }) { {notifications.map(n => new Date(router?.query?.checkedAt)} + fresh={new Date(n.sortTime) > new Date(router?.query?.checkedAt ?? lastChecked)} />)} diff --git a/components/toast.js b/components/toast.js index bb3d1cfe..525ec9ee 100644 --- a/components/toast.js +++ b/components/toast.js @@ -36,16 +36,6 @@ export const ToastProvider = ({ children }) => { const [toasts, setToasts] = useState([]) const toastId = useRef(0) - const dispatchToast = useCallback((toast) => { - toast = { - ...toast, - createdAt: +new Date(), - id: toastId.current++ - } - setToasts(toasts => ensureFlow(toasts, toast).map(mapHidden(toast))) - return () => removeToast(toast) - }, []) - const removeToast = useCallback(({ id, onCancel, tag }) => { setToasts(toasts => toasts.filter(toast => { if (toast.id === id) { @@ -65,11 +55,21 @@ export const ToastProvider = ({ children }) => { // remove toasts with same tag if they are not cancelable return false })) - }, []) + }, [setToasts]) + + const dispatchToast = useCallback((toast) => { + toast = { + ...toast, + createdAt: +new Date(), + id: toastId.current++ + } + setToasts(toasts => ensureFlow(toasts, toast).map(mapHidden(toast))) + return () => removeToast(toast) + }, [setToasts, removeToast]) const endFlow = useCallback((flowId) => { setToasts(toasts => toasts.filter(toast => toast.flowId !== flowId)) - }, []) + }, [setToasts]) const toaster = useMemo(() => ({ success: (body, options) => { @@ -110,13 +110,13 @@ export const ToastProvider = ({ children }) => { // Only clear toasts with no cancel function on page navigation // since navigation should not interfere with being able to cancel an action. useEffect(() => { - const handleRouteChangeStart = () => setToasts(toasts => toasts.filter(({ onCancel, onUndo }) => onCancel || onUndo), []) + const handleRouteChangeStart = () => setToasts(toasts => toasts.length > 0 ? toasts.filter(({ onCancel, onUndo }) => onCancel || onUndo) : toasts) router.events.on('routeChangeStart', handleRouteChangeStart) return () => { router.events.off('routeChangeStart', handleRouteChangeStart) } - }, [router]) + }, [router.events, setToasts]) // this function merges toasts with the same tag into one toast. // for example: 3x 'zap pending' -> '(3) zap pending'