mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Improve PWA permission and cache handling
This commit is contained in:
@@ -24,19 +24,80 @@ export function PWASettings() {
|
||||
registration
|
||||
} = usePWA()
|
||||
|
||||
const [notificationPermission, setNotificationPermission] = useState<NotificationPermission>('default')
|
||||
const [notificationPermission, setNotificationPermission] = useState<NotificationPermission | 'unsupported'>(
|
||||
'default'
|
||||
)
|
||||
const [cacheSize, setCacheSize] = useState<string>(pwaSettingsCopy.defaults.cacheCalculating)
|
||||
|
||||
useEffect(() => {
|
||||
if ('Notification' in window) {
|
||||
setNotificationPermission(Notification.permission)
|
||||
let isMounted = true
|
||||
let permissionStatus: PermissionStatus | null = null
|
||||
let handlePermissionChange: (() => void) | null = null
|
||||
|
||||
const setPermissionState = (state: PermissionState | NotificationPermission | 'unsupported') => {
|
||||
if (!isMounted) return
|
||||
if (state === 'prompt') {
|
||||
setNotificationPermission('default')
|
||||
return
|
||||
}
|
||||
if (state === 'granted' || state === 'denied' || state === 'default' || state === 'unsupported') {
|
||||
setNotificationPermission(state)
|
||||
}
|
||||
}
|
||||
|
||||
if ('storage' in navigator && 'estimate' in navigator.storage) {
|
||||
navigator.storage.estimate().then((estimate) => {
|
||||
const usageInMB = ((estimate.usage || 0) / (1024 * 1024)).toFixed(2)
|
||||
const updatePermission = async () => {
|
||||
if (!('Notification' in window)) {
|
||||
setPermissionState('unsupported')
|
||||
return
|
||||
}
|
||||
|
||||
setPermissionState(Notification.permission)
|
||||
|
||||
if ('permissions' in navigator && 'query' in navigator.permissions) {
|
||||
try {
|
||||
permissionStatus = await navigator.permissions.query({ name: 'notifications' })
|
||||
handlePermissionChange = () => setPermissionState(permissionStatus?.state ?? 'default')
|
||||
permissionStatus.addEventListener('change', handlePermissionChange)
|
||||
handlePermissionChange()
|
||||
} catch (error) {
|
||||
console.error('[PWA] Notification permission query failed:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateCacheSize = async () => {
|
||||
if (!('storage' in navigator && 'estimate' in navigator.storage)) {
|
||||
if (isMounted) {
|
||||
setCacheSize(pwaSettingsCopy.defaults.cacheUnavailable)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const estimate = await navigator.storage.estimate()
|
||||
const usage = estimate.usage
|
||||
if (typeof usage !== 'number') {
|
||||
setCacheSize(pwaSettingsCopy.defaults.cacheUnavailable)
|
||||
return
|
||||
}
|
||||
const usageInMB = (usage / (1024 * 1024)).toFixed(2)
|
||||
setCacheSize(`${usageInMB} ${pwaSettingsCopy.cache.storageUnit}`)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[PWA] Storage estimate failed:', error)
|
||||
if (isMounted) {
|
||||
setCacheSize(pwaSettingsCopy.defaults.cacheUnavailable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatePermission()
|
||||
updateCacheSize()
|
||||
|
||||
return () => {
|
||||
isMounted = false
|
||||
if (permissionStatus && handlePermissionChange) {
|
||||
permissionStatus.removeEventListener('change', handlePermissionChange)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
@@ -60,15 +121,17 @@ export function PWASettings() {
|
||||
}
|
||||
|
||||
const handleNotificationToggle = async (enabled: boolean) => {
|
||||
if (enabled) {
|
||||
const permission = await requestNotificationPermission()
|
||||
setNotificationPermission(permission as NotificationPermission)
|
||||
if (!enabled || notificationPermission === 'unsupported') {
|
||||
return
|
||||
}
|
||||
|
||||
if (permission === 'granted') {
|
||||
toast.success(pwaSettingsCopy.toasts.notificationsEnabled)
|
||||
} else {
|
||||
toast.error(pwaSettingsCopy.toasts.notificationsDenied)
|
||||
}
|
||||
const permission = await requestNotificationPermission()
|
||||
setNotificationPermission(permission)
|
||||
|
||||
if (permission === 'granted') {
|
||||
toast.success(pwaSettingsCopy.toasts.notificationsEnabled)
|
||||
} else {
|
||||
toast.error(pwaSettingsCopy.toasts.notificationsDenied)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Switch } from '@/components/ui/switch'
|
||||
import { Bell, CheckCircle, Question, XCircle } from '@phosphor-icons/react'
|
||||
|
||||
interface NotificationsSectionProps {
|
||||
permission: NotificationPermission
|
||||
permission: NotificationPermission | 'unsupported'
|
||||
onToggle: (enabled: boolean) => void
|
||||
copy: {
|
||||
title: string
|
||||
@@ -12,6 +12,7 @@ interface NotificationsSectionProps {
|
||||
label: string
|
||||
permissionLabel: string
|
||||
blocked: string
|
||||
unsupported: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +23,8 @@ export function NotificationsSection({ permission, onToggle, copy }: Notificatio
|
||||
return <CheckCircle size={16} className="text-accent" weight="fill" />
|
||||
case 'denied':
|
||||
return <XCircle size={16} className="text-destructive" weight="fill" />
|
||||
case 'unsupported':
|
||||
return <XCircle size={16} className="text-muted-foreground" weight="fill" />
|
||||
default:
|
||||
return <Question size={16} className="text-muted-foreground" weight="fill" />
|
||||
}
|
||||
@@ -51,7 +54,7 @@ export function NotificationsSection({ permission, onToggle, copy }: Notificatio
|
||||
<Switch
|
||||
checked={permission === 'granted'}
|
||||
onCheckedChange={onToggle}
|
||||
disabled={permission === 'denied'}
|
||||
disabled={permission === 'denied' || permission === 'unsupported'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -60,6 +63,12 @@ export function NotificationsSection({ permission, onToggle, copy }: Notificatio
|
||||
{copy.blocked}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{permission === 'unsupported' && (
|
||||
<div className="text-xs text-muted-foreground bg-muted/50 p-3 rounded-md">
|
||||
{copy.unsupported}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
"description": "Receive updates about your projects and builds",
|
||||
"label": "Push Notifications",
|
||||
"permissionLabel": "Permission:",
|
||||
"blocked": "Notifications are blocked. Please enable them in your browser settings."
|
||||
"blocked": "Notifications are blocked. Please enable them in your browser settings.",
|
||||
"unsupported": "Notifications aren't supported in this browser."
|
||||
},
|
||||
"cache": {
|
||||
"title": "Cache Management",
|
||||
@@ -84,6 +85,7 @@
|
||||
"notificationsDenied": "Notification permission denied"
|
||||
},
|
||||
"defaults": {
|
||||
"cacheCalculating": "Calculating..."
|
||||
"cacheCalculating": "Calculating...",
|
||||
"cacheUnavailable": "Unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ export function usePWA() {
|
||||
}
|
||||
}
|
||||
|
||||
const requestNotificationPermission = async () => {
|
||||
const requestNotificationPermission = async (): Promise<NotificationPermission | 'unsupported'> => {
|
||||
if (!('Notification' in window)) {
|
||||
return 'unsupported'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user