All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 56s
- Cambiar detección de desktop de min-width a (pointer: fine) - Esto detecta si tiene mouse/trackpad (desktop) vs touch (móvil) - Más confiable para PWAs que se abren con ancho fijo - Mantener ancho como fallback para compatibilidad
101 lines
4.0 KiB
TypeScript
101 lines
4.0 KiB
TypeScript
/**
|
|
* Plugin para interceptar enlaces externos que apuntan a esta PWA
|
|
* y navegarlos dentro de la misma ventana en lugar de abrir nuevas ventanas/pestañas
|
|
* En desktop, permite que los enlaces con target="_blank" abran nuevas ventanas para
|
|
* lanzar PWAs correspondientes
|
|
*/
|
|
export default defineNuxtPlugin(() => {
|
|
if (import.meta.client && typeof window !== 'undefined') {
|
|
// Detectar si la app está corriendo como PWA instalada
|
|
const isPWA = window.matchMedia('(display-mode: standalone)').matches ||
|
|
window.matchMedia('(display-mode: window-controls-overlay)').matches ||
|
|
(window.navigator as any).standalone === true
|
|
|
|
// Detectar si estamos en desktop usando pointer device (más confiable para PWAs)
|
|
const pointerQuery = window.matchMedia('(pointer: fine)')
|
|
const widthQuery = window.matchMedia('(min-width: 1024px)')
|
|
const isDesktop = pointerQuery.matches || widthQuery.matches
|
|
|
|
if (isPWA) {
|
|
// Obtener el origin de la aplicación
|
|
const appOrigin = window.location.origin
|
|
|
|
// Interceptar clics en enlaces externos
|
|
document.addEventListener('click', (event) => {
|
|
const target = event.target as HTMLElement
|
|
|
|
// Buscar el enlace más cercano (puede ser un elemento hijo del enlace)
|
|
const link = target.closest('a')
|
|
|
|
if (!link) return
|
|
|
|
const href = link.getAttribute('href')
|
|
if (!href) return
|
|
|
|
// Si el enlace tiene target="_blank", NUNCA interceptar
|
|
// Esto permite que en desktop los enlaces abran nuevas ventanas (PWAs)
|
|
const linkTarget = link.getAttribute('target')
|
|
if (linkTarget === '_blank') {
|
|
console.debug('Permitiendo apertura de nueva ventana para:', href)
|
|
return
|
|
}
|
|
|
|
try {
|
|
const url = new URL(href, window.location.origin)
|
|
|
|
// Solo interceptar enlaces que apunten a este origin
|
|
if (url.origin === appOrigin) {
|
|
// Prevenir comportamiento por defecto
|
|
event.preventDefault()
|
|
|
|
// Navegar usando el router de Nuxt si está dentro del scope
|
|
const router = useRouter()
|
|
const relativePath = url.pathname + url.search + url.hash
|
|
|
|
// Usar el router de Nuxt para navegación interna
|
|
router.push(relativePath)
|
|
}
|
|
} catch (error) {
|
|
// Si no se puede parsear la URL, dejar que el navegador maneje el enlace
|
|
console.debug('Error parsing link URL:', error)
|
|
}
|
|
}, { capture: true })
|
|
|
|
// Interceptar window.open para links que apunten a esta app
|
|
// En desktop, permitimos nuevas ventanas con target="_blank"
|
|
const originalWindowOpen = window.open
|
|
window.open = function(url?: string | URL, target?: string, features?: string) {
|
|
if (!url) {
|
|
return originalWindowOpen.call(window, url, target, features)
|
|
}
|
|
|
|
try {
|
|
const urlObj = typeof url === 'string' ? new URL(url, window.location.origin) : url
|
|
|
|
// Si es un enlace a esta app y no tiene target especificado o es _self
|
|
// Y NO estamos en desktop con target _blank (para permitir lanzar PWAs)
|
|
if (urlObj.origin === appOrigin && (!target || target === '_self')) {
|
|
const router = useRouter()
|
|
const relativePath = urlObj.pathname + urlObj.search + urlObj.hash
|
|
router.push(relativePath)
|
|
return null
|
|
}
|
|
|
|
// En desktop con target="_blank", permitir la apertura normal
|
|
if (isDesktop && target === '_blank') {
|
|
console.debug('Permitiendo window.open en desktop para:', url)
|
|
return originalWindowOpen.call(window, url, target, features)
|
|
}
|
|
} catch (error) {
|
|
console.debug('Error parsing window.open URL:', error)
|
|
}
|
|
|
|
// Para otros casos, usar el comportamiento original
|
|
return originalWindowOpen.call(window, url, target, features)
|
|
}
|
|
|
|
console.log('✅ PWA link handler initialized - capturing internal links (desktop mode:', isDesktop, ')')
|
|
}
|
|
}
|
|
})
|