adding data listening, user getching and using more of recoil

This commit is contained in:
Arjun Patel
2022-02-03 17:14:22 -08:00
parent 4b65d6cd68
commit 6a6f0f4aef
20 changed files with 302 additions and 517 deletions
+74 -25
View File
@@ -1,6 +1,7 @@
import Conversation, {
ConversationMember,
} from "@nirvana/common/models/conversation";
import { User } from "@nirvana/common/models/user";
import Collections from "@nirvana/common/services/collections";
import {
collection,
@@ -14,14 +15,19 @@ import {
} from "firebase/firestore";
import { useEffect } from "react";
import toast from "react-hot-toast";
import { useRecoilState } from "recoil";
import { useRecoilState, useRecoilValue } from "recoil";
import { useAuth } from "../contexts/authContext";
import { allRelevantConversations, allUsersConversations } from "./main";
import {
allRelevantConversations,
allUsersConversations,
nirvanaUserDataAtom,
} from "./main";
const db = getFirestore();
export default function MainRecoilDataHandler() {
const { currUser } = useAuth();
const [nirvanaUser, setNirvanaUser] = useRecoilState(nirvanaUserDataAtom);
const [userConvos, setUserConvos] = useRecoilState(allUsersConversations);
const [relevantConvos, setRelevantConvos] = useRecoilState(
@@ -31,23 +37,20 @@ export default function MainRecoilDataHandler() {
useEffect(() => {
const unsubs: Unsubscribe[] = [] as Unsubscribe[];
const convoSubs: Unsubscribe[] = [] as Unsubscribe[];
(async function () {
try {
// get all conversations that I am a part of
const q = query(
collectionGroup(db, Collections.conversationMembers),
where("id", "==", currUser.uid)
where("id", "==", currUser?.uid)
);
const unsubscribeUserConvoMember = onSnapshot(q, (snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added" || change.type === "modified") {
const newConvoMember: ConversationMember =
change.doc.data() as ConversationMember;
newConvoMember.id = change.doc.id;
console.log("modified convo member found: ", change.doc.data());
const newConvoMember: ConversationMember =
change.doc.data() as ConversationMember;
newConvoMember.id = change.doc.id;
if (change.type === "added" || change.type === "modified") {
// update all user convo associations
setUserConvos((prevMap) => {
return new Map(prevMap.set(newConvoMember.id, newConvoMember));
@@ -56,25 +59,26 @@ export default function MainRecoilDataHandler() {
// 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),
(convoDoc) => {
const updatedConvo = convoDoc.data() as Conversation;
console.log("got convo data and subscribed");
console.log(updatedConvo);
// if (change.type === "added" && convoId) {
// const unsubConvo = onSnapshot(
// doc(db, Collections.conversations, convoId),
// (convoDoc) => {
// const updatedConvo = convoDoc.data() as Conversation;
// console.log("got convo data and subscribed");
// console.log(updatedConvo);
setRelevantConvos((prevMap) => {
return new Map(prevMap.set(convoId, updatedConvo));
});
}
);
// setRelevantConvos((prevMap) => {
// return new Map(prevMap.set(convoId, updatedConvo));
// });
// }
// );
// todo : remove specific listeners if they are no longer priority conversations
// // todo : remove specific listeners if they are no longer priority conversations
unsubs.push(unsubConvo);
}
// unsubs.push(unsubConvo);
// }
}
if (change.type === "removed") {
console.log("Removed convo member: ", change.doc.data());
@@ -83,6 +87,51 @@ export default function MainRecoilDataHandler() {
});
unsubs.push(unsubscribeUserConvoMember);
// get my current user profile and stay updated to my status
const unsubUser = onSnapshot(
doc(db, Collections.users, currUser!.uid),
(doc) => {
const nirvanaUser = doc.data() as User;
setNirvanaUser(nirvanaUser);
}
);
unsubs.push(unsubUser);
// get every conversation where I am in the activeMembers list
const convoQuery = query(
collection(db, Collections.conversations),
where("activeMembers", "array-contains", currUser!.uid)
);
const unsubConvosListener = onSnapshot(convoQuery, (snapshot) => {
const arrayConvos: Conversation[] = [];
snapshot.docChanges().forEach((change) => {
const newOrUpdatedConvo: Conversation =
change.doc.data() as Conversation;
newOrUpdatedConvo.id = change.doc.id;
if (change.type === "added" || change.type === "modified") {
arrayConvos.push(newOrUpdatedConvo);
}
if (change.type === "removed") {
// todo: if convo was removed for me, then take out of array
// arrayConvos.filter()
}
});
// add to the main convos atom, by modifying the current map
setRelevantConvos((prevConvosMap) => {
const newMap = new Map(prevConvosMap);
arrayConvos.forEach((currconvo) => {
newMap.set(currconvo.id, currconvo);
});
console.log("updated convos: ", newMap);
return newMap;
});
});
unsubs.push(unsubConvosListener);
} catch (error) {
console.log(error);
toast.error("Problem in retrieving data");
+20 -3
View File
@@ -1,21 +1,38 @@
import { User as FirebaseUser } from "@firebase/auth";
import Conversation, {
ConversationMember,
AudioClip,
Link,
} from "@nirvana/common/models/conversation";
import { User as NirvanaUser } from "@nirvana/common/models/user";
import { atom } from "recoil";
export enum RecoilActions {
TEST = "TEST",
CURR_PAGE_PATH = "CURR_PAGE_PATH",
ALL_COMPLETE_CONVERSATIONS = "ALL_COMPLETE_CONVERSATIONS",
ALL_USERS_CONVERSATION_RELATIONSHIPS = "ALL_USERS_CONVERSATION_RELATIONSHIPS",
ALL_RELEVANT_CONVERSATIONS = "ALL_RELEVANT_CONVERSATIONS",
USER_DATA = "USER_DATA",
}
// export const currPagePath = atom({
// key: RecoilActions.CURR_PAGE_PATH, // unique ID (with respect to other atoms/selectors)
// default: "/s", // default value (aka initial value)
export const nirvanaUserDataAtom = atom<NirvanaUser | null>({
key: RecoilActions.ALL_COMPLETE_CONVERSATIONS,
default: null,
});
// testing if we can import data in server side, but since it's next js we need firebase calls in client side
// import { conversationService } from "@nirvana/common/services";
// const getTest = (async () => await conversationService.test())();
// export const test = atom({
// key: RecoilActions.TEST, // unique ID (with respect to other atoms/selectors)
// default: getTest, // default value (aka initial value)
// });
export class CompleteConversation {