Optimize BottomNav: instant visual feedback and ultra-low debounce for better responsiveness
This commit is contained in:
@ -15,11 +15,14 @@ const navItems = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const isNavigating = ref(false)
|
const isNavigating = ref(false)
|
||||||
|
const optimisticActivePath = ref('')
|
||||||
|
|
||||||
const navigateTo = async (path: string) => {
|
const navigateTo = async (path: string) => {
|
||||||
// Prevent rapid multiple navigations (debounce guard)
|
|
||||||
if (isNavigating.value) return
|
|
||||||
if (route.path === path) return
|
if (route.path === path) return
|
||||||
|
if (isNavigating.value) return
|
||||||
|
|
||||||
|
// Instant visual feedback
|
||||||
|
optimisticActivePath.value = path
|
||||||
|
|
||||||
try {
|
try {
|
||||||
isNavigating.value = true
|
isNavigating.value = true
|
||||||
@ -28,13 +31,18 @@ const navigateTo = async (path: string) => {
|
|||||||
if (e?.name !== 'NavigationDuplicated') {
|
if (e?.name !== 'NavigationDuplicated') {
|
||||||
console.error('SIBU | Error de navegación en el menú inferior:', e)
|
console.error('SIBU | Error de navegación en el menú inferior:', e)
|
||||||
}
|
}
|
||||||
|
// Revert on error
|
||||||
|
optimisticActivePath.value = ''
|
||||||
} finally {
|
} finally {
|
||||||
// Add a small delay to prevent rapid double-taps
|
// Ultra-short lock to avoid mechanical double-taps only
|
||||||
setTimeout(() => { isNavigating.value = false }, 300)
|
setTimeout(() => { isNavigating.value = false }, 50)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isActive = (path: string) => {
|
const isActive = (path: string) => {
|
||||||
|
if (optimisticActivePath.value) {
|
||||||
|
return optimisticActivePath.value === path
|
||||||
|
}
|
||||||
return route.path === path || route.path.startsWith(path + '/')
|
return route.path === path || route.path.startsWith(path + '/')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,9 +75,8 @@ onUnmounted(() => {
|
|||||||
v-for="item in navItems"
|
v-for="item in navItems"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
:class="{ active: isActive(item.path), 'opacity-50 pointer-events-none': isNavigating }"
|
:class="{ active: isActive(item.path) }"
|
||||||
@click.prevent="navigateTo(item.path)"
|
@click.stop="navigateTo(item.path)"
|
||||||
@touchend.prevent="navigateTo(item.path)"
|
|
||||||
>
|
>
|
||||||
<span class="material-icons">{{ item.icon }}</span>
|
<span class="material-icons">{{ item.icon }}</span>
|
||||||
<span class="nav-label">{{ t('navigation.' + item.name) }}</span>
|
<span class="nav-label">{{ t('navigation.' + item.name) }}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user