import { useState, useEffect } from "react"; import { useSelector, useDispatch } from "react-redux"; import { DMProfile, MemberSection, RecentFiles, UserProfilePopup, } from "./memberlist/index.js"; import { FiUserPlus } from "react-icons/fi"; import { CreateSpaceTips, CreateAgentTips } from "./createspace/index.js"; import { SettingsShortcuts } from "./settings/index.js"; import { setMemberSearchQuery, setSelectedMember, clearSelectedMember, } from "../store/slices/memberSlice"; import { fetchSpaceMembers } from "../store/slices/spaceSlice"; function MemberList({ activeView, activeRoom, createTab }) { const dispatch = useDispatch(); const { isDark } = useSelector((state) => state.theme); const { memberSearchQuery, selectedMember } = useSelector( (state) => state.member, ); const { selectedDMUser } = useSelector((state) => state.chat); const { activeConversation } = useSelector((state) => state.dm); const { spaces, membersMap, membersLoading, fetchedMembers } = useSelector( (state) => state.space, ); const appState = useSelector((state) => state.app); const view = activeView || appState.activeView; const room = activeRoom || appState.activeRoom; const activeSpace = appState.activeSpace; const [dmUser, setDmUser] = useState(null); // Detect if current room is a space room const { roomsMap } = useSelector((state) => state.space); const isSpaceRoom = room && Object.values(roomsMap).some( (rooms) => rooms.some((r) => r.id === room) ); const isBotRoom = room === "tro-ly-ai"; const isDM = view === "messages" || (room && !isSpaceRoom && !isBotRoom && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(room)); // Build dmUser from activeConversation useEffect(() => { if (!isDM) { setDmUser(null); return; } if (!room) { setDmUser(null); return; } if (activeConversation?.other_user) { const ou = activeConversation.other_user; setDmUser({ id: ou.id, name: ou.display_name || "Unknown", avatar: ou.avatar_url || null, color: ou.color || null, isOnline: ou.status === "online", isFriend: true, email: ou.email || "", bio: ou.bio || "", isBot: false, }); } else if (selectedDMUser) { setDmUser({ id: selectedDMUser.id || selectedDMUser.userId, name: selectedDMUser.name || "Unknown", avatar: selectedDMUser.avatar || null, color: selectedDMUser.color || null, isOnline: selectedDMUser.isOnline || false, isFriend: selectedDMUser.isFriend ?? true, email: selectedDMUser.email || "", bio: selectedDMUser.bio || "", isBot: selectedDMUser.isBot || false, }); } }, [room, isDM, selectedDMUser, activeConversation]); // 🆕 Lazy load space members when entering a space room useEffect(() => { if (!activeSpace || isDM) return; const hasMembers = membersMap[activeSpace] && membersMap[activeSpace].length > 0; const isFetched = fetchedMembers[activeSpace]; if (!hasMembers && !isFetched) { dispatch(fetchSpaceMembers(activeSpace)); } }, [activeSpace, isDM, dispatch, membersMap, fetchedMembers]); // CreateSpace view if (view === "createSpace") { return createTab === "agent" ? : ; } // Settings view if (view === "settings") { return ; } // DM view if (isDM) { return ; } // Space member list view — use real API data const spaceMembers = membersMap[activeSpace] || []; // Normalize API members to format MemberItem expects console.log("[MemberList] Raw spaceMembers:", spaceMembers); const normalizedMembers = spaceMembers.map((m) => { const displayName = m.displayName || m.display_name || m.username || m.email || "Unknown"; const isOnline = m.status === "online"; const avatarUrl = m.avatar || m.avatar_url; const normalized = { id: m.id || m.user_id, name: displayName, avatar: avatarUrl ? (avatarUrl.length <= 2 ? avatarUrl : displayName.charAt(0).toUpperCase()) : displayName.charAt(0).toUpperCase(), color: m.color || null, isOnline, isFriend: true, isBot: false, email: m.email || "", role: m.role || "member", }; console.log("[MemberList] Normalized member:", { original: m, normalized }); return normalized; }); console.log("[MemberList] Online:", normalizedMembers.filter((m) => m.isOnline).length, "Offline:", normalizedMembers.filter((m) => !m.isOnline).length); // Filter by search const filteredMembers = normalizedMembers.filter((m) => m.name.toLowerCase().includes(memberSearchQuery.toLowerCase()), ); const onlineMembers = filteredMembers.filter((m) => m.isOnline); const offlineMembers = filteredMembers.filter((m) => !m.isOnline); // Get current space name const currentSpace = spaces.find((s) => s.id === activeSpace); return (
Thành viên
dispatch(setMemberSearchQuery(e.target.value))} />
{/* User Profile Popup */} {selectedMember && ( dispatch(clearSelectedMember())} onSendMessage={(user) => { dispatch(clearSelectedMember()); }} /> )} {membersLoading && (
{[1, 2, 3, 4, 5].map((i) => (
))}
)} {!membersLoading && normalizedMembers.length === 0 && (
Chưa có thành viên nào
)} {!membersLoading && ( <> dispatch(setSelectedMember(member))} /> dispatch(setSelectedMember(member))} /> )}
); } export default MemberList;