From 1d815652c4052830936603242cd1038e499f3b01 Mon Sep 17 00:00:00 2001 From: Padreug Date: Mon, 11 May 2026 18:09:15 +0200 Subject: [PATCH] fix(useOrder): use VisibilityService.registerService (not onVisible/onHidden) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../restaurant/composables/useOrder.ts | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/modules/restaurant/composables/useOrder.ts b/src/modules/restaurant/composables/useOrder.ts index 423ffd2..00347da 100644 --- a/src/modules/restaurant/composables/useOrder.ts +++ b/src/modules/restaurant/composables/useOrder.ts @@ -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): UseOrderReturn { const api = injectService(SERVICE_TOKENS.RESTAURANT_API) - const visibility = tryInjectService<{ - onVisible: (cb: () => void) => () => void - onHidden: (cb: () => void) => () => void - }>(SERVICE_TOKENS.VISIBILITY_SERVICE) + const visibility = tryInjectService( + SERVICE_TOKENS.VISIBILITY_SERVICE + ) const pollMs = ( @@ -60,7 +60,7 @@ export function useOrder(orderId: Ref | string): UseOrderReturn { const error = ref(null) let timer: ReturnType | 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): 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): UseOrderReturn { onScopeDispose(() => { stopPolling() - unsubVisible?.() + unregisterVisibility?.() }) return {