From 1adb1bd52f768c66cae6ba31f849f24a2d5383ba Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Sun, 21 Nov 2021 18:22:22 +0100 Subject: [PATCH] use useInterval hook in ui-notification-toast Signed-off-by: Tilman Vatteroth --- .../notifications/ui-notification-toast.tsx | 72 +++++++------------ 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/src/components/notifications/ui-notification-toast.tsx b/src/components/notifications/ui-notification-toast.tsx index 761eea1eb..230b81757 100644 --- a/src/components/notifications/ui-notification-toast.tsx +++ b/src/components/notifications/ui-notification-toast.tsx @@ -4,16 +4,17 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import React, { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' +import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react' import { Button, ProgressBar, Toast } from 'react-bootstrap' import type { UiNotification } from '../../redux/ui-notifications/types' import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon' import { ShowIf } from '../common/show-if/show-if' import type { IconName } from '../common/fork-awesome/types' -import { dismissUiNotification } from '../../redux/ui-notifications/methods' import { Trans, useTranslation } from 'react-i18next' import { Logger } from '../../utils/logger' import { cypressId } from '../../utils/cypress-attribute' +import { useEffectOnce, useInterval } from 'react-use' +import { dismissUiNotification } from '../../redux/ui-notifications/methods' const STEPS_PER_SECOND = 10 const log = new Logger('UiNotificationToast') @@ -35,56 +36,35 @@ export const UiNotificationToast: React.FC = ({ buttons }) => { const { t } = useTranslation() - const [eta, setEta] = useState() - const interval = useRef(undefined) + const [remainingSteps, setRemainingSteps] = useState(() => durationInSecond * STEPS_PER_SECOND) - const deleteInterval = useCallback(() => { - if (interval.current) { - clearInterval(interval.current) - } - }, []) - - const dismissThisNotification = useCallback(() => { - log.debug(`Dismissed notification ${notificationId}`) - dismissUiNotification(notificationId) + const dismissNow = useCallback(() => { + log.debug(`Dismiss notification ${notificationId} immediately`) + setRemainingSteps(0) }, [notificationId]) - useLayoutEffect(() => { - if (dismissed || !!interval.current) { - return - } + useEffectOnce(() => { log.debug(`Show notification ${notificationId}`) - setEta(durationInSecond * STEPS_PER_SECOND) - interval.current = setInterval( - () => - setEta((lastETA) => { - if (lastETA === undefined) { - return - } else if (lastETA <= 0) { - return 0 - } else { - return lastETA - 1 - } - }), - 1000 / STEPS_PER_SECOND - ) - return () => { - deleteInterval() - } - }, [deleteInterval, dismissThisNotification, dismissed, durationInSecond, notificationId]) + }) + + useInterval( + () => setRemainingSteps((lastRemainingSteps) => lastRemainingSteps - 1), + useMemo(() => (dismissed || remainingSteps <= 0 ? null : 1000 / STEPS_PER_SECOND), [dismissed, remainingSteps]) + ) useEffect(() => { - if (eta === 0) { - dismissThisNotification() + if (remainingSteps <= 0 && !dismissed) { + log.debug(`Dismiss notification ${notificationId}`) + dismissUiNotification(notificationId) } - }, [dismissThisNotification, eta]) + }, [dismissed, remainingSteps, notificationId]) const buttonsDom = useMemo( () => buttons?.map((button, buttonIndex) => { const buttonClick = () => { button.onClick() - dismissThisNotification() + dismissNow() } return ( ) }), - [buttons, dismissThisNotification] + [buttons, dismissNow] ) const contentDom = useMemo(() => { @@ -109,10 +89,7 @@ export const UiNotificationToast: React.FC = ({ }, [contentI18nKey, contentI18nOptions, t]) return ( - + @@ -123,7 +100,12 @@ export const UiNotificationToast: React.FC = ({ {date.toRelative({ style: 'short' })} {contentDom} - +
{buttonsDom}
)