import Layout from "@/components/Layout"; import { useAuth } from "@/contexts/AuthContext"; import { useEffect, useState } from "react"; import { Navigate } from "react-router-dom"; import LoadingScreen from "@/components/LoadingScreen"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { aethexSocialService } from "@/lib/aethex-social-service"; import { communityService, realtimeService } from "@/lib/supabase-service"; import PostComposer from "@/components/social/PostComposer"; import { useToast } from "@/hooks/use-toast"; import { Heart, MessageCircle, Share2, UserPlus, UserCheck, Volume2, VolumeX, } from "lucide-react"; interface FeedItem { id: string; authorId: string; authorName: string; authorAvatar?: string | null; caption?: string; mediaUrl?: string | null; mediaType: "video" | "image" | "none"; likes: number; comments: number; } function parseContent(content: string): { text?: string; mediaUrl?: string | null; mediaType: "video" | "image" | "none"; } { try { const obj = JSON.parse(content || "{}"); return { text: obj.text || content, mediaUrl: obj.mediaUrl || null, mediaType: obj.mediaType || (obj.mediaUrl ? /(mp4|webm|mov)$/i.test(obj.mediaUrl) ? "video" : "image" : "none"), }; } catch { return { text: content, mediaUrl: null, mediaType: "none" }; } } export default function Feed() { const { user, loading } = useAuth(); const { toast } = useToast(); const [isLoading, setIsLoading] = useState(true); const [following, setFollowing] = useState([]); const [items, setItems] = useState([]); const [muted, setMuted] = useState(true); useEffect(() => { const load = async () => { setIsLoading(true); try { const posts = await communityService.getPosts(20); if (user?.id) { const flw = await aethexSocialService.getFollowing(user.id); setFollowing(flw); } else { setFollowing([]); } const mapped: FeedItem[] = posts.map((p: any) => { const meta = parseContent(p.content); const author = p.user_profiles || {}; return { id: p.id, authorId: p.author_id, authorName: author.full_name || author.username || "User", authorAvatar: author.avatar_url, caption: meta.text, mediaUrl: meta.mediaUrl, mediaType: meta.mediaType, likes: p.likes_count ?? 0, comments: p.comments_count ?? 0, }; }); setItems(mapped); } catch (error) { console.error("Failed to load feed", error); setItems([]); } finally { setIsLoading(false); } }; load(); let cleanup: any = null; try { const sub = realtimeService.subscribeToCommunityPosts(() => load()); cleanup = () => { try { sub.unsubscribe?.(); } catch {} }; } catch {} return () => { cleanup?.(); }; }, [user, loading]); const isFollowingAuthor = (id: string) => following.includes(id); const toggleFollow = async (targetId: string) => { if (!user) { toast({ description: "Please sign in to manage follows." }); return; } try { if (isFollowingAuthor(targetId)) { await aethexSocialService.unfollowUser(user.id, targetId); setFollowing((s) => s.filter((x) => x !== targetId)); } else { await aethexSocialService.followUser(user.id, targetId); setFollowing((s) => Array.from(new Set([...s, targetId]))); } } catch (error: any) { toast({ variant: "destructive", title: "Action failed", description: error?.message || "Try again in a moment.", }); } }; const share = async (id: string) => { const url = `${location.origin}/feed#post-${id}`; try { if ((navigator as any).share) { await (navigator as any).share({ title: "AeThex", text: "Check this post", url, }); } else { await navigator.clipboard.writeText(url); toast({ description: "Link copied" }); } } catch {} }; // Guests can view the feed with demo content if (loading || isLoading) { return ( ); } return (
setIsLoading(true)} />
{items.length === 0 && (
No posts yet. Share something to start the feed.
)} {items.map((item) => (
{item.mediaType === "video" && item.mediaUrl ? (
))}
); }