import { useEffect, useState } from 'react' import { Group } from 'common/group' import { User } from 'common/user' import { listenForGroup, listenForGroups, listenForMemberGroups, listenForOpenGroups, listGroups, } from 'web/lib/firebase/groups' import { getUser, getUsers } from 'web/lib/firebase/users' import { filterDefined } from 'common/util/array' import { Contract } from 'common/contract' import { uniq } from 'lodash' export const useGroup = (groupId: string | undefined) => { const [group, setGroup] = useState() useEffect(() => { if (groupId) return listenForGroup(groupId, setGroup) }, [groupId]) return group } export const useGroups = () => { const [groups, setGroups] = useState() useEffect(() => { return listenForGroups(setGroups) }, []) return groups } export const useOpenGroups = () => { const [groups, setGroups] = useState([]) useEffect(() => { return listenForOpenGroups(setGroups) }, []) return groups } export const useMemberGroups = ( userId: string | null | undefined, options?: { withChatEnabled: boolean }, sort?: { by: 'mostRecentChatActivityTime' | 'mostRecentContractAddedTime' } ) => { const [memberGroups, setMemberGroups] = useState() useEffect(() => { if (userId) return listenForMemberGroups( userId, (groups) => { if (options?.withChatEnabled) return setMemberGroups( filterDefined( groups.filter((group) => group.chatDisabled !== true) ) ) return setMemberGroups(groups) }, sort ) // eslint-disable-next-line react-hooks/exhaustive-deps }, [options?.withChatEnabled, sort?.by, userId]) return memberGroups } // Note: We cache member group ids in localstorage to speed up the initial load export const useMemberGroupIds = (user: User | null | undefined) => { const [memberGroupIds, setMemberGroupIds] = useState( undefined ) useEffect(() => { if (user) { const key = `member-groups-${user.id}` const memberGroupJson = localStorage.getItem(key) if (memberGroupJson) { setMemberGroupIds(JSON.parse(memberGroupJson)) } return listenForMemberGroups(user.id, (Groups) => { const groupIds = Groups.map((group) => group.id) setMemberGroupIds(groupIds) localStorage.setItem(key, JSON.stringify(groupIds)) }) } }, [user]) return memberGroupIds } export function useMembers(group: Group, max?: number) { const [members, setMembers] = useState([]) useEffect(() => { const { memberIds } = group if (memberIds.length > 0) { listMembers(group, max).then((members) => setMembers(members)) } }, [group, max]) return members } export async function listMembers(group: Group, max?: number) { const { memberIds } = group const numToRetrieve = max ?? memberIds.length if (memberIds.length === 0) return [] if (numToRetrieve > 100) return (await getUsers()).filter((user) => group.memberIds.includes(user.id) ) return await Promise.all(group.memberIds.slice(0, numToRetrieve).map(getUser)) } export const useGroupsWithContract = (contract: Contract) => { const [groups, setGroups] = useState([]) useEffect(() => { if (contract.groupSlugs) listGroups(uniq(contract.groupSlugs)).then((groups) => setGroups(filterDefined(groups)) ) }, [contract.groupSlugs]) return groups }