expo-popcore-app/components/blocks/ui/SocialActionBar.tsx

111 lines
2.6 KiB
TypeScript

import React, { memo, useCallback, useMemo } from 'react'
import { View, StyleSheet, ViewStyle } from 'react-native'
import { LinearGradient } from 'expo-linear-gradient'
import { LikeButton, LikeButtonProps } from './LikeButton'
import { FavoriteButton, FavoriteButtonProps } from './FavoriteButton'
export interface SocialActionBarProps {
templateId: string
liked?: boolean
favorited?: boolean
likeCount?: number
favoriteCount?: number
loading?: boolean
onLike?: () => void
onUnlike?: () => void
onFavorite?: () => void
onUnfavorite?: () => void
testID?: string
}
const SocialActionBarComponent: React.FC<SocialActionBarProps> = ({
templateId,
liked = false,
favorited = false,
likeCount,
favoriteCount,
loading = false,
onLike,
onUnlike,
onFavorite,
onUnfavorite,
testID,
}) => {
// 处理点赞按钮点击
const handleLikePress = useCallback(() => {
if (!loading) {
if (liked) {
onUnlike?.()
} else {
onLike?.()
}
}
}, [loading, liked, onLike, onUnlike])
// 处理收藏按钮点击
const handleFavoritePress = useCallback(() => {
if (!loading) {
if (favorited) {
onUnfavorite?.()
} else {
onFavorite?.()
}
}
}, [loading, favorited, onFavorite, onUnfavorite])
// LikeButton 的 props
const likeButtonProps: LikeButtonProps = useMemo(
() => ({
liked,
loading,
count: likeCount,
onPress: handleLikePress,
testID: testID ? `${testID}-like-button` : undefined,
}),
[liked, loading, likeCount, handleLikePress, testID]
)
// FavoriteButton 的 props
const favoriteButtonProps: FavoriteButtonProps = useMemo(
() => ({
favorited,
loading,
count: favoriteCount,
onPress: handleFavoritePress,
testID: testID ? `${testID}-favorite-button` : undefined,
}),
[favorited, loading, favoriteCount, handleFavoritePress, testID]
)
return (
<LinearGradient
colors={['rgba(17, 17, 17, 0)', 'rgba(17, 17, 17, 0.9)']}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 1 }}
style={styles.container}
testID={testID}
>
<View style={styles.content}>
<LikeButton {...likeButtonProps} />
<FavoriteButton {...favoriteButtonProps} />
</View>
</LinearGradient>
)
}
export const SocialActionBar = memo(SocialActionBarComponent)
const styles = StyleSheet.create({
container: {
width: '100%',
paddingVertical: 12,
paddingHorizontal: 16,
} as ViewStyle,
content: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
gap: 24,
},
})