/* * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' import { Button, ProgressBar, Toast } from 'react-bootstrap' import { UiNotification } from '../../redux/ui-notifications/types' import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon' import { ShowIf } from '../common/show-if/show-if' import { IconName } from '../common/fork-awesome/types' import { dismissUiNotification } from '../../redux/ui-notifications/methods' const STEPS_PER_SECOND = 10 export interface UiNotificationProps extends UiNotification { notificationId: number } export const UiNotificationToast: React.FC = ({ title, content, date, icon, dismissed, notificationId, durationInSecond, buttons }) => { const [eta, setEta] = useState() const interval = useRef(undefined) const deleteInterval = useCallback(() => { if (interval.current) { clearInterval(interval.current) } }, []) const dismissThisNotification = useCallback(() => { console.debug(`[Notifications] Dismissed notification ${ notificationId }`) dismissUiNotification(notificationId) }, [notificationId]) useLayoutEffect(() => { if (dismissed || !!interval.current) { return } console.debug(`[Notifications] 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]) useEffect(() => { if (eta === 0) { dismissThisNotification() } }, [dismissThisNotification, eta]) const buttonsDom = useMemo(() => buttons?.map(button => { const buttonClick = () => { button.onClick() dismissThisNotification() } return } ), [buttons, dismissThisNotification]) return ( { title } { date.toRelative({ style: 'short' }) } { content }
{ buttonsDom }
) }