diff --git a/components/settings/__tests__/notification-settings.test.tsx b/components/settings/__tests__/notification-settings.test.tsx
index a9db650ba..b6047870d 100644
--- a/components/settings/__tests__/notification-settings.test.tsx
+++ b/components/settings/__tests__/notification-settings.test.tsx
@@ -103,6 +103,20 @@ describe('NotificationSettings - pushNotifyInboxOnly', () => {
);
});
+ it('checks push again when the user comes back to the tab', async () => {
+ Object.defineProperty(document, 'visibilityState', { value: 'visible', configurable: true });
+ const { findByText } = render();
+ await findByText('email.inbox_only');
+ const check = webPush.isWebPushEnabled as ReturnType;
+ await waitFor(() => expect(check).toHaveBeenCalled());
+ const before = check.mock.calls.length;
+
+ // Push may have been turned off elsewhere (site settings, another tab) meanwhile.
+ await act(async () => { window.dispatchEvent(new Event('focus')); });
+
+ await waitFor(() => expect(check.mock.calls.length).toBeGreaterThan(before));
+ });
+
it('does not re-sync when push is disabled on this device', async () => {
(webPush.isWebPushEnabled as ReturnType).mockResolvedValueOnce(false);
render();
diff --git a/components/settings/notification-settings.tsx b/components/settings/notification-settings.tsx
index a7a63ab82..2ab9c809b 100644
--- a/components/settings/notification-settings.tsx
+++ b/components/settings/notification-settings.tsx
@@ -80,16 +80,37 @@ export function NotificationSettings() {
const activeRelayLabel =
relayOptions.find((option) => option.url === activeRelayUrl)?.label ?? activeRelayUrl;
+ const busy = pushStatus.kind === 'busy';
+
useEffect(() => {
if (!supported) return;
if (!client) return;
const accountId = client.getAccountId();
if (!accountId) return;
- void (async () => {
- const enabled = await isWebPushEnabled(accountId);
- setPushStatus(enabled ? { kind: 'enabled' } : { kind: 'idle' });
- })();
- }, [supported, client]);
+ let cancelled = false;
+ const refreshStatus = async () => {
+ try {
+ const enabled = await isWebPushEnabled(accountId);
+ if (!cancelled) {
+ setPushStatus(enabled ? { kind: 'enabled' } : { kind: 'idle' });
+ }
+ } catch {
+ if (!cancelled) setPushStatus({ kind: 'idle' });
+ }
+ };
+ const onVisible = () => {
+ if (document.visibilityState === 'visible') void refreshStatus();
+ };
+ if (pushStatus.kind === 'busy' || pushStatus.kind === 'error') return;
+ void refreshStatus();
+ window.addEventListener('focus', onVisible);
+ document.addEventListener('visibilitychange', onVisible);
+ return () => {
+ cancelled = true;
+ window.removeEventListener('focus', onVisible);
+ document.removeEventListener('visibilitychange', onVisible);
+ };
+ }, [supported, client, pushStatus.kind]);
// The device list is worth loading even when push is off on this browser -
// revoking a stale registration left on another device is exactly what you
@@ -108,7 +129,6 @@ export function NotificationSettings() {
void refreshDevices();
}, [refreshDevices]);
- const busy = pushStatus.kind === 'busy';
const pushEnabled = pushStatus.kind === 'enabled';
// In the static Lite build push is off by design (no service worker, see
// components/service-worker-registration.tsx), not a browser limitation.