blob: 382c9422aa4a08e1aaf1f60637d7c1ade92f9585 [file] [log] [blame]
// src/components/HomeFeed.jsx
import React, { useState, useEffect } from 'react'
import { ThumbsUp } from 'lucide-react'
import { fetchPosts, fetchPost } from '../api/posts'
import '../style/HomeFeed.css'
const categories = [
'推荐','穿搭','美食','彩妆','影视',
'职场','情感','家居','游戏','旅行','健身'
]
export default function HomeFeed() {
const [activeCat, setActiveCat] = useState('推荐')
const [items, setItems] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
async function loadPosts() {
try {
const list = await fetchPosts() // [{id, title, heat, created_at}, …]
// 第一轮:立即展示基础信息
const basicItems = list.map(p => ({
id: p.id,
title: p.title,
author: `作者 ${p.user_id || 'unknown'}`,
avatar: `https://i.pravatar.cc/40?img=${p.user_id || 1}`,
img: '', // 暂时为空
likes: p.heat || 0,
loading: true // 标记图片正在加载
}))
setItems(basicItems)
setLoading(false) // 基础内容已加载完成
// 第二轮:异步加载详情和图片
basicItems.forEach(async (item, index) => {
try {
const detail = await fetchPost(item.id)
setItems(prevItems =>
prevItems.map(prevItem =>
prevItem.id === item.id
? {
...prevItem,
img: detail.media_urls?.[0] || '',
loading: false
}
: prevItem
)
)
} catch (e) {
// 单个图片加载失败不影响其他
setItems(prevItems =>
prevItems.map(prevItem =>
prevItem.id === item.id
? { ...prevItem, loading: false }
: prevItem
)
)
}
})
} catch (e) {
setError(e.message)
setLoading(false)
}
}
loadPosts()
}, [])
return (
<div className="home-feed">
{/* 顶部分类 */}
<nav className="feed-tabs">
{categories.map(cat => (
<button
key={cat}
className={cat === activeCat ? 'tab active' : 'tab'}
onClick={() => setActiveCat(cat)}
>
{cat}
</button>
))}
</nav>
{/* 状态提示 */}
{loading ? (
<div className="loading">加载中…</div>
) : error ? (
<div className="error">加载失败:{error}</div>
) : (
/* 瀑布流卡片区 */
<div className="feed-grid">
{items.map(item => (
<div key={item.id} className="feed-card">
{item.loading ? (
<div className="card-img-placeholder">图片加载中...</div>
) : (
<img className="card-img" src={item.img} alt={item.title} />
)}
<h3 className="card-title">{item.title}</h3>
<div className="card-footer">
<div className="card-author">
<img className="avatar" src={item.avatar} alt={item.author} />
<span className="username">{item.author}</span>
</div>
<div className="card-likes">
<ThumbsUp size={16} />
<span className="likes-count">{item.likes}</span>
</div>
</div>
</div>
))}
</div>
)}
</div>
)
}