新增 PWA 更新提示並整理 README

This commit is contained in:
2026-04-16 19:57:08 +08:00
parent 0cfcdc3b0a
commit 975732017f
11 changed files with 349 additions and 67 deletions

View File

@@ -79,6 +79,7 @@ const STREAK_TITLES: Record<number, string> = {
7: '像神一般的',
8: '成為傳說',
}
const PWA_UPDATE_EVENT = 'badminton-scoreboard:pwa-update-ready'
function App() {
const location = useLocation()
@@ -115,6 +116,7 @@ function App() {
})
const [streakAnnouncement, setStreakAnnouncement] = useState<StreakAnnouncement | null>(null)
const [victoryAnnouncement, setVictoryAnnouncement] = useState<VictoryAnnouncement | null>(null)
const [pwaUpdateReady, setPwaUpdateReady] = useState(false)
const parsedAreaA = useMemo(() => parseRoster(areaAInput), [areaAInput])
const parsedAreaB = useMemo(() => parseRoster(areaBInput), [areaBInput])
@@ -174,6 +176,18 @@ function App() {
return () => window.clearTimeout(timer)
}, [victoryAnnouncement])
useEffect(() => {
const handlePwaUpdateReady = () => {
setPwaUpdateReady(true)
}
window.addEventListener(PWA_UPDATE_EVENT, handlePwaUpdateReady)
return () => {
window.removeEventListener(PWA_UPDATE_EVENT, handlePwaUpdateReady)
}
}, [])
const resetScoring = (nextState: ScoreState = initialScoreState) => {
setScoreState(nextState)
setScoreHistory([])
@@ -215,6 +229,21 @@ function App() {
})
}
const refreshForPwaUpdate = () => {
const registrationPromise = navigator.serviceWorker?.getRegistration
? navigator.serviceWorker.getRegistration()
: Promise.resolve(undefined)
void registrationPromise.then((registration) => {
if (registration?.waiting) {
registration.waiting.postMessage({ type: 'SKIP_WAITING' })
return
}
window.location.reload()
})
}
const loadGroupsFromDb = async () => {
if (!targetDate) {
setLoadStatus('error')
@@ -601,6 +630,18 @@ function App() {
/>
<Route path="/history" element={<HistoryPage />} />
</Routes>
{pwaUpdateReady ? (
<div className="pwa-update-toast" role="status" aria-live="polite">
<div className="pwa-update-copy">
<strong></strong>
<span></span>
</div>
<button className="pwa-update-button" onClick={refreshForPwaUpdate} type="button">
</button>
</div>
) : null}
</div>
)
}