48 lines
1.3 KiB
JavaScript
48 lines
1.3 KiB
JavaScript
/** Fetches live sessions; polls when tab visible. */
|
|
const POLL_MS = 1500
|
|
|
|
export function useLiveSessions() {
|
|
const { data: _sessions, refresh } = useAsyncData(
|
|
'live-sessions',
|
|
async () => {
|
|
try {
|
|
return await $fetch('/api/live')
|
|
}
|
|
catch (err) {
|
|
const msg = err?.message ?? String(err)
|
|
const status = err?.statusCode ?? err?.status
|
|
console.error('[useLiveSessions] Failed to fetch sessions:', status ? `${status}: ${msg}` : msg)
|
|
return []
|
|
}
|
|
},
|
|
{ default: () => [] },
|
|
)
|
|
|
|
const sessions = computed(() => Object.freeze([...(_sessions.value ?? [])]))
|
|
const pollInterval = ref(null)
|
|
|
|
function startPolling() {
|
|
if (pollInterval.value) return
|
|
refresh()
|
|
pollInterval.value = setInterval(refresh, POLL_MS)
|
|
}
|
|
|
|
function stopPolling() {
|
|
if (pollInterval.value) {
|
|
clearInterval(pollInterval.value)
|
|
pollInterval.value = null
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
if (typeof document === 'undefined') return
|
|
document.addEventListener('visibilitychange', () => {
|
|
document.visibilityState === 'visible' ? (startPolling(), refresh()) : stopPolling()
|
|
})
|
|
if (document.visibilityState === 'visible') startPolling()
|
|
})
|
|
onBeforeUnmount(stopPolling)
|
|
|
|
return Object.freeze({ sessions, refresh, startPolling, stopPolling })
|
|
}
|