export const usePWA = () => { const isInstalled = ref(false); const isInstallable = ref(false); const deferredPrompt = ref(null); // Check if app is installed (running in standalone mode) const checkInstallStatus = () => { if (process.client) { isInstalled.value = window.matchMedia('(display-mode: standalone)').matches || (window.navigator as any).standalone || document.referrer.includes('android-app://'); } }; // Check if device is mobile const isMobile = computed(() => { if (process.client) { return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); } return false; }); // Check if device is iOS const isIOS = computed(() => { if (process.client) { return /iPad|iPhone|iPod/.test(navigator.userAgent); } return false; }); // Check if device is Android const isAndroid = computed(() => { if (process.client) { return /Android/i.test(navigator.userAgent); } return false; }); // Install the app const install = async () => { if (deferredPrompt.value) { deferredPrompt.value.prompt(); const choiceResult = await deferredPrompt.value.userChoice; if (choiceResult.outcome === 'accepted') { console.log('User accepted the install prompt'); deferredPrompt.value = null; isInstallable.value = false; return true; } else { console.log('User dismissed the install prompt'); return false; } } return false; }; // Check if app can be installed const canInstall = computed(() => { return isMobile.value && !isInstalled.value && (isInstallable.value || isIOS.value); }); // Initialize PWA functionality const init = () => { if (process.client) { checkInstallStatus(); // Listen for the beforeinstallprompt event window.addEventListener('beforeinstallprompt', (e) => { console.log('beforeinstallprompt event fired'); e.preventDefault(); deferredPrompt.value = e; isInstallable.value = true; }); // Listen for successful app installation window.addEventListener('appinstalled', () => { console.log('PWA was installed'); isInstalled.value = true; isInstallable.value = false; deferredPrompt.value = null; }); // Listen for display mode changes window.matchMedia('(display-mode: standalone)').addEventListener('change', (e) => { isInstalled.value = e.matches; }); } }; return { isInstalled: readonly(isInstalled), isInstallable: readonly(isInstallable), isMobile, isIOS, isAndroid, canInstall, install, init }; };