expo-duooomi-app/components/hot-update.tsx

95 lines
2.6 KiB
TypeScript

import * as Sentry from '@sentry/react-native'
import * as Updates from 'expo-updates'
import { useUpdates } from 'expo-updates'
import { useCallback, useEffect, useState } from 'react'
import { Block, Text } from '@/@share/components'
import { useUpdateChecker } from '@/hooks/use-update-checker'
import { ProgressLine } from './progress'
export const HotUpdate = () => {
const { hasUpdate = true } = useUpdateChecker()
const [showUpdate, setShowUpdate] = useState(hasUpdate)
const { isDownloading, isUpdatePending } = useUpdates()
const [downloadProgress, setDownloadProgress] = useState(0)
useEffect(() => {
setShowUpdate(hasUpdate)
}, [hasUpdate])
useEffect(() => {
Sentry.captureMessage('HotUpdate', {
tags: {
component: 'HotUpdate',
},
contexts: {
update: {
hasUpdate,
isDownloading,
isUpdatePending,
},
},
})
if (isDownloading) {
const interval = setInterval(() => {
setDownloadProgress((prev) => {
if (prev >= 95) return prev
const next = Number((prev + Math.random() * 10).toFixed(2))
return Math.min(next, 100)
})
}, 300)
return () => clearInterval(interval)
}
}, [isDownloading])
useEffect(() => {
if (isUpdatePending) {
setDownloadProgress(100)
setTimeout(() => {
Updates.reloadAsync()
}, 2000)
}
}, [isUpdatePending])
const downloadAndApplyUpdate = useCallback(async () => {
try {
setDownloadProgress(0)
await Updates.fetchUpdateAsync()
} catch (error) {
console.error('更新失败:', error)
setShowUpdate(false)
Sentry.captureMessage('HotUpdateError', {
tags: {
component: 'HotUpdate',
},
contexts: {
update: {
error: error instanceof Error ? error.message : '更新失败',
},
},
})
}
}, [])
useEffect(() => {
if (showUpdate) {
downloadAndApplyUpdate()
}
}, [showUpdate, downloadAndApplyUpdate])
if (!showUpdate) return null
return (
<Block className="bg-white p-[10px]">
<ProgressLine className="h-[5px] w-full" progress={downloadProgress} progressClassName="h-[5px]" />
<Block className="mt-1 flex-row items-center justify-between bg-white px-1">
<Text className="text-[12px] text-black">
{isDownloading ? '更新中' : downloadProgress >= 100 ? '更新成功' : '更新失败'}
</Text>
<Text className="text-[12px] text-black">{downloadProgress}%</Text>
</Block>
</Block>
)
}