patx/gitman

(() => {
  const bell = document.querySelector('[data-notification-bell]');
  const count = document.querySelector('[data-notification-count]');
  if (!bell || !count) return;
  let loading = false;
  let checkedAt = 0;
  const refresh = async () => {
    if (loading || document.hidden || Date.now() - checkedAt < 5000) return;
    loading = true;
    try {
      const response = await fetch('/-/notifications/unread', { headers: { Accept: 'application/json' }, cache: 'no-store' });
      if (!response.ok) return;
      const data = await response.json();
      const unread = Number(data.unread_count) || 0;
      const label = data.has_more ? '99+' : String(unread);
      count.textContent = label;
      count.hidden = unread === 0;
      bell.setAttribute('aria-label', unread ? `Notifications (${label} unread)` : 'Notifications');
      checkedAt = Date.now();
    } catch (_) {
      // Keep the last successful count if the connection is interrupted.
    } finally {
      loading = false;
    }
  };
  window.addEventListener('pageshow', (event) => {
    const navigation = performance.getEntriesByType('navigation')[0];
    if (!event.persisted && (!navigation || navigation.type !== 'back_forward')) return;
    if (document.querySelector('[data-notification-feed]')) {
      window.location.reload();
    } else {
      checkedAt = 0;
      refresh();
    }
  });
  refresh();
  setInterval(refresh, 60000);
  window.addEventListener('focus', refresh);
  document.addEventListener('visibilitychange', refresh);
})();