expo-duooomi-app/app/device.tsx

136 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Ionicons } from '@expo/vector-icons'
import { Block, ConfirmModal, ListEmpty, 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'
import React, { useCallback, useEffect } from 'react'
import { bleManager } from '@/ble/managers/bleManager'
import BannerSection from '@/components/BannerSection'
import { bleStore, userStore } from '@/stores'
import { screenWidth } from '@/utils'
import { buildCdnUrl } from '@/utils/getCDNKey'
// ============ 主组件 ============
const Device = observer(() => {
const { user, isAuthenticated } = userStore
const { isConnected } = bleStore.state
const { galleryList } = bleStore
const itemWidth = Math.floor((screenWidth - 12 * 2 - 12 * 2) / 3)
useFocusEffect(() => {
if (!isAuthenticated) {
router.replace('/')
router.push('/auth')
}
})
useEffect(() => {
if (!isConnected) {
Toast.show({ title: `设备已断开连接` })
router.back()
}
}, [isConnected])
const renderGridItem = useCallback(
({ item }: { item: any }) => {
const handleDeleteConfirm = async () => {
try {
await bleManager.deleteFile(item)
bleStore.removeGalleryItem(item)
Toast.hideModal()
} catch (error: any) {
// console.error('Error deleting file:', error)
// Toast.show({ title: `删除失败: ${error?.message || error}` })
}
}
const handleDelete = async () => {
if (!isConnected) {
Toast.show({ title: `请先连接设备` })
return
}
if (galleryList.length <= 1) {
Toast.show({ title: `至少保留一个文件` })
return
}
Toast.showModal(
<ConfirmModal
title="删除文件"
content={
<Text className="text-[14px] font-bold leading-relaxed text-gray-800"></Text>
}
onCancel={() => Toast.hideModal()}
onConfirm={handleDeleteConfirm}
/>,
)
}
const url = buildCdnUrl(item)
if (!url) return null
return (
<Block className="relative">
<Block
className={`relative overflow-hidden border-2 ${'shadow-hard-black'} ${'border-black'}`}
style={{ transform: [{ skewX: '-6deg' }], height: itemWidth, width: itemWidth }}
>
<Block className="flex items-center justify-center" style={{ height: itemWidth, width: itemWidth }}>
<VideoBox style={{ width: itemWidth, height: itemWidth }} url={url} />
</Block>
{/* 删除按钮 */}
<Block
className="absolute right-1 top-1 z-20 size-6 items-center justify-center rounded-full border-2 border-black bg-[#e61e25] shadow-hard-black"
style={{ transform: [{ skewX: '6deg' }] }}
onClick={() => {
handleDelete()
}}
>
<Ionicons color="white" name="trash-outline" size={12} />
</Block>
</Block>
</Block>
)
},
[itemWidth],
)
const renderHeader = () => (
<Block className="flex-row items-center justify-between px-[16px]" style={{ paddingTop: 12, paddingBottom: 12 }}>
<Block className="ml-[-8px] size-[40px] items-center justify-center" opacity={0.7} onClick={() => router.back()}>
<Ionicons color="white" name="chevron-back" size={24} />
</Block>
<Text className="text-[16px] font-[700] text-white"></Text>
<Block className="w-[32px]" />
</Block>
)
return (
<Block className="relative flex-1">
<BannerSection />
<Stack.Screen options={{ headerShown: false }} />
{renderHeader()}
<Block className="z-10 flex-1">
<FlashList
contentContainerStyle={{ paddingHorizontal: 12, paddingBottom: 200 }}
data={galleryList}
drawDistance={1200}
// @ts-ignore
estimatedItemSize={itemWidth}
getItemType={() => 'row'}
ItemSeparatorComponent={() => <Block style={{ height: 6 }} />}
keyExtractor={(item) => item}
ListEmptyComponent={<ListEmpty />}
numColumns={3}
renderItem={renderGridItem}
/>
</Block>
</Block>
)
})
export default Device