Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 1x 1x 4x 4x 4x 4x 4x 4x 4x 1x 12x 12x 6x 6x 6x 6x 6x 6x 6x 6x 12x 12x 12x 1x 12x 12x | 'use client'
import {useEffect, useState} from 'react'
import {registerServiceWorker, watchInstallOffer} from './pwa'
/** Once per page load: the service worker and the browser's install offer. */
export default function PwaSetup() {
useEffect(() => {
watchInstallOffer()
registerServiceWorker()
}, [])
return null
}
/** True while the device has no network (pages come from the saved copy). */
export function useOffline() {
const [offline, setOffline] = useState(false)
useEffect(() => {
const update = () => setOffline(!navigator.onLine)
update()
window.addEventListener('online', update)
window.addEventListener('offline', update)
return () => {
window.removeEventListener('online', update)
window.removeEventListener('offline', update)
}
}, [])
return offline
}
/** A small "Offline" pill, shown only without signal. */
export function OfflineBadge({className = ''}: {className?: string}) {
const offline = useOffline()
if (!offline) return null
return (
<span
role="status"
title="No signal: you're seeing the copy saved on this device"
className={`rounded-full bg-warn-bg px-2.5 py-1 text-xs font-bold text-warn-fg ${className}`}
>
Offline
</span>
)
}
|