Files
maternal-app/maternal-web/store/middleware/offlineMiddleware.ts
Andrei 846710d80c
Some checks failed
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled
fix: Make network detection more lenient for reverse proxy environments
Changed network detection to only mark as offline on actual network errors,
not on HTTP errors like 404. This fixes the issue where the app shows
'You are offline' even when connected, which happens when accessing through
a reverse proxy where the /api/health endpoint might not be properly routed.

Now the app will show as online as long as it can reach the server
(any HTTP response), and only show offline on true connection failures.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-01 19:51:56 +00:00

91 lines
2.6 KiB
TypeScript

import { Middleware } from '@reduxjs/toolkit';
import { RootState } from '../store';
import { setOnlineStatus } from '../slices/networkSlice';
import { addPendingAction, removePendingAction, incrementRetryCount } from '../slices/offlineSlice';
/**
* Offline middleware - intercepts actions and queues them when offline
*/
export const offlineMiddleware: Middleware<{}, RootState> = (store) => (next) => (action: any) => {
const state = store.getState();
const isOnline = state.network?.isOnline ?? true;
// Check if this is an async action that should be queued
const isOfflineableAction =
action.type?.includes('/create') ||
action.type?.includes('/update') ||
action.type?.includes('/delete');
// If offline and action should be queued
if (!isOnline && isOfflineableAction && action.meta?.requestId) {
console.log('[Offline Middleware] Queuing action:', action.type);
// Queue the action
store.dispatch(
addPendingAction({
type: action.type,
payload: action.payload,
})
);
// Still process the optimistic update
return next(action);
}
// If online, process normally
return next(action);
};
/**
* Network status detector - listens for online/offline events
*/
export const setupNetworkDetection = (dispatch: any) => {
if (typeof window === 'undefined') return;
const handleOnline = () => {
console.log('[Network] Connection restored');
dispatch(setOnlineStatus(true));
};
const handleOffline = () => {
console.log('[Network] Connection lost');
dispatch(setOnlineStatus(false));
};
// Listen to browser online/offline events
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
// Periodic connectivity check
const checkConnectivity = async () => {
try {
const startTime = Date.now();
const response = await fetch('/api/health', {
method: 'HEAD',
cache: 'no-cache',
});
const latency = Date.now() - startTime;
// Consider online if we got ANY response (even 404)
// Only mark offline on actual network errors
dispatch(setOnlineStatus(true));
} catch (error) {
// Only network errors (no connection) should mark as offline
dispatch(setOnlineStatus(false));
}
};
// Check connectivity every 30 seconds
const intervalId = setInterval(checkConnectivity, 30000);
// Initial check
checkConnectivity();
// Cleanup function
return () => {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
clearInterval(intervalId);
};
};