From 35bfd5312af82e7f323d669c52c63d97d6c23491 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Thu, 3 Feb 2022 22:48:22 -0800 Subject: [PATCH] caching relevant users for my disposal and starting to render content --- .../web/components/Conversations/LiveRoom.tsx | 19 +-- .../UserDetails/MasterAvatarGroup.tsx | 110 ++++++++++++++---- packages/web/recoil/MainRecoilDataHandler.tsx | 41 ++++++- packages/web/recoil/main.tsx | 14 ++- 4 files changed, 141 insertions(+), 43 deletions(-) diff --git a/packages/web/components/Conversations/LiveRoom.tsx b/packages/web/components/Conversations/LiveRoom.tsx index 94bee12..58676ca 100644 --- a/packages/web/components/Conversations/LiveRoom.tsx +++ b/packages/web/components/Conversations/LiveRoom.tsx @@ -1,24 +1,15 @@ import Conversation from "@nirvana/common/models/conversation"; import { Avatar } from "antd"; import { FaWalking } from "react-icons/fa"; +import { MasterAvatarGroupWithUserFetch } from "../UserDetails/MasterAvatarGroup"; export default function LiveRoom(props: { conversation: Conversation }) { return ( - - - - - - - + Engineering diff --git a/packages/web/components/UserDetails/MasterAvatarGroup.tsx b/packages/web/components/UserDetails/MasterAvatarGroup.tsx index e3810e4..7b61e3d 100644 --- a/packages/web/components/UserDetails/MasterAvatarGroup.tsx +++ b/packages/web/components/UserDetails/MasterAvatarGroup.tsx @@ -3,9 +3,15 @@ import { useAuth } from "../../contexts/authContext"; import { useRecoilValue, useRecoilState } from "recoil"; import { allRelevantContactsAtom } from "../../recoil/main"; import { userService } from "@nirvana/common/services"; +import { Avatar } from "antd"; -export default function MasterAvatarGroup(props: { listOfUsers: User[] }) { - const contactsMap = useRecoilValue(allRelevantContactsAtom); +const AVATAR_SHAPE = "square"; + +export default function MasterAvatarGroup(props: { + listOfUsers: User[]; + showCurrUser?: boolean; +}) { + const { currUser } = useAuth(); /** * Requirements: @@ -15,46 +21,100 @@ export default function MasterAvatarGroup(props: { listOfUsers: User[] }) { * if 6 more 'other' people, then show 3 and then one circle saying how many more there are */ - const { currUser } = useAuth(); + let finalistUsers: User[] = props.listOfUsers; - const listOfOtherUsers = props.listOfUsers.filter( - (lUser) => lUser.id != currUser!.uid - ); + if (!props.showCurrUser) { + finalistUsers = props.listOfUsers.filter( + (lUser) => lUser.id != currUser!.uid + ); + } + + // these are the finalists, so now show all of them depending on the number + if (finalistUsers?.length == 1) { + return ( + + ); + } + + if (finalistUsers?.length == 2) { + return ( + + + + + + + + + ); + } return ( - - {listOfOtherUsers.map((oUser) => ( - + + {finalistUsers.map((oUser) => ( + ))} - + ); } export function MasterAvatarGroupWithUserFetch(props: { listOfUserIds: string[]; + showCurrUser?: boolean; }) { - const [contactsMap, setContactsMap] = useRecoilState(allRelevantContactsAtom); + const relContactsMap = useRecoilValue(allRelevantContactsAtom); const { currUser } = useAuth(); - const listOfOtherUsers = props.listOfUserIds.filter( - (lUser) => lUser != currUser!.uid - ); + let listOfOtherUsers: string[] = [] as string[]; + if (props.showCurrUser) { + listOfOtherUsers = props.listOfUserIds; + } else { + listOfOtherUsers = props.listOfUserIds.filter( + (lUser) => lUser != currUser!.uid + ); + } const resultUsers: User[] = [] as User[]; - listOfOtherUsers.forEach(async (oUser) => { - if (contactsMap.has(oUser) && contactsMap.get(oUser) instanceof User) { - resultUsers.push(contactsMap.get(oUser)!); - } else { - // otherwise, fetch document from firestore and then set the cache - const retrievedUser = await userService.getUser(oUser); - - if (retrievedUser) { - setContactsMap(new Map(contactsMap.set(oUser, retrievedUser))); - } + console.log(listOfOtherUsers); + listOfOtherUsers.forEach((oUser) => { + if (relContactsMap.has(oUser)) { + resultUsers.push(relContactsMap.get(oUser)!); } }); - return ; + console.log("fetched users for frontend: ", resultUsers); + + return ; } diff --git a/packages/web/recoil/MainRecoilDataHandler.tsx b/packages/web/recoil/MainRecoilDataHandler.tsx index 3d4ffc5..cd896d0 100644 --- a/packages/web/recoil/MainRecoilDataHandler.tsx +++ b/packages/web/recoil/MainRecoilDataHandler.tsx @@ -15,15 +15,18 @@ import { } from "firebase/firestore"; import { useEffect } from "react"; import toast from "react-hot-toast"; -import { useRecoilState } from "recoil"; +import { useRecoilState, useSetRecoilState } from "recoil"; import { useAuth } from "../contexts/authContext"; import { + allRelevantContactsAtom, allRelevantConversationsAtom, allUsersConversationsAtom, + cachedRelevantContactsSelector, nirvanaUserDataAtom, } from "./main"; import { firestoreDb as db } from "../services/firebaseService"; +import { userService } from "@nirvana/common/services"; export default function MainRecoilDataHandler() { const { currUser } = useAuth(); @@ -34,6 +37,8 @@ export default function MainRecoilDataHandler() { allRelevantConversationsAtom ); + const [relContacts, setRelContacts] = useRecoilState(allRelevantContactsAtom); + useEffect(() => { const unsubs: Unsubscribe[] = [] as Unsubscribe[]; @@ -120,6 +125,40 @@ export default function MainRecoilDataHandler() { } }); + // build user's cache + let allUsersToCache: string[] = [] as string[]; + + arrayConvos.forEach((currconvo) => { + allUsersToCache = [...allUsersToCache, ...currconvo.activeMembers]; + }); + + console.log( + "going to try caching a bunch of users...maybe some duplicates", + allUsersToCache + ); + + // if this userId is in the contacts map, then cool + // otherwise fetch with userService + + allUsersToCache.map(async (oUser) => { + if ( + relContacts.has(oUser) && + relContacts.get(oUser) instanceof User + ) { + // do nothing + + console.log("user already cached, no need to re-cache"); + } else { + // otherwise, fetch document from firestore and then set the cache + const retrievedUser = await userService.getUser(oUser); + console.log("fetching user to add to cache"); + + if (retrievedUser) { + setRelContacts(new Map(relContacts.set(oUser, retrievedUser))); + } + } + }); + // add to the main convos atom, by modifying the current map setRelevantConvos((prevConvosMap) => { const newMap = new Map(prevConvosMap); diff --git a/packages/web/recoil/main.tsx b/packages/web/recoil/main.tsx index 5a72a30..fc518b1 100644 --- a/packages/web/recoil/main.tsx +++ b/packages/web/recoil/main.tsx @@ -5,8 +5,9 @@ import Conversation, { Link, } from "@nirvana/common/models/conversation"; import { User as NirvanaUser } from "@nirvana/common/models/user"; +import { userService } from "@nirvana/common/services"; -import { atom, selector, selectorFamily } from "recoil"; +import { atom, DefaultValue, selector, selectorFamily } from "recoil"; export enum RecoilActions { TEST = "TEST", @@ -110,11 +111,18 @@ export const allRelevantContactsAtom = atom>({ // todo: useful selector where a component can pass in a list of users // and return their full information -export const cachedRelevantContactsSelector = selector({ +export const cachedRelevantContactsSelector = selector({ key: RecoilActions.RELEVANT_CONTACTS_SELECTOR_CACHE, get: async ({ get }) => { - const currContacts: Map = get(allRelevantContactsAtom); return []; }, // selector set (pass in a user and build cache if somethings not in the cache already) + set: async ({ set, get }, listUserIdsToCache: string[]) => { + if (listUserIdsToCache instanceof DefaultValue) { + // set(newUserToCache) + return; + } + + const contactsMap = get(allRelevantContactsAtom); + }, });