This commit is contained in:
imeepos
2026-01-28 18:46:44 +08:00
parent e478b126cd
commit 7c50d396e9
40 changed files with 6567 additions and 39 deletions

View File

@@ -22,8 +22,14 @@ import EditProfileDrawer from '@/components/drawer/EditProfileDrawer'
import Dropdown from '@/components/ui/dropdown'
import Toast from '@/components/ui/Toast'
import { signOut, useSession } from '@/lib/auth'
import { useTemplateGenerations, type TemplateGeneration } from '@/hooks'
import {
useTemplateGenerations,
useUserFavorites,
useUserLikes,
type TemplateGeneration
} from '@/hooks'
import { MySkeleton } from '@/components/skeleton/MySkeleton'
import { TabNavigation } from '@/components/blocks/home/TabNavigation'
import { useUserBalance } from '@/hooks/use-user-balance'
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
@@ -35,6 +41,8 @@ const GALLERY_ITEM_SIZE = Math.floor(
(screenWidth - GALLERY_HORIZONTAL_PADDING * 2 - GALLERY_GAP * 2) / 3
)
type TabType = 'works' | 'favorites' | 'likes'
// 获取作品封面图 - Webp优先
const getCoverUrl = (item: TemplateGeneration) =>
item.webpPreviewUrl || item.resultUrl?.[0] || item.template?.coverImageUrl
@@ -44,6 +52,10 @@ export default function My() {
const { t, i18n } = useTranslation()
const [editDrawerVisible, setEditDrawerVisible] = useState(false)
// Tab 状态
const [activeTab, setActiveTab] = useState<TabType>('works')
const [activeTabIndex, setActiveTabIndex] = useState(0)
// 获取积分余额
const { balance } = useUserBalance()
@@ -69,6 +81,41 @@ export default function My() {
hasMore,
} = useTemplateGenerations()
// 获取收藏列表
const {
favorites,
loading: favoritesLoading,
loadingMore: favoritesLoadingMore,
refetch: favoritesRefetch,
loadMore: favoritesLoadMore,
hasMore: favoritesHasMore,
} = useUserFavorites()
// 获取点赞列表
const {
likes,
loading: likesLoading,
loadingMore: likesLoadingMore,
refetch: likesRefetch,
loadMore: likesLoadMore,
hasMore: likesHasMore,
} = useUserLikes()
// Tab 配置
const tabs = [
t('my.tabs.works'),
t('my.tabs.favorites'),
t('my.tabs.likes')
]
// 处理 Tab 切换
const handleTabPress = useCallback((index: number) => {
setActiveTabIndex(index)
if (index === 0) setActiveTab('works')
else if (index === 1) setActiveTab('favorites')
else if (index === 2) setActiveTab('likes')
}, [])
// 调试日志
useEffect(() => {
console.log('📊 作品列表状态:', {
@@ -79,9 +126,11 @@ export default function My() {
})
}, [generations.length, loading, loadingMore, hasMore])
// 初始化加载作品列表
// 初始化加载数据
useEffect(() => {
refetch({ page: 1, limit: 20 })
favoritesRefetch()
likesRefetch()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
@@ -235,21 +284,17 @@ export default function My() {
</Pressable>
</View>
{/* "生成作品" 标题行 */}
<View style={styles.sectionHeader}>
<Text style={styles.sectionTitle}>{t('my.generatedWorks')}</Text>
<Pressable
style={styles.sectionMoreButton}
onPress={() => router.push('/worksList' as any)}
>
<SearchIcon />
</Pressable>
</View>
{/* Tab 导航 */}
<TabNavigation
tabs={tabs}
activeIndex={activeTabIndex}
onTabPress={handleTabPress}
/>
{/* 作品九宫格 */}
{loading ? (
{activeTab === 'works' && loading ? (
<MySkeleton />
) : (
) : activeTab === 'works' ? (
<ScrollView
testID="my-scroll-view"
style={styles.scrollView}
@@ -338,7 +383,77 @@ export default function My() {
)}
</View>
</ScrollView>
)}
) : activeTab === 'favorites' && favoritesLoading ? (
<MySkeleton />
) : activeTab === 'favorites' ? (
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.scrollContent}
showsVerticalScrollIndicator={false}
>
<View style={styles.galleryGrid}>
{favorites.length === 0 ? (
<View style={styles.emptyState}>
<Text style={styles.emptyStateText}>
{t('my.noFavorites')}
</Text>
</View>
) : (
favorites.map((item, index) => (
<Pressable
key={item.id}
style={[
styles.galleryItem,
index % 3 !== 2 && styles.galleryItemMarginRight,
styles.galleryItemMarginBottom,
]}
>
<Image
source={item.template?.coverImageUrl ? { uri: item.template.coverImageUrl } : require('@/assets/images/membership.png')}
style={styles.galleryImage}
contentFit="cover"
/>
</Pressable>
))
)}
</View>
</ScrollView>
) : activeTab === 'likes' && likesLoading ? (
<MySkeleton />
) : activeTab === 'likes' ? (
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.scrollContent}
showsVerticalScrollIndicator={false}
>
<View style={styles.galleryGrid}>
{likes.length === 0 ? (
<View style={styles.emptyState}>
<Text style={styles.emptyStateText}>
{t('my.noLikes')}
</Text>
</View>
) : (
likes.map((item, index) => (
<Pressable
key={item.id}
style={[
styles.galleryItem,
index % 3 !== 2 && styles.galleryItemMarginRight,
styles.galleryItemMarginBottom,
]}
>
<Image
source={item.template?.coverImageUrl ? { uri: item.template.coverImageUrl } : require('@/assets/images/membership.png')}
style={styles.galleryImage}
contentFit="cover"
/>
</Pressable>
))
)}
</View>
</ScrollView>
) : null}
{/* 编辑资料抽屉 */}
@@ -433,25 +548,6 @@ const styles = StyleSheet.create({
color: '#FFFFFF',
fontSize: 12,
},
sectionHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 12,
marginHorizontal: 12,
backgroundColor: '#090A0B',
},
sectionTitle: {
color: '#FFFFFF',
fontSize: 14,
fontWeight: '600',
},
sectionMoreButton: {
width: 20,
height: 20,
alignItems: 'center',
justifyContent: 'center',
},
galleryGrid: {
flexDirection: 'row',
flexWrap: 'wrap',