import { useIdle } from '@vueuse/core' import { ref, onMounted, onUnmounted } from 'vue' const SECONDS = 1000 const MINUTES = 60 * SECONDS interface PollingOptions { interval?: number inactivityThreshold?: number pauseInBackground?: boolean } export function usePolling( fn: () => Promise | void, options: PollingOptions = {} ) { const { interval = 30 * SECONDS, inactivityThreshold = 5 * MINUTES, pauseInBackground = true, } = options const { idle } = useIdle(inactivityThreshold) const isPolling = ref(true) const pollingId = ref(null) const isTabActive = () => { return !pauseInBackground || document.visibilityState === 'visible' } // Stop polling permanently - cannot be resumed const stopPolling = () => { isPolling.value = false // Permanently set to false if (pollingId.value !== null) { clearTimeout(pollingId.value) pollingId.value = null } } // Pause polling temporarily - can be resumed const pausePolling = () => { if (pollingId.value !== null) { clearTimeout(pollingId.value) pollingId.value = null } // Note: We don't change isPolling.value here, just clear the timeout } // Start polling with intelligent checks const startPolling = () => { // Clear any existing polling timeout if (pollingId.value !== null) { clearTimeout(pollingId.value) pollingId.value = null } const poll = async () => { if (isPolling.value && isTabActive() && !idle.value) { try { await fn() } catch (error) { console.error('Polling error:', error) } } if (isPolling.value) { pollingId.value = window.setTimeout(poll, interval) } } poll() } const resumePolling = () => { if (isPolling.value) { startPolling() } else { console.warn('Cannot resume polling that was stopped') } } function updateVisibility() { if (document.visibilityState === 'visible') { if (isPolling.value) { startPolling() } } else if (pauseInBackground) { pausePolling() } } onMounted(() => { document.addEventListener('visibilitychange', updateVisibility) startPolling() }) onUnmounted(() => { document.removeEventListener('visibilitychange', updateVisibility) stopPolling() }) return { isPolling, pausePolling, resumePolling, startPolling, stopPolling } }