fix: robust mobile suspend and auth recovery

This commit is contained in:
2026-03-04 00:51:32 -05:00
parent bdfcd55370
commit 90bb93be17
11 changed files with 257 additions and 47 deletions

View File

@ -135,17 +135,17 @@ function closePromoModal() {
selectedPromo.value = null;
}
async function fetchData() {
async function fetchData(isBackground = false) {
await Promise.all([
routeStore.loadRoutes(),
couponStore.loadCoupons({ active_only: true })
routeStore.loadRoutes(undefined, false, isBackground),
couponStore.loadCoupons({ active_only: true }, isBackground)
]);
updateActiveUnits();
}
async function handleRefocus() {
// Refrescar datos en fondo
fetchData();
// Refrescar datos en fondo de manera silenciosa (isBackground = true)
fetchData(true);
await nextTick();
@ -419,7 +419,9 @@ function locateUser(): Promise<void> {
}
resolve();
},
{ enableHighAccuracy: true, timeout: 8000, maximumAge: 30000 }
// maximumAge: 5 min — al volver del background, usa posición cacheada inmediatamente
// en lugar de esperar que el GPS se reactive (evita timeout al desbloquear pantalla)
{ enableHighAccuracy: false, timeout: 6000, maximumAge: 300000 }
);
});
}
@ -515,10 +517,19 @@ function handleImageError(event: Event) {
}
// Watch for user profile to trigger location if preference is enabled OR on auth changes
watch([() => authStore.userProfile?.auto_location, isLoaded], ([canLocate, loaded]) => {
// Nota: solo se activa si NO tenemos coordenadas aún Y el mapa está cargado.
// Se evita re-disparar por TOKEN_REFRESHED porque onAuthStateChange ya no recarga
// el perfil en ese evento, así que userProfile no cambia al despertar la pantalla.
watch([() => authStore.userProfile?.auto_location, isLoaded], ([canLocate, loaded], [prevCanLocate]) => {
// Solo localizar si: el mapa cargó, auto_location está activo,
// y NO tenemos coords aún (o el mapa se reinicializó sin coords)
if (canLocate && loaded && !userCoords.value) {
console.log('SIBU | Iniciando geolocalización automática...');
locateUser();
// Extra guard: no re-disparar si auto_location no cambió (solo isLoaded cambió)
// Esto previene relocalización innecesaria al volver del background
if (prevCanLocate !== undefined || !userCoords.value) {
console.log('SIBU | Iniciando geolocalización automática...');
locateUser();
}
}
}, { immediate: true });
</script>

View File

@ -20,12 +20,25 @@ const englishOnly = ref(false)
onMounted(async () => {
analyticsService.logEvent({ event_name: 'screen_view', screen_name: 'Transport' })
window.addEventListener('app-refocus', handleRefocus)
await Promise.all([
routeStore.loadRoutes(),
taxiStore.loadTaxis()
])
})
function handleRefocus() {
Promise.all([
routeStore.loadRoutes(undefined, false, true),
taxiStore.loadTaxis(undefined, true)
])
}
import { onUnmounted } from 'vue'
onUnmounted(() => {
window.removeEventListener('app-refocus', handleRefocus)
})
const handleBusSearch = async () => {
await routeStore.loadRoutes({
originCity: originSearch.value,
@ -237,7 +250,7 @@ const correlimientos = computed(() => {
</div>
</div>
<div class="text-right flex flex-col items-end gap-2">
<p class="font-black text-xl text-primary">{{ taxi.shift }}</p>
<p class="font-black text-xl text-primary">{{ taxi.shifts?.[0] || 'Día' }}</p>
<FavoriteButton
item-type="taxi"
:item-id="taxi.id"

View File

@ -144,15 +144,15 @@ function handleOutsideClick(e: MouseEvent) {
if (!target.closest('.route-selector')) dropdownOpen.value = false
}
async function fetchData() {
await routeStore.loadRoutes()
async function fetchData(isBackground = false) {
await routeStore.loadRoutes(undefined, false, isBackground)
if (localSelectedRouteId.value) {
await scheduleStore.loadRouteSchedules(localSelectedRouteId.value)
await scheduleStore.loadRouteSchedules(localSelectedRouteId.value, isBackground)
}
}
function handleRefocus() {
fetchData()
fetchData(true)
}
onMounted(async () => {