diff --git a/packages/common/helpers/dateTime.tsx b/packages/common/helpers/dateTime.tsx index 9def876..efb31b5 100644 --- a/packages/common/helpers/dateTime.tsx +++ b/packages/common/helpers/dateTime.tsx @@ -1,4 +1,4 @@ -import moment from "moment"; +const moment = require("moment"); export function generateGreetings(): string { const hour = moment().hour(); @@ -17,3 +17,16 @@ export function generateGreetings(): string { export function getTime(date?: Date) { return date != null ? date.getTime() : 0; } + +const today = new Date(); + +const yesterday = today; +yesterday.setDate(yesterday.getDate() - 1); + +const Days7Ago = today; +Days7Ago.setDate(Days7Ago.getDate() - 7); + +const earlierThisMonth = today; +earlierThisMonth.setDate(earlierThisMonth.getDate() - 30); + +export { today, yesterday, Days7Ago, earlierThisMonth }; diff --git a/packages/common/package.json b/packages/common/package.json index d17f180..631fe6c 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -6,6 +6,7 @@ "private": false, "dependencies": { "@typescript-eslint/eslint-plugin": "^5.10.2", + "moment": "^2.29.1", "typescript": "^4.5.5", "uuid": "^8.3.2" }, diff --git a/packages/web/components/MainTabsOrPages/Conversations.tsx b/packages/web/components/MainTabsOrPages/Conversations.tsx index cbf6ef4..3c03028 100644 --- a/packages/web/components/MainTabsOrPages/Conversations.tsx +++ b/packages/web/components/MainTabsOrPages/Conversations.tsx @@ -17,12 +17,31 @@ import { Routes } from "@nirvana/common/helpers/routes"; import LiveRoom from "../Conversations/LiveRoom"; import Conversation from "@nirvana/common/models/conversation"; import { useRecoilValue } from "recoil"; -import { liveRoomsSelector } from "../../recoil/main"; +import { + liveRoomsSelector, + RelativeTimeConvosSections, + RelativeTimeSeparatedConvosSelector, +} from "../../recoil/main"; export default function Conversations() { const router = useRouter(); const liveRooms = useRecoilValue(liveRoomsSelector); + const relativeConvoSections = useRecoilValue( + RelativeTimeSeparatedConvosSelector + ); + const todayConvos = relativeConvoSections.get( + RelativeTimeConvosSections.today + ); + const last7DaysConvos = relativeConvoSections.get( + RelativeTimeConvosSections.last7Days + ); + const earlierMonthConvos = relativeConvoSections.get( + RelativeTimeConvosSections.earlierThisMonth + ); + const oldJunkConvos = relativeConvoSections.get( + RelativeTimeConvosSections.oldJunk + ); const handleViewConversationDetails = (convoId) => { router.push({ @@ -52,13 +71,15 @@ export default function Conversations() { )} {/* Today */} - - - Today - + {todayConvos && todayConvos?.length > 0 && ( + + + Today + - - + + + )} handleViewConversationDetails("woah")} @@ -349,7 +370,7 @@ export default function Conversations() { - November 2021 + Old Junk diff --git a/packages/web/recoil/main.tsx b/packages/web/recoil/main.tsx index fc518b1..46d924f 100644 --- a/packages/web/recoil/main.tsx +++ b/packages/web/recoil/main.tsx @@ -3,11 +3,18 @@ import Conversation, { ConversationMember, AudioClip, Link, + ConversationMemberState, } from "@nirvana/common/models/conversation"; import { User as NirvanaUser } from "@nirvana/common/models/user"; import { userService } from "@nirvana/common/services"; import { atom, DefaultValue, selector, selectorFamily } from "recoil"; +import { + today, + yesterday, + Days7Ago, + earlierThisMonth as earlyMonthDate, +} from "@nirvana/common/helpers/dateTime"; export enum RecoilActions { TEST = "TEST", @@ -20,6 +27,7 @@ export enum RecoilActions { SORTED_CONVERSATIONS = "SORTED_CONVERSATIONS", LIVE_ROOMS = "LIVE_ROOMS", + RELATIVE_TIME_SECTIONS_CONVOS = "RELATIVE_TIME_SECTIONS_CONVOS", ALL_RELEVANT_CONTACTS = "ALL_RELEVANT_CONTACTS", RELEVANT_CONTACTS_SELECTOR_CACHE = "RELEVANT_CONTACTS_SELECTOR_CACHE", @@ -34,6 +42,7 @@ export const nirvanaUserDataAtom = atom({ // 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"; +import { earlierThisMonth } from "@nirvana/common/helpers/dateTime"; // const getTest = (async () => await conversationService.test())(); @@ -76,7 +85,7 @@ export const sortedRoomSelector = selector({ return 1; } - if (a.lastActivityDate > b.lastActivityDate) { + if (a.lastActivityDate.toDate() > b.lastActivityDate.toDate()) { return 1; } @@ -102,6 +111,90 @@ export const liveRoomsSelector = selector({ }, }); +export enum RelativeTimeConvosSections { + today = "TODAY", + + last7Days = "LAST 7 DAYS", + + earlierThisMonth = "EARLIER THIS MONTH", + + oldJunk = "OLD JUNK", +} + +// map from the section title to the list of conversations, all sorted desc lastActivity date +export const RelativeTimeSeparatedConvosSelector = selector< + Map +>({ + key: RecoilActions.RELATIVE_TIME_SECTIONS_CONVOS, + get: ({ get }) => { + const sortedConvos = get(sortedRoomSelector); + + // find the convos where the user convo membership state is "inbox" or default + const userMemberMap = get(allUsersConversationsAtom); + + // inbox/default Convos: already sorted + const defaultConvos = sortedConvos.filter((convo) => { + return ( + userMemberMap.get(convo.id)?.state == ConversationMemberState.default + ); + }); + + // go through these and organize in the different sections + + const organizedMapRelConvos = new Map< + RelativeTimeConvosSections, + Conversation[] + >(new Map()); + + // putting in sections in map so we can just add later + organizedMapRelConvos.set( + RelativeTimeConvosSections.today, + [] as Conversation[] + ); + organizedMapRelConvos.set( + RelativeTimeConvosSections.last7Days, + [] as Conversation[] + ); + organizedMapRelConvos.set( + RelativeTimeConvosSections.earlierThisMonth, + [] as Conversation[] + ); + organizedMapRelConvos.set( + RelativeTimeConvosSections.oldJunk, + [] as Conversation[] + ); + + defaultConvos.map((convo) => { + let sectionForConvo = RelativeTimeConvosSections.today; + + // put it in the junk with this + if (!convo.lastActivityDate) { + sectionForConvo = RelativeTimeConvosSections.oldJunk; + } else if (convo.lastActivityDate.toDate() > yesterday) { + sectionForConvo = RelativeTimeConvosSections.today; + } else if (convo.lastActivityDate.toDate() > Days7Ago) { + sectionForConvo = RelativeTimeConvosSections.last7Days; + } else if (convo.lastActivityDate.toDate() > earlyMonthDate) { + sectionForConvo = RelativeTimeConvosSections.earlierThisMonth; + } else { + sectionForConvo = RelativeTimeConvosSections.oldJunk; + } + + const currValInSection = organizedMapRelConvos.get(sectionForConvo); + + // already set, but just making sure + if (currValInSection) { + organizedMapRelConvos.set(sectionForConvo, [ + ...currValInSection, + convo, + ]); + } + }); + + return organizedMapRelConvos; + }, +}); + // 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>({ @@ -110,19 +203,4 @@ 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({ - key: RecoilActions.RELEVANT_CONTACTS_SELECTOR_CACHE, - get: async ({ get }) => { - 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); - }, -}); +// and return their full information...either get from cache if there or fetch from database if not and update cache