import React, { Suspense, useEffect, useState, useCallback } from "react"; import { useTranslation } from "react-i18next"; import TopBar from "./components/Layout/TopBar"; import PostList from "./components/Posts/PostList"; import ContentFilters from "./components/Filters/ContentFilters"; import IslandUniverse from "./components/Island/IslandUniverse"; import IslandViewer from "./components/Island/IslandViewer"; import ChatContainer from "./components/Chat/ChatContainer"; import { fetchIslandByUsername } from "./api/client"; const MapView = React.lazy(() => import("./components/Map/MapView")); const THEME_KEY = "sociowire:theme"; const CONTENT_FILTER_KEY = "sociowire:contentFilter"; export default function App() { const { t } = useTranslation(); const [theme, setTheme] = useState("blue"); // Clean up Facebook OAuth hash fragment (#_=_) useEffect(() => { if (window.location.hash === "#_=_") { if (window.history.replaceState) { window.history.replaceState(null, "", window.location.pathname + window.location.search); } else { window.location.hash = ""; } } }, []); // Wall state (lifted from MapView) const [wallPosts, setWallPosts] = useState([]); const [wallLoading, setWallLoading] = useState(false); const [wallError, setWallError] = useState(""); const [selectedPost, setSelectedPost] = useState(null); // Content filter (shared between map and sociowall) - persisted // "all" | "links" | "video" | "image" | "text" | "live" | "event" const [contentFilter, setContentFilter] = useState(() => { try { const saved = localStorage.getItem(CONTENT_FILTER_KEY); if (saved && ["all", "links", "video", "image", "text", "live", "event"].includes(saved)) { return saved; } } catch {} return "all"; }); // Save content filter to localStorage useEffect(() => { try { localStorage.setItem(CONTENT_FILTER_KEY, contentFilter); } catch {} }, [contentFilter]); // Island Universe & Island Viewer state const [showUniverse, setShowUniverse] = useState(false); const [selectedIsland, setSelectedIsland] = useState(null); const handlePostsState = useCallback((next) => { if (!next) return; if (Array.isArray(next.posts)) setWallPosts(next.posts); setWallLoading(!!next.loading); setWallError(next.error || ""); }, []); const handlePostDeleted = useCallback((postId) => { setWallPosts((prev) => prev.filter((p) => (p.id ?? p._id) !== postId)); if (selectedPost && (selectedPost.id ?? selectedPost._id) === postId) { setSelectedPost(null); } }, [selectedPost]); const handlePostUpdated = useCallback((updatedPost) => { if (!updatedPost) return; setWallPosts((prev) => prev.map((p) => (p.id ?? p._id) === (updatedPost.id ?? updatedPost._id) ? { ...p, ...updatedPost } : p ) ); }, []); // charge le thème au démarrage useEffect(() => { if (typeof window === "undefined") return; try { const saved = localStorage.getItem(THEME_KEY); if (saved === "dark" || saved === "blue" || saved === "light") { setTheme(saved); document.body.setAttribute("data-theme", saved); } else { setTheme("blue"); document.body.setAttribute("data-theme", "blue"); } } catch (e) { setTheme("blue"); document.body.setAttribute("data-theme", "blue"); } }, []); // applique / sauvegarde le thème useEffect(() => { if (typeof window === "undefined") return; try { document.body.setAttribute("data-theme", theme); localStorage.setItem(THEME_KEY, theme); } catch (e) { // ignore } }, [theme]); useEffect(() => { const onScroll = () => { const threshold = window.innerHeight * 0.55; const expanded = window.scrollY > threshold; document.body.classList.toggle("sw-wall-expanded", expanded); }; window.addEventListener("scroll", onScroll, { passive: true }); onScroll(); return () => window.removeEventListener("scroll", onScroll); }, []); // Island Universe handlers const handleOpenUniverse = () => { setShowUniverse(true); }; const handleCloseUniverse = () => { setShowUniverse(false); }; const handleIslandClick = (island) => { setShowUniverse(false); // Close universe setSelectedIsland(island); // Open island viewer }; const handleOpenUserIsland = async (uname) => { const u = (uname || "").trim(); if (!u) return; try { const island = await fetchIslandByUsername(u); if (island) { setShowUniverse(false); setSelectedIsland(island); } } catch {} }; return (
{t('map.loadingMap')}
{t('map.warmingUp')}
} >
{/* BELOW THE MAP (page scroll like Facebook) */}
{/* Content filters - shared between map and sociowall */}
{/* SocioWall header inside panel */}

SOCIOWALL

{t('islands.communities')}

{t('islands.exploreIslands')}

{t('islands.islandsDescription')}

{/* Chat System */}
{/* Island Universe Modal */} {showUniverse && ( )} {/* Island Viewer Modal */} {selectedIsland && ( setSelectedIsland(null)} /> )}
); }