fix(useOrder): use VisibilityService.registerService (not onVisible/onHidden)

VisibilityService exposes `registerService(name, onResume, onPause)`
returning an unregister fn, not the `onVisible(cb)` / `onHidden(cb)`
shape I'd invented. OrderStatusPage was throwing
'visibility.onVisible is not a function' on every mount.

Rewire useOrder to register a (onResume, onPause) pair:
  onResume → immediate refetch + restart polling if status is
             non-terminal (useful for mobile where polling
             pauses during background)
  onPause  → stop polling to save battery while hidden
The returned unregister fn is called from onScopeDispose, same as
before. Also fixed the related TS narrowing on order.value.status
via the same Order|null cast already used elsewhere in this file.

Verified vue-tsc -b clean.
This commit is contained in:
Padreug 2026-05-11 18:09:15 +02:00
commit 1d815652c4

View file

@ -19,6 +19,7 @@ import {
SERVICE_TOKENS,
} from '@/core/di-container'
import appConfig from '@/app.config'
import type { VisibilityService } from '@/core/services/VisibilityService'
import type { RestaurantAPI } from '../services/RestaurantAPI'
import type {
Order,
@ -42,10 +43,9 @@ export interface UseOrderReturn {
export function useOrder(orderId: Ref<string> | string): UseOrderReturn {
const api = injectService<RestaurantAPI>(SERVICE_TOKENS.RESTAURANT_API)
const visibility = tryInjectService<{
onVisible: (cb: () => void) => () => void
onHidden: (cb: () => void) => () => void
}>(SERVICE_TOKENS.VISIBILITY_SERVICE)
const visibility = tryInjectService<VisibilityService>(
SERVICE_TOKENS.VISIBILITY_SERVICE
)
const pollMs =
(
@ -60,7 +60,7 @@ export function useOrder(orderId: Ref<string> | string): UseOrderReturn {
const error = ref<Error | null>(null)
let timer: ReturnType<typeof setInterval> | null = null
let unsubVisible: (() => void) | null = null
let unregisterVisibility: (() => void) | null = null
function targetId(): string {
return typeof orderId === 'string' ? orderId : orderId.value
@ -105,13 +105,25 @@ export function useOrder(orderId: Ref<string> | string): UseOrderReturn {
}
// Refetch immediately when the tab becomes visible again — useful
// for mobile where polling pauses during background.
// for mobile where polling pauses during background. The
// VisibilityService takes (name, onResume, onPause) and returns
// an unregister fn.
if (visibility) {
unsubVisible = visibility.onVisible(() => {
fetchOnce().then(() => {
if (!isTerminal(order.value?.status)) startPolling()
})
})
unregisterVisibility = visibility.registerService(
`useOrder-${typeof orderId === 'string' ? orderId : 'ref'}`,
async () => {
await fetchOnce()
if (
!isTerminal((order.value as Order | null)?.status)
) {
startPolling()
}
},
async () => {
// pause polling while hidden — saves battery on mobile
stopPolling()
}
)
}
watch(
@ -129,7 +141,7 @@ export function useOrder(orderId: Ref<string> | string): UseOrderReturn {
onScopeDispose(() => {
stopPolling()
unsubVisible?.()
unregisterVisibility?.()
})
return {