fix: resolve blank screen on return from external links
This commit is contained in:
@ -21,6 +21,15 @@ const isAuthScreen = computed(() => {
|
||||
})
|
||||
|
||||
let lastHiddenAt: number | null = null
|
||||
let refocusDebounceTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
function dispatchRefocus(reason: string) {
|
||||
// Debounce: no disparar dos eventos seguidos en menos de 1 segundo
|
||||
if (refocusDebounceTimer) return
|
||||
refocusDebounceTimer = setTimeout(() => { refocusDebounceTimer = null }, 1000)
|
||||
console.log(`SIBU | App refocus — motivo: ${reason}`)
|
||||
window.dispatchEvent(new CustomEvent('app-refocus'))
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
@ -29,10 +38,32 @@ function handleVisibilityChange() {
|
||||
}
|
||||
if (document.visibilityState === 'visible' && lastHiddenAt !== null) {
|
||||
const secondsAway = (Date.now() - lastHiddenAt) / 1000
|
||||
// Si pasaron más de 3 segundos, asumimos que el proceso pudo ser suspendido
|
||||
if (secondsAway > 3) {
|
||||
console.log(`SIBU | App recuperada tras ${secondsAway.toFixed(1)}s. Disparando refocus...`)
|
||||
window.dispatchEvent(new CustomEvent('app-refocus'))
|
||||
// Umbral bajo (1 s) para capturar retornos rápidos desde Google Maps / links externos
|
||||
if (secondsAway > 1) {
|
||||
dispatchRefocus(`visibilitychange tras ${secondsAway.toFixed(1)}s`)
|
||||
}
|
||||
lastHiddenAt = null
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: 'pageshow' se dispara al volver desde el bfcache (back-forward cache)
|
||||
// Muy común en Safari/iOS cuando se abre un link externo y se regresa
|
||||
function handlePageShow(event: PageTransitionEvent) {
|
||||
if (event.persisted) {
|
||||
// La página fue restaurada desde bfcache — siempre necesita refocus
|
||||
dispatchRefocus('pageshow persisted (bfcache)')
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: 'focus' en window cubre casos donde visibilitychange no se dispara
|
||||
// (algunos navegadores Android al volver de otra app)
|
||||
let windowFocusTimer: ReturnType<typeof setTimeout> | null = null
|
||||
function handleWindowFocus() {
|
||||
// Solo si la pestaña estuvo oculta antes
|
||||
if (lastHiddenAt !== null) {
|
||||
const secondsAway = (Date.now() - lastHiddenAt) / 1000
|
||||
if (secondsAway > 1) {
|
||||
dispatchRefocus(`window focus tras ${secondsAway.toFixed(1)}s`)
|
||||
}
|
||||
lastHiddenAt = null
|
||||
}
|
||||
@ -49,10 +80,16 @@ onMounted(() => {
|
||||
favoritesStore.loadFavorites()
|
||||
}
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||
window.addEventListener('pageshow', handlePageShow)
|
||||
window.addEventListener('focus', handleWindowFocus)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||
window.removeEventListener('pageshow', handlePageShow)
|
||||
window.removeEventListener('focus', handleWindowFocus)
|
||||
if (refocusDebounceTimer) clearTimeout(refocusDebounceTimer)
|
||||
if (windowFocusTimer) clearTimeout(windowFocusTimer)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user