fix(mini): sync cached tab bars with the visible page

This commit is contained in:
stu2not
2026-09-15 11:42:38 +08:00
parent fce6cd1cc1
commit 5a2349bb6d
6 changed files with 35 additions and 6 deletions
+6 -6
View File
@@ -1,6 +1,7 @@
import { Image, Text, View } from '@tarojs/components'
import Taro, { useDidShow } from '@tarojs/taro'
import { useState } from 'react'
import Taro from '@tarojs/taro'
import { useSyncExternalStore } from 'react'
import { getActiveTabRoute, subscribeTabBarRoute } from '@/utils/tab-bar'
import './index.scss'
const tabs = [
@@ -16,8 +17,7 @@ function currentRoute() {
}
export default function CustomTabBar() {
const [route, setRoute] = useState(currentRoute)
useDidShow(() => setRoute(currentRoute()))
const route = useSyncExternalStore(subscribeTabBarRoute, getActiveTabRoute)
return (
<View className='companion-tab-bar'>
{tabs.map((tab) => {
@@ -26,8 +26,8 @@ export default function CustomTabBar() {
return (
<View key={tab.page} className={`companion-tab ${active ? 'active' : ''}`}
onClick={() => {
if (active) return
Taro.switchTab({ url: `/${path}`, success: () => setRoute(path) })
if (currentRoute() === path) return
Taro.switchTab({ url: `/${path}` })
}}>
<Image className='companion-tab-icon' src={active ? tab.selected : tab.icon} mode='aspectFit' />
<Text className='companion-tab-label'>{tab.label}</Text>
+2
View File
@@ -1,5 +1,6 @@
import { getParticipantArtwork } from '@/utils/artwork'
import { getPageStyle } from '@/utils/page-style'
import { setActiveTabRoute } from '@/utils/tab-bar'
import { View, Text, ScrollView, Image } from '@tarojs/components'
import { useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
@@ -15,6 +16,7 @@ export default function Chat() {
const [isGuest, setIsGuest] = useState(false)
useDidShow(() => {
setActiveTabRoute('pages/chat/index')
void loadConversations()
})
+2
View File
@@ -1,4 +1,5 @@
import { getPageStyle } from '@/utils/page-style'
import { setActiveTabRoute } from '@/utils/tab-bar'
import { View, Text, Slider, Image } from '@tarojs/components'
import { useRef, useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
@@ -140,6 +141,7 @@ export default function Device() {
const volumeCommandInFlightRef = useRef(false)
useDidShow(() => {
setActiveTabRoute('pages/device/index')
void loadDeviceInfo()
})
+2
View File
@@ -1,4 +1,5 @@
import { getPageStyle } from '@/utils/page-style'
import { setActiveTabRoute } from '@/utils/tab-bar'
import { View, Text, Map } from '@tarojs/components'
import { useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
@@ -139,6 +140,7 @@ export default function Location() {
const [isGuest, setIsGuest] = useState(false)
useDidShow(() => {
setActiveTabRoute('pages/location/index')
void loadLocation(true)
})
+2
View File
@@ -1,6 +1,7 @@
import FirmwareProgress from '@/components/firmware-progress'
import { getRoleArtwork } from '@/utils/artwork'
import { getPageStyle } from '@/utils/page-style'
import { setActiveTabRoute } from '@/utils/tab-bar'
import { View, Text, Image, Input, Button } from '@tarojs/components'
import { useEffect, useRef, useState } from 'react'
import Taro, { useDidHide, useDidShow, useShareAppMessage } from '@tarojs/taro'
@@ -130,6 +131,7 @@ export default function Sleep() {
const isFirmwareStatusPollingRef = useRef(false)
useDidShow(() => {
setActiveTabRoute('pages/sleep/index')
void loadData()
})
+21
View File
@@ -0,0 +1,21 @@
export type TabBarRoute = 'pages/device/index' | 'pages/chat/index' | 'pages/location/index' | 'pages/sleep/index'
// WeChat caches a separate custom tab bar for each page. All instances follow
// the route reported by the visible page, including navigation from other UI.
let activeRoute: TabBarRoute = 'pages/device/index'
const listeners = new Set<() => void>()
export function getActiveTabRoute(): TabBarRoute {
return activeRoute
}
export function subscribeTabBarRoute(listener: () => void): () => void {
listeners.add(listener)
return () => { listeners.delete(listener) }
}
export function setActiveTabRoute(route: TabBarRoute): void {
if (activeRoute === route) return
activeRoute = route
listeners.forEach((listener) => listener())
}