fix: corregir race condition en favoritos con Supabase INITIAL_SESSION
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, onUnmounted } from 'vue'
|
import { computed, onMounted, onUnmounted, watch } from 'vue'
|
||||||
import { RouterView, useRoute } from "vue-router";
|
import { RouterView, useRoute } from "vue-router";
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import MainLayout from "./components/layouts/MainLayout.vue";
|
import MainLayout from "./components/layouts/MainLayout.vue";
|
||||||
@ -155,15 +155,24 @@ onMounted(() => {
|
|||||||
event_name: 'app_open',
|
event_name: 'app_open',
|
||||||
properties: { language: locale.value }
|
properties: { language: locale.value }
|
||||||
})
|
})
|
||||||
// Load favorites if the user is already logged in
|
|
||||||
if (authStore.isAuthenticated) {
|
|
||||||
favoritesStore.loadFavorites()
|
|
||||||
}
|
|
||||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||||
window.addEventListener('pageshow', handlePageShow)
|
window.addEventListener('pageshow', handlePageShow)
|
||||||
window.addEventListener('focus', handleWindowFocus)
|
window.addEventListener('focus', handleWindowFocus)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Cargar favoritos cuando Supabase confirme la sesión (puede ser después de onMounted)
|
||||||
|
// immediate:true cubre el caso donde la sesión ya está lista al arrancar
|
||||||
|
const stopFavWatcher = watch(
|
||||||
|
() => authStore.isAuthenticated,
|
||||||
|
(authenticated) => {
|
||||||
|
if (authenticated && favoritesStore.favorites.length === 0 && !favoritesStore.isLoading) {
|
||||||
|
favoritesStore.loadFavorites()
|
||||||
|
stopFavWatcher() // Solo necesitamos cargarlo una vez al inicio
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||||
window.removeEventListener('pageshow', handlePageShow)
|
window.removeEventListener('pageshow', handlePageShow)
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import { useFavoritesStore } from '@/stores/favorites'
|
import { useFavoritesStore } from '@/stores/favorites'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
|
||||||
@ -31,16 +31,22 @@ const isFavorited = computed(() => {
|
|||||||
return favoritesStore.isFavorite(props.itemType, props.itemId)
|
return favoritesStore.isFavorite(props.itemType, props.itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
// Observamos isAuthenticated con immediate:true para cubrir 2 casos:
|
||||||
// Load favorites if authenticated and not loaded yet
|
// 1. El usuario ya estaba autenticado cuando el componente montó.
|
||||||
if (authStore.isAuthenticated && favoritesStore.favorites.length === 0) {
|
// 2. Supabase completó INITIAL_SESSION DESPUÉS de que el componente montó
|
||||||
|
// (race condition común al navegar directamente a una URL).
|
||||||
|
watch(
|
||||||
|
() => authStore.isAuthenticated,
|
||||||
|
(authenticated) => {
|
||||||
|
if (authenticated && favoritesStore.favorites.length === 0 && !favoritesStore.isLoading) {
|
||||||
favoritesStore.loadFavorites()
|
favoritesStore.loadFavorites()
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
async function handleToggle() {
|
async function handleToggle() {
|
||||||
if (!authStore.isAuthenticated) {
|
if (!authStore.isAuthenticated) {
|
||||||
// Optionally redirect to login or show message
|
|
||||||
alert('Debes iniciar sesión para agregar favoritos')
|
alert('Debes iniciar sesión para agregar favoritos')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useFavoritesStore } from '@/stores/favorites'
|
import { useFavoritesStore } from '@/stores/favorites'
|
||||||
|
import { useAuthStore } from '@/stores/auth'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { getImageUrl as utilGetImageUrl } from '@/utils/imageUrl'
|
import { getImageUrl as utilGetImageUrl } from '@/utils/imageUrl'
|
||||||
import LoadingBranded from '@/components/common/LoadingBranded.vue'
|
import LoadingBranded from '@/components/common/LoadingBranded.vue'
|
||||||
@ -9,6 +10,7 @@ import LoadingBranded from '@/components/common/LoadingBranded.vue'
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const favoritesStore = useFavoritesStore()
|
const favoritesStore = useFavoritesStore()
|
||||||
|
const authStore = useAuthStore()
|
||||||
const selectedFilter = ref('all')
|
const selectedFilter = ref('all')
|
||||||
|
|
||||||
const filters = computed(() => [
|
const filters = computed(() => [
|
||||||
@ -20,9 +22,16 @@ const filters = computed(() => [
|
|||||||
{ key: 'stops', label: t('navigation.routes'), icon: 'location_on' }, // Reusing navigation.routes or adding a specific one
|
{ key: 'stops', label: t('navigation.routes'), icon: 'location_on' }, // Reusing navigation.routes or adding a specific one
|
||||||
])
|
])
|
||||||
|
|
||||||
onMounted(async () => {
|
// Mismo patrón que FavoriteButton: esperar a que Supabase complete INITIAL_SESSION
|
||||||
await favoritesStore.loadFavorites()
|
watch(
|
||||||
})
|
() => authStore.isAuthenticated,
|
||||||
|
(authenticated) => {
|
||||||
|
if (authenticated) {
|
||||||
|
favoritesStore.loadFavorites()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
function getImageUrl(path?: string) {
|
function getImageUrl(path?: string) {
|
||||||
return utilGetImageUrl(path, 'business')
|
return utilGetImageUrl(path, 'business')
|
||||||
|
|||||||
Reference in New Issue
Block a user