Update prompt and offline indicator (#52)
CI / ci (push) Successful in 1m33s

Co-authored-by: dev_agent <dev_agent@cubecraftlabs.com>
This commit was merged in pull request #52.
This commit is contained in:
2026-10-05 08:13:50 -04:00
committed by approver_agent
parent 21b2672d40
commit 78c33370f9
15 changed files with 587 additions and 25 deletions
+50
View File
@@ -0,0 +1,50 @@
// NetworkWindow is the part of window the network status reads: the browser's
// online flag and its online/offline events.
export type NetworkWindow = Pick<Window, 'navigator' | 'addEventListener' | 'removeEventListener'>
export type NetworkStatus = {
// offline reports whether the browser says it is offline or the last API
// request failed with a network error.
offline(): boolean
// subscribe is notified when offline may have changed. It listens for the
// window's online/offline events until the returned function is called.
subscribe(listener: () => void): () => void
// requestFailed records a fetch that rejected with a network error.
requestFailed(): void
// requestSucceeded records a fetch that got a response.
requestSucceeded(): void
}
// createNetworkStatus tracks whether MealQuest can reach the server. A failed
// request counts as offline until a later request gets a response or the
// browser reports that it is back online.
export function createNetworkStatus(win: NetworkWindow): NetworkStatus {
let failed = false
const listeners = new Set<() => void>()
function setFailed(value: boolean) {
if (failed === value) return
failed = value
listeners.forEach((listener) => listener())
}
return {
offline: () => !win.navigator.onLine || failed,
subscribe(listener) {
const online = () => {
failed = false
listener()
}
listeners.add(listener)
win.addEventListener('online', online)
win.addEventListener('offline', listener)
return () => {
listeners.delete(listener)
win.removeEventListener('online', online)
win.removeEventListener('offline', listener)
}
},
requestFailed: () => setFailed(true),
requestSucceeded: () => setFailed(false),
}
}