import { useRouter } from 'expo-router'
import { StatusBar } from 'expo-status-bar'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
FlatList,
StyleSheet,
StatusBar as RNStatusBar,
View,
ActivityIndicator,
RefreshControl,
Dimensions,
Platform,
} from 'react-native'
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
import { TemplateCard } from '@/components/blocks/home'
import ErrorState from '@/components/ErrorState'
import LoadingState from '@/components/LoadingState'
import { useUserLikes } from '@/hooks'
import { useTemplateSocialStore } from '@/stores/templateSocialStore'
import { root } from '@repo/core'
import { TemplateSocialController } from '@repo/sdk'
import { handleError } from '@/hooks/use-error'
const NUM_COLUMNS = 2
const HORIZONTAL_PADDING = 16
const CARD_GAP = 5
const SCREEN_WIDTH = Dimensions.get('window').width
// 计算卡片宽度
const calculateCardWidth = () => {
return (SCREEN_WIDTH - HORIZONTAL_PADDING * 2 - CARD_GAP * (NUM_COLUMNS - 1)) / NUM_COLUMNS
}
const CARD_WIDTH = calculateCardWidth()
export default function LikesScreen() {
const insets = useSafeAreaInsets()
const router = useRouter()
const [refreshing, setRefreshing] = useState(false)
// 使用 Store 中的点赞/收藏状态
const { setLiked, setFavorited, incrementLikeCount, decrementLikeCount } = useTemplateSocialStore()
// 获取用户点赞列表
const {
likes,
loading,
loadingMore,
error,
execute,
refetch,
loadMore,
hasMore,
} = useUserLikes()
// 初始化加载
useEffect(() => {
execute()
}, [])
// 下拉刷新处理
const handleRefresh = useCallback(async () => {
setRefreshing(true)
await refetch()
setRefreshing(false)
}, [refetch])
// 加载更多处理
const handleEndReached = useCallback(() => {
if (!loadingMore && hasMore && !loading) {
loadMore()
}
}, [loadingMore, hasMore, loading, loadMore])
// 导航到模板详情
const handleTemplatePress = useCallback((id: string) => {
router.push({
pathname: '/templateDetail' as any,
params: { id },
})
}, [router])
// 获取 social controller
const getSocialController = useCallback(() => {
return root.get(TemplateSocialController)
}, [])
// 点赞/取消点赞处理
const handleLike = useCallback(async (id: string) => {
setLiked(id, true)
incrementLikeCount(id)
try {
const social = getSocialController()
await handleError(() => social.like({ templateId: id }))
} catch (e) {
setLiked(id, false)
decrementLikeCount(id)
}
}, [setLiked, incrementLikeCount, decrementLikeCount, getSocialController])
const handleUnlike = useCallback(async (id: string) => {
setLiked(id, false)
decrementLikeCount(id)
try {
const social = getSocialController()
await handleError(() => social.unlike({ templateId: id }))
} catch (e) {
setLiked(id, true)
incrementLikeCount(id)
}
}, [setLiked, incrementLikeCount, decrementLikeCount, getSocialController])
// 收藏/取消收藏处理
const handleFavorite = useCallback(async (id: string) => {
setFavorited(id, true)
try {
const social = getSocialController()
await handleError(() => social.favorite({ templateId: id }))
} catch (e) {
setFavorited(id, false)
}
}, [setFavorited, getSocialController])
const handleUnfavorite = useCallback(async (id: string) => {
setFavorited(id, false)
try {
const social = getSocialController()
await handleError(() => social.unfavorite({ templateId: id }))
} catch (e) {
setFavorited(id, true)
}
}, [setFavorited, getSocialController])
// 状态判断
const showEmptyState = useMemo(() =>
!loading && !error && likes.length === 0,
[loading, error, likes.length]
)
const showErrorState = useMemo(() =>
!loading && !!error,
[loading, error]
)
const showTemplateList = useMemo(() =>
!loading && !error && likes.length > 0,
[loading, error, likes.length]
)
// 渲染模板卡片
const renderTemplateItem = useCallback(({ item }: { item: typeof likes[0] }) => {
if (!item.template?.id) return null
return (
)
}, [handleTemplatePress, handleLike, handleUnlike, handleFavorite, handleUnfavorite])
// 提取 key
const keyExtractor = useCallback((item: typeof likes[0]) => item.id || '', [])
// 列表头部组件
const ListHeaderComponent = useMemo(() => {
// 加载状态
if (loading) {
return
}
// 错误状态
if (showErrorState) {
return (
refetch()}
variant="error"
/>
)
}
// 空状态
if (showEmptyState) {
return (
execute()}
/>
)
}
return null
}, [loading, showErrorState, showEmptyState, refetch, execute])
// 列表底部组件
const ListFooterComponent = useMemo(() => {
if (loadingMore) {
return (
)
}
return null
}, [loadingMore])
// 获取有效的点赞列表(过滤掉没有 template.id 的)
const validLikes = useMemo(() =>
likes.filter(item => !!item.template?.id),
[likes]
)
return (
}
/>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#090A0B',
},
scrollView: {
flex: 1,
backgroundColor: '#090A0B',
},
scrollContent: {
paddingHorizontal: HORIZONTAL_PADDING,
paddingBottom: 20,
backgroundColor: '#090A0B',
},
columnWrapper: {
gap: CARD_GAP,
marginBottom: CARD_GAP,
},
loadingMoreContainer: {
paddingVertical: 20,
alignItems: 'center',
justifyContent: 'center',
},
})