diff --git a/documentation/ConversationsFlow.md b/documentation/ConversationsFlow.md
index 9e90008..b49a8a5 100644
--- a/documentation/ConversationsFlow.md
+++ b/documentation/ConversationsFlow.md
@@ -53,8 +53,11 @@ all conversations in the conversation map and place in right category /\*\*
### Data Needed
- live conversations going on right now and which people are in them
-- all inbox-like conversations such as today, last 7 days, etc
- a. being able to play the last message in the conversation with a play button
- b. see if there is a new update in the conversation which I have not viewed
-- priority conversations
- a. need to be able to play any messages from there
+- all inbox-like conversations such as today, last 7 days, etc a. being able to
+ play the last message in the conversation with a play button b. see if there
+ is a new update in the conversation which I have not viewed c. how many new
+ audio clips or links are in the conversation
+- priority conversations a. need to be able to play last convo chunk from here
+ and reply from here
+
+- drawer a. need all links in all conversations where I am active b.
diff --git a/packages/common/models/conversation.ts b/packages/common/models/conversation.ts
index 9ca861f..563cf35 100644
--- a/packages/common/models/conversation.ts
+++ b/packages/common/models/conversation.ts
@@ -1,22 +1,6 @@
import { v4 as uuid } from "uuid";
import { Timestamp } from "firebase/firestore";
-export class CompleteConversation {
- id: string; // conversation id
-
- 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[];
-}
export default class Conversation {
id: string = uuid();
diff --git a/packages/common/services/conversationService.ts b/packages/common/services/conversationService.ts
index d27c608..5be04ad 100644
--- a/packages/common/services/conversationService.ts
+++ b/packages/common/services/conversationService.ts
@@ -41,6 +41,7 @@ export default class ConversationService {
{
...conversation,
createdDate: serverTimestamp(),
+ lastActivityDate: serverTimestamp(),
},
{ merge: true }
);
diff --git a/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx b/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx
index bc54f04..cb3aa8c 100644
--- a/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx
+++ b/packages/web/components/FullPageExperiences/CreateConversation.tsx.tsx
@@ -1,5 +1,5 @@
import { User } from "@nirvana/common/models/user";
-import { useEffect, useMemo, useRef, useState } from "react";
+import { RefObject, useEffect, useMemo, useRef, useState } from "react";
import { FaPlus, FaRegTimesCircle, FaSearch } from "react-icons/fa";
import { usersIndex } from "../../services/algoliaSearchService";
import SimpleLoadingDot from "../Loading/SimpleLoadingDot";
@@ -164,10 +164,10 @@ export default function CreateConversation() {
toast.success("Created Conversation");
- // router.push({
- // pathname: Routes.home,
- // query: { page: QueryRoutes.convos },
- // });
+ router.push({
+ pathname: Routes.home,
+ query: { page: QueryRoutes.convos },
+ });
} catch (error) {
toast.error("Problem in creating conversation");
}
diff --git a/packages/web/components/MainTabsOrPages/Header.tsx b/packages/web/components/MainTabsOrPages/Header.tsx
index 187f49b..5c6a74a 100644
--- a/packages/web/components/MainTabsOrPages/Header.tsx
+++ b/packages/web/components/MainTabsOrPages/Header.tsx
@@ -17,7 +17,6 @@ import UserStatusBubble from "../UserDetails/UserStatusBubble";
export default function Header() {
const { currUser } = useAuth();
- console.log(currUser);
const router = useRouter();
diff --git a/packages/web/pages/s/index.tsx b/packages/web/pages/s/index.tsx
index 1f88a1f..664ba8b 100644
--- a/packages/web/pages/s/index.tsx
+++ b/packages/web/pages/s/index.tsx
@@ -13,8 +13,11 @@ import KeyboardShortcutHandler from "../../components/MainTabsOrPages/KeyboardSh
import SearchResults from "../../components/FullPageExperiences/SearchResults";
import { QueryRoutes, Routes } from "@nirvana/common/helpers/routes";
import ViewConvo from "../../components/MainTabsOrPages/ViewConvo";
+import MainRecoilDataHandler from "../../recoil/MainRecoilDataHandler";
export default function Me() {
+ // TODO: if not authenticated, take user away
+
// figure out what content to render from here
const router = useRouter();
const currPage = router.query.page;
@@ -113,6 +116,8 @@ export default function Me() {
Me.getLayout = function (content: ReactElement) {
return (
+
+
diff --git a/packages/web/recoil/MainRecoilDataHandler.tsx b/packages/web/recoil/MainRecoilDataHandler.tsx
new file mode 100644
index 0000000..351a271
--- /dev/null
+++ b/packages/web/recoil/MainRecoilDataHandler.tsx
@@ -0,0 +1,100 @@
+import Conversation, {
+ ConversationMember,
+} from "@nirvana/common/models/conversation";
+import Collections from "@nirvana/common/services/collections";
+import {
+ collection,
+ collectionGroup,
+ doc,
+ getFirestore,
+ onSnapshot,
+ query,
+ Unsubscribe,
+ where,
+} from "firebase/firestore";
+import { useEffect } from "react";
+import toast from "react-hot-toast";
+import { useRecoilState } from "recoil";
+import { useAuth } from "../contexts/authContext";
+import { allRelevantConversations, allUsersConversations } from "./main";
+
+const db = getFirestore();
+
+export default function MainRecoilDataHandler() {
+ const { currUser } = useAuth();
+
+ const [userConvos, setUserConvos] = useRecoilState(allUsersConversations);
+ const [relevantConvos, setRelevantConvos] = useRecoilState(
+ allRelevantConversations
+ );
+
+ 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)
+ );
+ 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());
+
+ // update all user convo associations
+ setUserConvos((prevMap) => {
+ return new Map(prevMap.set(newConvoMember.id, 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;
+
+ 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);
+
+ setRelevantConvos((prevMap) => {
+ return new Map(prevMap.set(convoId, updatedConvo));
+ });
+ }
+ );
+
+ // todo : remove specific listeners if they are no longer priority conversations
+
+ unsubs.push(unsubConvo);
+ }
+ }
+ if (change.type === "removed") {
+ console.log("Removed convo member: ", change.doc.data());
+ }
+ });
+ });
+
+ unsubs.push(unsubscribeUserConvoMember);
+ } catch (error) {
+ console.log(error);
+ toast.error("Problem in retrieving data");
+ }
+ })();
+
+ return () => {
+ unsubs.forEach((unsub) => {
+ unsub();
+ });
+ };
+ }, []);
+
+ return <>>;
+}
diff --git a/packages/web/recoil/main.tsx b/packages/web/recoil/main.tsx
index 244ae4d..806ed28 100644
--- a/packages/web/recoil/main.tsx
+++ b/packages/web/recoil/main.tsx
@@ -1,10 +1,69 @@
+import Conversation, {
+ ConversationMember,
+ AudioClip,
+ Link,
+} from "@nirvana/common/models/conversation";
+
import { atom } from "recoil";
-// export enum RecoilActions {
-// CURR_PAGE_PATH = "CURR_PAGE_PATH",
-// }
+export enum RecoilActions {
+ 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",
+}
// 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 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({
+ key: RecoilActions.ALL_USERS_CONVERSATION_RELATIONSHIPS,
+ default: new Map(),
+});
+
+export const allRelevantConversations = atom({
+ key: RecoilActions.ALL_RELEVANT_CONVERSATIONS,
+ default: new Map(),
+});