diff --git a/packages/common/services/index.ts b/packages/common/services/index.ts
index ebc8496..2903234 100644
--- a/packages/common/services/index.ts
+++ b/packages/common/services/index.ts
@@ -1,3 +1,6 @@
import ConversationService from "./conversationService";
+import UserService from "./userService";
export const conversationService = new ConversationService();
+
+export const userService = new UserService();
diff --git a/packages/common/services/userService.tsx b/packages/common/services/userService.ts
similarity index 97%
rename from packages/common/services/userService.tsx
rename to packages/common/services/userService.ts
index dd69436..95cb710 100644
--- a/packages/common/services/userService.tsx
+++ b/packages/common/services/userService.ts
@@ -12,7 +12,7 @@ import {
DocumentSnapshot,
} from "firebase/firestore";
import { User, UserStatus } from "../models/user";
-import { Collections } from "./collections";
+import Collections from "./collections";
export default class UserService {
private db: Firestore = getFirestore();
diff --git a/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx b/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx
index c4376c8..22e4cd6 100644
--- a/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx
+++ b/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx
@@ -152,6 +152,7 @@ export default function CreateConversation() {
});
// add myself to this collection of members
+ arrActiveMembers.push(currUser!.uid);
members.push(
new ConversationMember(
currUser!.uid,
diff --git a/packages/web/components/UserDetails/MasterAvatarGroup.tsx b/packages/web/components/UserDetails/MasterAvatarGroup.tsx
new file mode 100644
index 0000000..e3810e4
--- /dev/null
+++ b/packages/web/components/UserDetails/MasterAvatarGroup.tsx
@@ -0,0 +1,60 @@
+import { User } from "@nirvana/common/models/user";
+import { useAuth } from "../../contexts/authContext";
+import { useRecoilValue, useRecoilState } from "recoil";
+import { allRelevantContactsAtom } from "../../recoil/main";
+import { userService } from "@nirvana/common/services";
+
+export default function MasterAvatarGroup(props: { listOfUsers: User[] }) {
+ const contactsMap = useRecoilValue(allRelevantContactsAtom);
+
+ /**
+ * Requirements:
+ * if one two users in the conversation: then just get the one that is not the currUser
+ * if three people => show icon of the other two people
+ * if 4 people => show 3 people in triangle fashion
+ * if 6 more 'other' people, then show 3 and then one circle saying how many more there are
+ */
+
+ const { currUser } = useAuth();
+
+ const listOfOtherUsers = props.listOfUsers.filter(
+ (lUser) => lUser.id != currUser!.uid
+ );
+
+ return (
+
+ {listOfOtherUsers.map((oUser) => (
+
+ ))}
+
+ );
+}
+
+export function MasterAvatarGroupWithUserFetch(props: {
+ listOfUserIds: string[];
+}) {
+ const [contactsMap, setContactsMap] = useRecoilState(allRelevantContactsAtom);
+
+ const { currUser } = useAuth();
+
+ const 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)));
+ }
+ }
+ });
+
+ return ;
+}
diff --git a/packages/web/recoil/MainRecoilDataHandler.tsx b/packages/web/recoil/MainRecoilDataHandler.tsx
index c452971..3d4ffc5 100644
--- a/packages/web/recoil/MainRecoilDataHandler.tsx
+++ b/packages/web/recoil/MainRecoilDataHandler.tsx
@@ -15,23 +15,23 @@ import {
} from "firebase/firestore";
import { useEffect } from "react";
import toast from "react-hot-toast";
-import { useRecoilState, useRecoilValue } from "recoil";
+import { useRecoilState } from "recoil";
import { useAuth } from "../contexts/authContext";
import {
- allRelevantConversations,
- allUsersConversations,
+ allRelevantConversationsAtom,
+ allUsersConversationsAtom,
nirvanaUserDataAtom,
} from "./main";
-const db = getFirestore();
+import { firestoreDb as db } from "../services/firebaseService";
export default function MainRecoilDataHandler() {
const { currUser } = useAuth();
const [nirvanaUser, setNirvanaUser] = useRecoilState(nirvanaUserDataAtom);
- const [userConvos, setUserConvos] = useRecoilState(allUsersConversations);
+ const [userConvos, setUserConvos] = useRecoilState(allUsersConversationsAtom);
const [relevantConvos, setRelevantConvos] = useRecoilState(
- allRelevantConversations
+ allRelevantConversationsAtom
);
useEffect(() => {
@@ -51,16 +51,17 @@ export default function MainRecoilDataHandler() {
newConvoMember.id = change.doc.id;
if (change.type === "added" || change.type === "modified") {
+ // if we are adding a new convo relevant to me, then start a convo listener for this convo
+ const convoId = change.doc.ref.parent.parent!.id;
+
// update all user convo associations
setUserConvos((prevMap) => {
- return new Map(prevMap.set(newConvoMember.id, newConvoMember));
+ return new Map(prevMap.set(convoId, newConvoMember));
});
// if we are adding a new convo relevant to me, then start a convo listener for this convo
- const convoId = change.doc.ref.parent.parent?.id;
// find if this is a done, later, or inbox, and only add listeners accordingly
- console.log(convoId);
// if (change.type === "added" && convoId) {
// const unsubConvo = onSnapshot(
// doc(db, Collections.conversations, convoId),
diff --git a/packages/web/recoil/main.tsx b/packages/web/recoil/main.tsx
index 17a2abc..5a72a30 100644
--- a/packages/web/recoil/main.tsx
+++ b/packages/web/recoil/main.tsx
@@ -6,7 +6,7 @@ import Conversation, {
} from "@nirvana/common/models/conversation";
import { User as NirvanaUser } from "@nirvana/common/models/user";
-import { atom, selector } from "recoil";
+import { atom, selector, selectorFamily } from "recoil";
export enum RecoilActions {
TEST = "TEST",
@@ -20,6 +20,9 @@ export enum RecoilActions {
SORTED_CONVERSATIONS = "SORTED_CONVERSATIONS",
LIVE_ROOMS = "LIVE_ROOMS",
+ ALL_RELEVANT_CONTACTS = "ALL_RELEVANT_CONTACTS",
+ RELEVANT_CONTACTS_SELECTOR_CACHE = "RELEVANT_CONTACTS_SELECTOR_CACHE",
+
USER_DATA = "USER_DATA",
}
@@ -38,60 +41,30 @@ export const nirvanaUserDataAtom = atom({
// default: getTest, // default value (aka initial value)
// });
-export class CompleteConversation {
- id: string; // conversation id
-
- get isLive(): boolean {
- return this.members?.length > 0;
- }
-
- // method/property for knowing if this there is a new activity for me in this conversation
-
- // method/property for getting the latest link if valid
-
- // method/property to get the latest convo chunk/last person talking
-
- conversation: Conversation;
-
- constructor(convo: Conversation) {
- this.conversation = convo;
- this.id = this.conversation.id;
- }
-
- userMember?: ConversationMember;
-
- members: ConversationMember[] = [] as ConversationMember[];
- audioClips: AudioClip[] = [] as AudioClip[];
- links: Link[] = [] as Link[];
-}
-
-// map cache of all complete conversation objects
-export const allCompleteConversations = atom({
- key: RecoilActions.ALL_COMPLETE_CONVERSATIONS,
- default: new Map(),
-});
-
-// map cache of all relevant users
-
-// selector for the convos that have members in the live room
-
-// selectors for convos: inbox/default, live, later, done, priority
-
// approach: fill in all "bottom" level atoms, and then build the tree later with selectors
-export const allUsersConversations = atom({
+// convo id -> userMember object
+export const allUsersConversationsAtom = atom({
key: RecoilActions.ALL_USERS_CONVERSATION_RELATIONSHIPS,
default: new Map(),
});
-export const allRelevantConversations = atom({
+export const allRelevantConversationsAtom = atom({
key: RecoilActions.ALL_RELEVANT_CONVERSATIONS,
default: new Map(),
+ effects: [
+ ({ onSet }) => {
+ onSet((newMap) => {
+ //go through and make sure that our relevant user's cache is up to date
+ // const allUsersInConvos = newMap.values()
+ });
+ },
+ ],
});
export const sortedRoomSelector = selector({
key: RecoilActions.SORTED_CONVERSATIONS,
get: ({ get }) => {
- const relConvos = get(allRelevantConversations);
+ const relConvos = get(allRelevantConversationsAtom);
const convosArr: Conversation[] = Array.from(relConvos.values());
convosArr.sort((a, b) => {
@@ -113,7 +86,9 @@ export const sortedRoomSelector = selector({
},
});
-// get all rooms with active members in the room, and
+// selectors for convos: inbox/default, live, later, done, priority
+
+// get all rooms with active members in the room
export const liveRoomsSelector = selector({
key: RecoilActions.LIVE_ROOMS,
get: ({ get }) => {
@@ -125,3 +100,21 @@ export const liveRoomsSelector = selector({
return liveRooms;
},
});
+
+// map cache of all relevant users
+// get all of the users in all of the conversations, once through a simple service call
+export const allRelevantContactsAtom = atom