import { FiActivity, FiSun } from "react-icons/fi"; import { useCallback, useMemo } from "react"; import { $selectedLineId } from "../../../controller/recoil"; import { Avatar } from "antd"; import LineIcon from "../lineIcon"; import { LineMemberState } from "@nirvana/core/models/line.model"; import MasterLineData from "@nirvana/core/models/masterLineData.model"; import moment from "moment"; import { useGetUserDetails } from "../../../controller/index"; import { useLineDataProvider } from "../../../controller/lineDataProvider"; import { useRecoilState } from "recoil"; // todo: send a much more comprehensive master line object? or just add properties to the // masterLineData object so that we don't have different models to maintain between client and server export default function LineRow({ masterLineData, }: { masterLineData: MasterLineData; }) { const [selectedLineId, setSelectedLineId] = useRecoilState($selectedLineId); const { data: userData } = useGetUserDetails(); // TODO: p2 move those socket handler functions to another hook so that they don't come from the context as this will cause each line row to re-render on changes to the context state/value const { handleUnTuneToLine } = useLineDataProvider(); /** show user line details */ const handleSelectLine = useCallback(() => { // if not already selected so that we are not changing this recoil atom of selected line id and causing a mess if (selectedLineId !== masterLineData.lineDetails._id.toString()) { setSelectedLineId((prevSelectedLineId) => { // untune myself from the previously selected if it was a temporary one/inbox // todo: p3: consolidate this logic as it's used in escape but different scenarios sort of so p3 if ( prevSelectedLineId && masterLineData.currentUserMember?.state === LineMemberState.INBOX ) handleUnTuneToLine(prevSelectedLineId); return masterLineData.lineDetails._id.toString(); }); } }, [setSelectedLineId, masterLineData, selectedLineId]); // take the source of truth list of memeberIds tuned in, and see if I'm in it const isUserTunedIn = useMemo( () => masterLineData.tunedInMemberIds?.includes(userData?.user?._id.toString()), [masterLineData.tunedInMemberIds, userData] ); /** * TODO: slowly add to this and fix based on added features * */ const renderActivityIcon = useMemo(() => { if (isUserTunedIn) return ; // if there is someone or me broadcasting here if (masterLineData.currentBroadcastersUserIds?.length > 0) return ; // if there is new activity blocks for me if (masterLineData.currentUserMember.lastVisitDate) return ( ); return ( ); }, [masterLineData, isUserTunedIn]); const renderRightActivity = useMemo(() => { // TODO: get the profile pictures of the broadcasters if (masterLineData.currentBroadcastersUserIds?.length > 0) return ( {masterLineData.otherUserObjects?.map((otherUser, index) => ( ))} ); // if there is new activity/black dot, then show relative time as little bolder? or too much? // TODO: compare last visit date to latest audio block if (masterLineData.currentUserMember.lastVisitDate) return ( {moment(masterLineData.currentUserMember.lastVisitDate).fromNow()} ); return ( {moment(masterLineData.currentUserMember.lastVisitDate).fromNow()} ); }, [masterLineData]); const profilePictures = useMemo(() => { const pictureSources: string[] = []; // ?don't add in my image as that's useless contextually? // if (userData?.user?.picture) pictureSources.push(userData.user.picture); masterLineData.otherUserObjects?.forEach((otherUser) => { if (otherUser.picture) pictureSources.push(otherUser.picture); }); return pictureSources; }, [masterLineData, userData]); return (
{/* status dot */} {renderActivityIcon} {profilePictures && }

{masterLineData.lineDetails.name}

{renderRightActivity}
); }