feat: 添加固件更新功能,优化设备信息显示,移除不必要的日志

This commit is contained in:
康猛 2026-01-27 11:46:26 +08:00
parent f9d13dbaf2
commit f3ddb954dc
3 changed files with 143 additions and 35 deletions

View File

@ -72,7 +72,7 @@ const Index = observer(function Index() {
const file = root.get(FileController)
// file.convertToWebp('https://cdn.roasmax.cn/material/b59b75841c484d8bafec9c5636930b69.webp', 256)
firmware.getLatestPublished('duomi').then((r) => {
console.log('latest duomi firmware:', r)
// console.log('latest duomi firmware:', r)
})
}
useEffect(() => {

View File

@ -14,7 +14,7 @@ import {
} from '@share/components'
import { FlashList } from '@shopify/flash-list'
import * as ImagePicker from 'expo-image-picker'
import { router, useFocusEffect } from 'expo-router'
import { router } from 'expo-router'
import { observer } from 'mobx-react-lite'
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ActivityIndicator, RefreshControl, ScrollView } from 'react-native'
@ -71,21 +71,10 @@ const Sync = observer(() => {
// 加载生成记录
useEffect(() => {
if (!isLogin)
if (user?.id) {
loadGenerations()
}
}, [user?.id, loadGenerations])
// 页面聚焦时重新请求数据
useFocusEffect(
useCallback(() => {
if (user?.id) {
console.log('页面聚焦,重新请求数据')
loadGenerations()
}
}, [user?.id, loadGenerations]),
)
if (isFocused) {
loadGenerations()
}
}, [isFocused])
// 将生成记录转换为 posts 格式
const posts = useMemo(() => {
@ -419,12 +408,15 @@ const Sync = observer(() => {
itemWidth={ITEM_WIDTH}
post={post}
// 页面失焦时不渲染,减少内存占用
isVisible={isFocused}
onSelect={handleItemSelect}
/>
)
}
if (!isFocused) {
return null
}
return (
<Block className="relative flex-1 bg-black">
<BannerSection />
@ -433,11 +425,11 @@ const Sync = observer(() => {
<FlashList
contentContainerStyle={{ paddingHorizontal: 12, paddingBottom: 200 }}
data={posts}
drawDistance={300}
// drawDistance={300}
maxItemsInRecyclePool={0}
removeClippedSubviews={true}
ItemSeparatorComponent={() => <Block style={{ height: 6 }} />}
keyExtractor={(item: any) => item?.id || `fallback-${Math.random()}`}
keyExtractor={(item: any) => item?.id}
ListFooterComponent={ListFooter}
ListHeaderComponent={renderHeader}
ListEmptyComponent={<ListEmpty />}
@ -451,7 +443,7 @@ const Sync = observer(() => {
/>
</Block>
<FABButtons canSync={canSync} onGenAgain={handleGenAgain} handleSync={handleSync} />
<FABButtons onGenAgain={handleGenAgain} handleSync={handleSync} />
<SelectionBar
isSelectionMode={isSelectionMode}
@ -709,8 +701,8 @@ const GridItem = memo(
}
const imgShow = post.webpPreviewUrl || post.imageUrl
const placeholderSrc = null
// console.log('imgShow----------', imgShow)
const placeholderSrc = null
// 新数据使用webp 旧数据使用mp4
return (
@ -720,7 +712,7 @@ const GridItem = memo(
style={{ transform: [{ skewX: '-6deg' }], height: itemWidth, width: itemWidth }}
>
<Block style={{ height: itemWidth, width: itemWidth }}>
{isVisible && <Img className="size-full" src={imgShow} placeholderSrc={placeholderSrc} />}
{isVisible && <Img className="size-full" src={imgShow} />}
</Block>
{isSelected && <Block className="absolute inset-0 border-[3px] border-accent" />}
@ -868,7 +860,7 @@ const HeaderBanner = observer(({ connectedDevice, onPick }: { connectedDevice: a
if (isLogin) {
signOut().then(() => {
Toast.show({ title: '已登出' })
// router.replace('/')
router.replace('/auth')
})
}
}

View File

@ -1,5 +1,7 @@
import { Ionicons } from '@expo/vector-icons'
import { Block, ConfirmModal, ListEmpty, Text, Toast, VideoBox } from '@share/components'
import { root } from '@repo/core'
import { FirmwareController } from '@repo/sdk'
import { Block, ConfirmModal, ListEmpty, SyncProgressToast, Text, Toast, VideoBox } from '@share/components'
import { FlashList } from '@shopify/flash-list'
import { router, Stack, useFocusEffect } from 'expo-router'
import { observer } from 'mobx-react-lite'
@ -29,6 +31,21 @@ const Device = observer(() => {
})
const [loading, setLoading] = useState(false)
const [binInfo, setBinInfo] = useState<any>(null)
const loadBin = async () => {
const firmware = root.get(FirmwareController)
firmware.getLatestPublished('duomi').then((r) => {
console.log('latest duomi firmware:', r)
setBinInfo(r)
})
}
useEffect(() => {
console.log('expo env------------', process.env.EXPO_PUBLIC_ENV)
loadBin()
}, [])
// ✅ 页面聚焦时自动获取设备信息和版本号
useFocusEffect(
useCallback(() => {
@ -63,6 +80,8 @@ const Device = observer(() => {
])
console.log('queryDeviceData------------', deviceInfoData)
console.log('versionInfo------------', versionInfo)
// ✅ 直接使用返回的数据更新本地状态
if (versionInfo) {
setVersion(versionInfo.version || '')
@ -90,6 +109,73 @@ const Device = observer(() => {
}
}, [])
const handleOtaUpgrade = async () => {
try {
if (!binInfo?.fileUrl) {
Toast?.show({ title: '固件文件地址无效' })
return
}
bleStore.setState((prestate) => {
return { ...prestate, transferProgress: 0 }
})
Toast.showLoading({
renderContent: () => <SyncProgressToast title="固件升级中" />,
duration: 0,
})
const buffer = await bleManager.performOtaUpgrade(binInfo.fileUrl)
Toast.hide()
Toast?.show({ title: `固件升级成功 (${buffer.byteLength} bytes) `, duration: 2e3 })
} catch (error) {
console.error('固件升级失败:', error)
const msg = typeof error === 'string' ? error : (error as any)?.message || '固件升级失败'
Toast?.show({ title: msg })
} finally {
Toast.hide()
}
}
// ✅ 固件更新处理
const handleFirmwareUpdate = useCallback(async () => {
if (!isConnected) {
Toast.show({ title: '请先连接设备' })
return
}
if (!binInfo?.version) {
Toast.show({ title: '无法获取固件信息' })
return
}
Toast.showModal(
<ConfirmModal
title="固件更新"
content={
<Block className="space-y-[8px]">
<Text className="text-[14px] font-bold leading-relaxed text-gray-800"></Text>
<Block className="rounded-lg bg-gray-100 p-[8px]">
<Text className="text-[12px] text-gray-600">{version}</Text>
<Text className="text-[12px] text-green-600">{binInfo?.version}</Text>
</Block>
<Text className="text-[11px] text-gray-500">
; 15 ; APP
</Text>
</Block>
}
confirmText="开始更新"
onCancel={() => Toast.hideModal()}
onConfirm={async () => {
Toast.hideModal()
Toast.show({ title: '开始更新固件...' })
// TODO: 实现固件更新逻辑
handleOtaUpgrade()
}}
/>,
)
}, [isConnected, binInfo, version])
// ✅ 计算内存百分比和显示文本(处理 bigint
const memoryDisplay = useMemo(() => {
if (memoryStats.total === 0n) return null
@ -227,15 +313,6 @@ const Device = observer(() => {
</Block>
)}
{/* 固件版本 */}
{version && (
<Block className="flex-row items-center justify-between">
<Text className="text-[12px] text-gray-500"></Text>
<Text className="text-[12px] font-bold text-white">{version}</Text>
</Block>
)}
{/* 电池电量 */}
{deviceInfo?.powerlevel !== undefined && (
<Block className="flex-row items-center justify-between">
<Text className="text-[12px] text-gray-500"></Text>
@ -251,11 +328,50 @@ const Device = observer(() => {
</Block>
</Block>
)}
{/* 固件版本 */}
{version && (
<Block className="flex-row items-center justify-between">
<Text className="text-[12px] text-gray-500"></Text>
<Text className="text-[12px] font-bold text-white">{version}</Text>
</Block>
)}
{/* 最新固件版本 */}
{binInfo?.version && (
<Block className="flex-row items-center justify-between">
<Text className="text-[12px] text-gray-500"></Text>
<Text className="text-[12px] font-bold text-green-400">{binInfo.version}</Text>
</Block>
)}
{/* 电池电量 */}
</Block>
{/* 固件更新按钮 */}
{binInfo?.version && version && binInfo.version !== version && (
<Block className="mt-[12px]">
<Block
className="flex-row items-center justify-between rounded-lg border-2 border-yellow-400 bg-yellow-400/10 px-[12px] py-[8px]"
onClick={handleFirmwareUpdate}
>
<Block className="flex-1">
<Text className="text-[12px] font-bold text-yellow-400"></Text>
<Text className="mt-[2px] text-[10px] text-gray-400">
{version} {binInfo.version}
</Text>
</Block>
<Block className="flex-row items-center gap-[4px] rounded bg-yellow-400 px-[12px] py-[6px]">
<Ionicons color="black" name="download-outline" size={14} />
<Text className="text-[12px] font-bold text-black"></Text>
</Block>
</Block>
</Block>
)}
{/* 内存信息 */}
{memoryDisplay && (
<Block className="space-y-[8px]">
<Block className="mt-[12px] space-y-[8px]">
{/* 内存标题 */}
<Block className="mb-[8px] flex-row items-center justify-between">
<Text className="text-[12px] font-bold text-white"></Text>