mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Merge pull request #71 from johndoe6345789/codex/centralize-localstorage-handling
Centralize PWA install prompt state handling
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import { Download, X, DeviceMobile, Desktop } from '@phosphor-icons/react'
|
||||
@@ -6,41 +5,26 @@ import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { usePWA } from '@/hooks/use-pwa'
|
||||
|
||||
export function PWAInstallPrompt() {
|
||||
const { isInstallable, installApp } = usePWA()
|
||||
const [dismissed, setDismissed] = useState(false)
|
||||
const [showPrompt, setShowPrompt] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const hasBeenDismissed = localStorage.getItem('pwa-install-dismissed')
|
||||
if (hasBeenDismissed) {
|
||||
setDismissed(true)
|
||||
}
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
if (isInstallable && !hasBeenDismissed) {
|
||||
setShowPrompt(true)
|
||||
}
|
||||
}, 3000)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [isInstallable])
|
||||
const {
|
||||
isInstallable,
|
||||
isInstallPromptDismissed,
|
||||
isInstallPromptVisible,
|
||||
installApp,
|
||||
dismissInstallPrompt,
|
||||
} = usePWA()
|
||||
|
||||
const handleInstall = async () => {
|
||||
const success = await installApp()
|
||||
if (success) {
|
||||
setShowPrompt(false)
|
||||
}
|
||||
if (success) return
|
||||
}
|
||||
|
||||
const handleDismiss = () => {
|
||||
setShowPrompt(false)
|
||||
setDismissed(true)
|
||||
localStorage.setItem('pwa-install-dismissed', 'true')
|
||||
dismissInstallPrompt()
|
||||
}
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isInstallable && !dismissed && showPrompt && (
|
||||
{isInstallable && !isInstallPromptDismissed && isInstallPromptVisible && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
|
||||
@@ -14,6 +14,8 @@ interface PWAState {
|
||||
}
|
||||
|
||||
export function usePWA() {
|
||||
const [isInstallPromptDismissed, setInstallPromptDismissed] = useState(false)
|
||||
const [isInstallPromptVisible, setInstallPromptVisible] = useState(false)
|
||||
const [state, setState] = useState<PWAState>({
|
||||
isInstallable: false,
|
||||
isInstalled: false,
|
||||
@@ -25,6 +27,10 @@ export function usePWA() {
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') return
|
||||
const storedDismissed = window.localStorage.getItem('pwa-install-dismissed')
|
||||
if (storedDismissed) {
|
||||
setInstallPromptDismissed(true)
|
||||
}
|
||||
|
||||
const checkInstalled = () => {
|
||||
try {
|
||||
@@ -52,6 +58,7 @@ export function usePWA() {
|
||||
const handleAppInstalled = () => {
|
||||
setState(prev => ({ ...prev, isInstalled: true, isInstallable: false }))
|
||||
setDeferredPrompt(null)
|
||||
setInstallPromptVisible(false)
|
||||
}
|
||||
|
||||
const handleOnline = () => {
|
||||
@@ -104,10 +111,24 @@ export function usePWA() {
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!state.isInstallable || state.isInstalled || isInstallPromptDismissed) {
|
||||
setInstallPromptVisible(false)
|
||||
return
|
||||
}
|
||||
|
||||
const timer = window.setTimeout(() => {
|
||||
setInstallPromptVisible(true)
|
||||
}, 3000)
|
||||
|
||||
return () => window.clearTimeout(timer)
|
||||
}, [state.isInstallable, state.isInstalled, isInstallPromptDismissed])
|
||||
|
||||
const installApp = async () => {
|
||||
if (!deferredPrompt) return false
|
||||
|
||||
try {
|
||||
setInstallPromptVisible(false)
|
||||
await deferredPrompt.prompt()
|
||||
const choiceResult = await deferredPrompt.userChoice
|
||||
|
||||
@@ -123,6 +144,14 @@ export function usePWA() {
|
||||
}
|
||||
}
|
||||
|
||||
const dismissInstallPrompt = () => {
|
||||
setInstallPromptDismissed(true)
|
||||
setInstallPromptVisible(false)
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem('pwa-install-dismissed', 'true')
|
||||
}
|
||||
}
|
||||
|
||||
const updateApp = () => {
|
||||
if (state.registration) {
|
||||
state.registration.waiting?.postMessage({ type: 'SKIP_WAITING' })
|
||||
@@ -165,7 +194,10 @@ export function usePWA() {
|
||||
|
||||
return {
|
||||
...state,
|
||||
isInstallPromptDismissed,
|
||||
isInstallPromptVisible,
|
||||
installApp,
|
||||
dismissInstallPrompt,
|
||||
updateApp,
|
||||
clearCache,
|
||||
requestNotificationPermission,
|
||||
|
||||
Reference in New Issue
Block a user