import React, { useEffect } from "react"; /* UI */ import TitleBar from "./Titlebar"; import Profile from "./Profile"; import PhotoViewer from "./PhotoViewer"; import HomePage from "./HomePage"; import FriendsListPage from "./FriendsListPage"; /* Router */ import { BrowserRouter as Router, Switch, Route, useLocation, } from "react-router-dom"; /* Layout */ import Container from "react-bootstrap/Container"; /* Redux */ import { useDispatch, useSelector } from "react-redux"; import { friendsListPageSet, profileLinkSet, watchSet, } from "../features/accountPage/accountPageSlice"; /* Mock-backend helpers */ import { currentUserOffline, currentUserOnline, subscribeCurrentUser, subscribeUsers, subscribePosts, } from "../backend/backend"; /* ------------------------------------------------------------------ */ /* Keep Redux in sync with the current pathname (once per navigation) */ /* ------------------------------------------------------------------ */ const RouteStateSync = () => { const dispatch = useDispatch(); const location = useLocation(); useEffect(() => { const { pathname } = location; /* friends list page */ dispatch(friendsListPageSet(pathname.startsWith("/fakebook/friends/list"))); /* watch page (videos feed) */ dispatch(watchSet(pathname.startsWith("/fakebook/watch"))); }, [location, dispatch]); return null; // renders nothing }; /* ------------------------------------------------------------------ */ const UserAccount = () => { const dispatch = useDispatch(); /* Redux selectors */ const profileLink = useSelector((state) => state.accountPage.profileLink); const currentUser = useSelector((state) => state.currentUser); const users = useSelector((state) => state.users); /* -------------------------------------------------- */ /* Firestore-like subscriptions & online/offline flag */ /* -------------------------------------------------- */ useEffect(() => { const unsubCurrentUser = subscribeCurrentUser(); const unsubUsers = subscribeUsers(); const unsubPosts = subscribePosts(); /* mark user online */ currentUserOnline(); /* window closed or refreshed */ const beforeUnload = () => currentUserOffline(); window.addEventListener("beforeunload", beforeUnload); /* tab visibility switch */ const visChange = () => document.visibilityState === "visible" ? currentUserOnline() : currentUserOffline(); document.addEventListener("visibilitychange", visChange); /* cleanup */ return () => { unsubCurrentUser(); unsubUsers(); unsubPosts(); window.removeEventListener("beforeunload", beforeUnload); document.removeEventListener("visibilitychange", visChange); }; }, []); /* -------------------------------------------------- */ /* Build unique profile link (.index appended once) */ /* -------------------------------------------------- */ useEffect(() => { if (!currentUser) return; /* remove any existing trailing ".number" */ const base = profileLink.replace(/\.\d+$/, ""); const newLink = currentUser.index && currentUser.index > 0 ? `${base}.${currentUser.index}` : base; dispatch(profileLinkSet(newLink)); }, [currentUser, profileLink, dispatch]); /* Loading guard */ if (!currentUser || users.length === 0) { return
…Loading
; } /* -------------------------------------------------- */ /* Render */ /* -------------------------------------------------- */ return (
{/* Friends list ------------------------------------------------ */} {/* Single photo ----------------------------------------------- */} {/* Watch (video feed) ----------------------------------------- */} } /> {/* User profile ----------------------------------------------- */} {/* News-feed root --------------------------------------------- */} } />
); }; export default UserAccount;