diff --git a/components/blocks/ui/VideoSocialButton.test.tsx b/components/blocks/ui/VideoSocialButton.test.tsx
index 9ad16e5..74be1d5 100644
--- a/components/blocks/ui/VideoSocialButton.test.tsx
+++ b/components/blocks/ui/VideoSocialButton.test.tsx
@@ -90,6 +90,20 @@ describe('VideoSocialButton Component', () => {
)
expect(getByText('50')).toBeTruthy()
})
+
+ it('应该在已点赞状态显示实心心形图标', () => {
+ const { getByTestId } = render(
+
+ )
+ expect(getByTestId('video-social-liked-like-button')).toBeTruthy()
+ })
+
+ it('应该在已收藏状态显示实心星形图标', () => {
+ const { getByTestId } = render(
+
+ )
+ expect(getByTestId('video-social-favorited-favorite-button')).toBeTruthy()
+ })
})
describe('交互', () => {
@@ -113,6 +127,26 @@ describe('VideoSocialButton Component', () => {
expect(onFavorite).toHaveBeenCalledTimes(1)
})
+ it('已点赞状态点击应该调用 onUnlike', () => {
+ const onUnlike = jest.fn()
+ const { getByTestId } = render(
+
+ )
+ const likeButton = getByTestId('video-social-on-unlike-like-button')
+ fireEvent.press(likeButton)
+ expect(onUnlike).toHaveBeenCalledTimes(1)
+ })
+
+ it('已收藏状态点击应该调用 onUnfavorite', () => {
+ const onUnfavorite = jest.fn()
+ const { getByTestId } = render(
+
+ )
+ const favoriteButton = getByTestId('video-social-on-unfavorite-favorite-button')
+ fireEvent.press(favoriteButton)
+ expect(onUnfavorite).toHaveBeenCalledTimes(1)
+ })
+
it('loading 状态下应该禁用按钮', () => {
const onLike = jest.fn()
const onFavorite = jest.fn()
@@ -136,6 +170,46 @@ describe('VideoSocialButton Component', () => {
})
})
+ describe('数量格式化', () => {
+ it('应该显示零数量', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('0')).toBeTruthy()
+ })
+
+ it('应该格式化千位数量', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('1.5k')).toBeTruthy()
+ expect(getByText('2.8k')).toBeTruthy()
+ })
+
+ it('应该格式化万位数量', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('1.5w')).toBeTruthy()
+ expect(getByText('2.8w')).toBeTruthy()
+ })
+
+ it('应该处理大数量', () => {
+ const { getByText } = render(
+
+ )
+ expect(getByText('9999')).toBeTruthy()
+ expect(getByText('8888')).toBeTruthy()
+ })
+
+ it('应该处理 undefined 数量', () => {
+ const { getAllByText } = render(
+
+ )
+ expect(getAllByText('0').length).toBe(2)
+ })
+ })
+
describe('样式', () => {
it('应该使用垂直布局', () => {
const { getByTestId } = render(
@@ -155,21 +229,6 @@ describe('VideoSocialButton Component', () => {
})
describe('边界情况', () => {
- it('应该处理零数量', () => {
- const { getByText } = render(
-
- )
- expect(getByText('0')).toBeTruthy()
- })
-
- it('应该处理大数量', () => {
- const { getByText } = render(
-
- )
- expect(getByText('9999')).toBeTruthy()
- expect(getByText('8888')).toBeTruthy()
- })
-
it('应该处理缺失的回调函数', () => {
const { getByTestId } = render(
diff --git a/components/blocks/ui/VideoSocialButton.tsx b/components/blocks/ui/VideoSocialButton.tsx
index 5d1be25..13f4ffd 100644
--- a/components/blocks/ui/VideoSocialButton.tsx
+++ b/components/blocks/ui/VideoSocialButton.tsx
@@ -1,7 +1,6 @@
-import React, { memo, useCallback, useMemo } from 'react'
-import { View, StyleSheet } from 'react-native'
-import { LikeButton, LikeButtonProps } from './LikeButton'
-import { FavoriteButton, FavoriteButtonProps } from './FavoriteButton'
+import React, { memo, useCallback } from 'react'
+import { View, StyleSheet, Text, Pressable } from 'react-native'
+import { Ionicons } from '@expo/vector-icons'
export interface VideoSocialButtonProps {
templateId: string
@@ -52,41 +51,53 @@ const VideoSocialButtonComponent: React.FC = ({
}
}, [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]
- )
+ // 格式化数量显示
+ const formatCount = (count?: number): string => {
+ if (count === undefined || count === null) return '0'
+ if (count >= 10000) {
+ return `${(count / 10000).toFixed(1)}w`
+ }
+ if (count >= 1000) {
+ return `${(count / 1000).toFixed(1)}k`
+ }
+ return count.toString()
+ }
return (
{/* 点赞按钮 */}
-
-
-
+
+
+
+
+ {formatCount(likeCount)}
+
{/* 收藏按钮 */}
-
-
-
+
+
+
+
+ {formatCount(favoriteCount)}
+
)
}
@@ -96,20 +107,33 @@ export const VideoSocialButton = memo(VideoSocialButtonComponent)
const styles = StyleSheet.create({
container: {
position: 'absolute',
- right: 13,
- bottom: 100,
+ right: 12,
+ bottom: 180,
flexDirection: 'column',
alignItems: 'center',
- gap: 16,
+ gap: 20,
},
- button: {
- width: 48,
- height: 48,
- borderRadius: 24,
- backgroundColor: 'rgba(25, 27, 31, 0.8)',
+ buttonWrapper: {
+ alignItems: 'center',
+ gap: 4,
+ },
+ iconContainer: {
+ width: 52,
+ height: 52,
+ borderRadius: 26,
+ backgroundColor: 'rgba(0, 0, 0, 0.3)',
justifyContent: 'center',
alignItems: 'center',
- borderWidth: 1,
- borderColor: 'rgba(47, 49, 52, 1)',
+ },
+ iconContainerActive: {
+ backgroundColor: 'rgba(255, 255, 255, 0.15)',
+ },
+ count: {
+ color: '#FFFFFF',
+ fontSize: 12,
+ fontWeight: '600',
+ textShadowColor: 'rgba(0, 0, 0, 0.5)',
+ textShadowOffset: { width: 0, height: 1 },
+ textShadowRadius: 2,
},
})