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 && (
-
+
{/* 内存标题 */}
存储空间