Duffer Derek
// PWA Provider Component - Main integration point for PWA features
"use client";
import React, { useEffect, useState, useRef } from "react";
import { OnboardingManager } from "@/components/onboarding/OnboardingManager";
import { useHealthCheck } from "@/hooks/useHealthCheck";
import { registerServiceWorker } from "@/lib/serviceWorker";
import { registerFirebaseMessagingSW } from "@/lib/firebase";
import {
safeServiceWorkerRegistration,
safeFirebaseMessagingSWRegistration,
isIOSDevice,
debugIOSPWA,
} from "@/lib/iosPWAUtils";
import { useFocusCenter } from "@/contexts/FocusCenterContext";
interface PWAProviderProps {
isLoggedIn: boolean;
children: React.ReactNode;
}
export const PWAProvider: React.FC<PWAProviderProps> = ({ isLoggedIn, children }) => {
const [isServiceWorkerRegistered, setIsServiceWorkerRegistered] = useState(false);
// Get Focus Center refresh function to update data when notifications are clicked
// Note: This component is wrapped by FocusCenterProvider in index.tsx, so context is always available
const { refreshFocusCenter } = useFocusCenter();
// Register service workers on mount with iOS-specific handling
useEffect(() => {
const registerSWs = async () => {
try {
// iOS-specific debug info
if (isIOSDevice()) {
// console.log("iOS device detected, using safe service worker registration");
debugIOSPWA();
}
// Use safe service worker registration for iOS
const mainSWRegistration = isIOSDevice()
? await safeServiceWorkerRegistration()
: await registerServiceWorker();
// Use safe Firebase messaging service worker registration for iOS
const firebaseSWRegistration = isIOSDevice()
? await safeFirebaseMessagingSWRegistration()
: await registerFirebaseMessagingSW();
if (mainSWRegistration && firebaseSWRegistration) {
setIsServiceWorkerRegistered(true);
// console.log("Both service workers registered successfully");
// Dispatch a custom event to notify that service workers are ready
window.dispatchEvent(new CustomEvent("serviceWorkerReady"));
} else if (mainSWRegistration) {
setIsServiceWorkerRegistered(true);
// console.log("Main service worker registered successfully");
window.dispatchEvent(new CustomEvent("serviceWorkerReady"));
} else if (isIOSDevice()) {
// On iOS, continue even if service workers fail
console.warn("iOS: Service worker registration failed, continuing without SW");
setIsServiceWorkerRegistered(true);
window.dispatchEvent(new CustomEvent("serviceWorkerReady"));
}
} catch (error) {
console.error("Failed to register service workers:", error);
// iOS-specific error handling
if (isIOSDevice()) {
console.warn("iOS: Service worker registration failed, continuing without SW");
setIsServiceWorkerRegistered(true);
window.dispatchEvent(new CustomEvent("serviceWorkerReady"));
}
}
};
registerSWs();
}, []);
// Handle silent data refresh when notifications are received
useEffect(() => {
if (!isLoggedIn) return;
// Handle notification received - silently refresh Focus Center data without reloading
const handleNotificationReceived = async () => {
// console.log("🔔 Notification received - silently refreshing Focus Center data");
// Silently refresh Focus Center data - React will automatically update the UI
try {
await refreshFocusCenter();
// console.log("✅ Focus Center data refreshed silently");
} catch (error) {
console.error("Failed to refresh Focus Center data:", error);
}
};
// Listen for messages from service worker (notification clicks and received notifications)
const handleServiceWorkerMessage = (event: MessageEvent) => {
if (event.data && event.data.type === 'NOTIFICATION_RECEIVED') {
handleNotificationReceived();
return;
}
if (event.data && event.data.type === 'NOTIFICATION_CLICK') {
// console.log("🔔 Notification clicked - refreshing Focus Center data and bringing app to foreground");
// Explicitly focus the window to bring app to foreground on mobile
// This is crucial when app is minimized
if (window.focus) {
window.focus();
}
// Also ensure document gets focus
if (document.hasFocus && !document.hasFocus()) {
// Try to focus the window multiple times to ensure it works on mobile
const focusWindow = () => {
window.focus();
if (document.body && typeof document.body.focus === 'function') {
document.body.focus();
}
};
focusWindow();
// Retry focus after a short delay for mobile devices
setTimeout(focusWindow, 50);
}
// Refresh Focus Center data immediately when notification is clicked
// This ensures the new item is available when the user navigates
const refreshData = async () => {
try {
await refreshFocusCenter();
// console.log("✅ Focus Center data refreshed after notification click");
} catch (error) {
console.error("Failed to refresh Focus Center data on notification click:", error);
}
};
// Navigate to URL if provided
const urlToNavigate = event.data.url;
if (urlToNavigate && urlToNavigate !== '/' && urlToNavigate !== window.location.pathname) {
// For navigation, refresh data first, then navigate
refreshData().then(() => {
// Small delay to ensure data is refreshed before navigation
setTimeout(() => {
window.location.href = urlToNavigate;
}, 150);
});
return;
}
// Silently refresh data without reloading - React will update the UI automatically
refreshData();
}
};
// Listen for custom notification received events (for foreground notifications)
const handleNotificationReceivedEvent = () => {
handleNotificationReceived();
};
// Listen for service worker messages
if ('serviceWorker' in navigator && navigator.serviceWorker) {
navigator.serviceWorker.addEventListener('message', handleServiceWorkerMessage);
}
// Listen for custom notification received events (foreground notifications)
window.addEventListener('notificationReceived', handleNotificationReceivedEvent);
return () => {
window.removeEventListener('notificationReceived', handleNotificationReceivedEvent);
if ('serviceWorker' in navigator && navigator.serviceWorker) {
navigator.serviceWorker.removeEventListener('message', handleServiceWorkerMessage);
}
};
}, [isLoggedIn, refreshFocusCenter]);
// Initialize health checks
useHealthCheck(isLoggedIn);
return (
<OnboardingManager isLoggedIn={isLoggedIn} isServiceWorkerReady={isServiceWorkerRegistered}>
{children}
</OnboardingManager>
);
};
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists