Duffer Derek

Current Path : /var/www/sitesecurity.bitkit.dk/httpdocs/src/components/pwa/
Upload File :
Current File : /var/www/sitesecurity.bitkit.dk/httpdocs/src/components/pwa/PWAProvider.tsx

// 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