import { useEffect, useState } from 'react'; import { toast } from 'sonner'; // App version - automatically updated during build const APP_VERSION = import.meta.env.VITE_APP_VERSION || 'dev'; const VERSION_CHECK_INTERVAL = 5 * 60 * 1000; // Check every 5 minutes /** * Monitors for new app deployments and prompts user to refresh */ export function useVersionCheck() { const [newVersionAvailable, setNewVersionAvailable] = useState(false); useEffect(() => { // Don't run in development if (import.meta.env.DEV) { return; } const checkVersion = async () => { try { // Fetch the current index.html with cache bypass const response = await fetch('/', { method: 'HEAD', cache: 'no-cache', headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', }, }); // Check ETag or Last-Modified to detect changes const etag = response.headers.get('ETag'); const lastModified = response.headers.get('Last-Modified'); const currentFingerprint = `${etag}-${lastModified}`; const storedFingerprint = sessionStorage.getItem('app-version-fingerprint'); if (storedFingerprint && storedFingerprint !== currentFingerprint) { // New version detected setNewVersionAvailable(true); toast.info('New version available', { description: 'A new version of ThrillWiki is available. Please refresh to update.', duration: 30000, // Show for 30 seconds action: { label: 'Refresh Now', onClick: () => window.location.reload(), }, }); } // Store current fingerprint if (!storedFingerprint) { sessionStorage.setItem('app-version-fingerprint', currentFingerprint); } } catch (error) { // Silently fail - version check is non-critical console.debug('Version check failed:', error); } }; // Initial check after 1 minute (give time for user to settle in) const initialTimer = setTimeout(checkVersion, 60000); // Then check periodically const interval = setInterval(checkVersion, VERSION_CHECK_INTERVAL); return () => { clearTimeout(initialTimer); clearInterval(interval); }; }, []); return { newVersionAvailable }; }