function useDebouncedNotifications()

in packages/api/src/hooks/useDebouncedNotifications.ts [26:87]


function useDebouncedNotifications(): [DebouncedNotifications] {
  const now = Date.now();

  const [{ notificationDebounceTimeout }] = useStyleOptions();
  const [notifications] = useNotifications();
  const debouncedNotificationsRef = useRef({});
  const forceRender = useForceRender();

  // Delete notifications or mark them to be deleted if debouncing.
  for (const id of Object.keys(debouncedNotificationsRef.current).filter(id => !(id in notifications))) {
    debouncedNotificationsRef.current = updateIn(debouncedNotificationsRef.current, [id], debouncedNotification => {
      if (now < debouncedNotification.updateNotBefore) {
        // The update need to be postponed.
        return { ...debouncedNotification, outOfDate: true };
      }

      // Otherwise, return undefined will remove it.
    });
  }

  // For any changes, update notifications or mark them to be updated if debouncing.
  for (const [, { alt, data, id, level, message, timestamp }] of Object.entries(notifications)) {
    debouncedNotificationsRef.current = updateIn(debouncedNotificationsRef.current, [id], debouncedNotification => {
      if (
        debouncedNotification &&
        alt === debouncedNotification.alt &&
        Object.is(data, debouncedNotification.data) &&
        level === debouncedNotification.level &&
        message === debouncedNotification.message &&
        timestamp === debouncedNotification.timestamp
      ) {
        // If nothing changed, return as-is.
        return debouncedNotification;
      }

      if (debouncedNotification && now < debouncedNotification.updateNotBefore) {
        // The update need to be postponed.
        return {
          ...debouncedNotification,
          outOfDate: true
        };
      }

      // Update the notification.
      return {
        ...debouncedNotification,
        alt,
        data,
        id,
        level,
        message,
        outOfDate: false,
        timestamp,
        updateNotBefore: now + notificationDebounceTimeout
      };
    });
  }

  useTimer(getEarliestUpdateNotBefore(debouncedNotificationsRef.current), forceRender);

  return [debouncedNotificationsRef.current];
}