feat: Add user likes tab and local timeline, update branding assets
- Add likes tab to user profiles displaying user's liked posts - Implement new `/api/users/[handle]/likes` endpoint to fetch user's liked posts - Add local timeline feed type to show only local node posts without fediverse content - Update favicon and add new logotext branding asset - Enhance search results with isLiked and isReposted status for authenticated users - Populate like and repost information in search posts endpoint - Update profile page tabs to conditionally show likes tab for non-bot users - Add loading states and empty state messaging for likes tab - Remove deprecated guide page - Improve bot settings page and content generation logic
This commit is contained in:
@@ -81,13 +81,15 @@ export default function ProfilePage() {
|
||||
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [posts, setPosts] = useState<Post[]>([]);
|
||||
const [likedPosts, setLikedPosts] = useState<Post[]>([]);
|
||||
const [currentUser, setCurrentUser] = useState<{ id: string; handle: string } | null>(null);
|
||||
const [isFollowing, setIsFollowing] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [activeTab, setActiveTab] = useState<'posts' | 'followers' | 'following'>('posts');
|
||||
const [activeTab, setActiveTab] = useState<'posts' | 'likes' | 'followers' | 'following'>('posts');
|
||||
const [followers, setFollowers] = useState<UserSummary[]>([]);
|
||||
const [following, setFollowing] = useState<UserSummary[]>([]);
|
||||
const [postsLoading, setPostsLoading] = useState(true);
|
||||
const [likesLoading, setLikesLoading] = useState(false);
|
||||
const [followersLoading, setFollowersLoading] = useState(false);
|
||||
const [followingLoading, setFollowingLoading] = useState(false);
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
@@ -106,6 +108,7 @@ export default function ProfilePage() {
|
||||
setSaveError(null);
|
||||
setFollowers([]);
|
||||
setFollowing([]);
|
||||
setLikedPosts([]);
|
||||
// Get current user
|
||||
fetch('/api/auth/me')
|
||||
.then(res => res.json())
|
||||
@@ -197,6 +200,15 @@ export default function ProfilePage() {
|
||||
.catch(() => setFollowing([]))
|
||||
.finally(() => setFollowingLoading(false));
|
||||
}
|
||||
|
||||
if (activeTab === 'likes') {
|
||||
setLikesLoading(true);
|
||||
fetch(`/api/users/${handle}/likes`)
|
||||
.then(res => res.json())
|
||||
.then(data => setLikedPosts(data.posts || []))
|
||||
.catch(() => setLikedPosts([]))
|
||||
.finally(() => setLikesLoading(false));
|
||||
}
|
||||
}, [activeTab, handle]);
|
||||
|
||||
const handleFollow = async () => {
|
||||
@@ -617,7 +629,10 @@ export default function ProfilePage() {
|
||||
|
||||
{/* Tabs */}
|
||||
<div style={{ display: 'flex', borderTop: '1px solid var(--border)' }}>
|
||||
{(['posts', 'followers', 'following'] as const).map(tab => (
|
||||
{(user?.isBot
|
||||
? ['posts', 'followers', 'following'] as const
|
||||
: ['posts', 'likes', 'followers', 'following'] as const
|
||||
).map(tab => (
|
||||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
@@ -663,6 +678,29 @@ export default function ProfilePage() {
|
||||
)
|
||||
)}
|
||||
|
||||
{activeTab === 'likes' && (
|
||||
likesLoading ? (
|
||||
<div style={{ padding: '48px', textAlign: 'center', color: 'var(--foreground-tertiary)' }}>
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
) : likedPosts.length === 0 ? (
|
||||
<div style={{ padding: '48px', textAlign: 'center', color: 'var(--foreground-tertiary)' }}>
|
||||
<p>No liked posts yet</p>
|
||||
</div>
|
||||
) : (
|
||||
likedPosts.map((post, index) => (
|
||||
<PostCard
|
||||
key={`${post.id}-${index}`}
|
||||
post={post}
|
||||
onLike={handleLike}
|
||||
onRepost={handleRepost}
|
||||
onComment={handleComment}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
))
|
||||
)
|
||||
)}
|
||||
|
||||
{activeTab === 'followers' && (
|
||||
followersLoading ? (
|
||||
<div style={{ padding: '24px', textAlign: 'center', color: 'var(--foreground-tertiary)' }}>
|
||||
|
||||
Reference in New Issue
Block a user