From f3ddb954dce040c1dfa55c845e1e4cc3f3a6477c Mon Sep 17 00:00:00 2001 From: km2025 Date: Tue, 27 Jan 2026 11:46:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=9B=BA=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E4=BF=A1=E6=81=AF=E6=98=BE=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(tabs)/index.tsx | 2 +- app/(tabs)/sync.tsx | 38 +++++------- app/device.tsx | 138 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 143 insertions(+), 35 deletions(-) diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index b5a498e..339c37f 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -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(() => { diff --git a/app/(tabs)/sync.tsx b/app/(tabs)/sync.tsx index a615b45..716705a 100644 --- a/app/(tabs)/sync.tsx +++ b/app/(tabs)/sync.tsx @@ -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 ( @@ -433,11 +425,11 @@ const Sync = observer(() => { } - keyExtractor={(item: any) => item?.id || `fallback-${Math.random()}`} + keyExtractor={(item: any) => item?.id} ListFooterComponent={ListFooter} ListHeaderComponent={renderHeader} ListEmptyComponent={} @@ -451,7 +443,7 @@ const Sync = observer(() => { /> - + - {isVisible && } + {isVisible && } {isSelected && } @@ -868,7 +860,7 @@ const HeaderBanner = observer(({ connectedDevice, onPick }: { connectedDevice: a if (isLogin) { signOut().then(() => { Toast.show({ title: '已登出' }) - // router.replace('/') + router.replace('/auth') }) } } diff --git a/app/device.tsx b/app/device.tsx index 1a4e248..a74ecd1 100644 --- a/app/device.tsx +++ b/app/device.tsx @@ -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(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: () => , + 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( + + 确定要更新固件吗? + + 当前版本:{version} + 最新版本:{binInfo?.version} + + + 更新过程中请保持设备连接和电量充足; 更新大概需要 15 分钟;更新过程中请勿操作设备和 APP。 + + + } + 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(() => { )} - {/* 固件版本 */} - {version && ( - - 固件版本 - {version} - - )} - - {/* 电池电量 */} {deviceInfo?.powerlevel !== undefined && ( 电池电量 @@ -251,11 +328,50 @@ const Device = observer(() => { )} + + {/* 固件版本 */} + {version && ( + + 固件版本 + {version} + + )} + + {/* 最新固件版本 */} + {binInfo?.version && ( + + 最新固件版本 + {binInfo.version} + + )} + + {/* 电池电量 */} + {/* 固件更新按钮 */} + {binInfo?.version && version && binInfo.version !== version && ( + + + + 发现新版本固件 + + {version} → {binInfo.version} + + + + + 更新 + + + + )} + {/* 内存信息 */} {memoryDisplay && ( - + {/* 内存标题 */} 存储空间