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, selector, selectorFamily } 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", 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", } export const nirvanaUserDataAtom = atom({ 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) // }); // approach: fill in all "bottom" level atoms, and then build the tree later with selectors // convo id -> userMember object export const allUsersConversationsAtom = atom({ key: RecoilActions.ALL_USERS_CONVERSATION_RELATIONSHIPS, default: new Map(), }); 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(allRelevantConversationsAtom); const convosArr: Conversation[] = Array.from(relConvos.values()); convosArr.sort((a, b) => { if (!a.lastActivityDate) { return -1; } if (!b.lastActivityDate) { return 1; } if (a.lastActivityDate > b.lastActivityDate) { return 1; } return -1; }); return convosArr; }, }); // 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 }) => { const sortedConvos = get(sortedRoomSelector); const liveRooms = sortedConvos.filter( (conv) => conv.membersInLiveRoom?.length > 0 ); 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>({ key: RecoilActions.ALL_RELEVANT_CONTACTS, default: new Map(), }); // todo: useful selector where a component can pass in a list of users // and return their full information 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) });