From 10ac1626abc1941d9ebb07fc3d720c595f1799dd Mon Sep 17 00:00:00 2001 From: talksik Date: Sat, 11 Jun 2022 12:40:17 -0500 Subject: [PATCH] more logic for getting conversation if it's not there but should be --- packages/api/routes/conversations.ts | 22 ++++++++++- packages/api/services/conversation.service.ts | 13 +++++++ packages/desktop/src/api/NirvanaApi.tsx | 6 +++ .../src/providers/ConversationProvider.tsx | 37 ++++++++++++++++--- packages/desktop/src/util/types.ts | 18 +++++---- 5 files changed, 80 insertions(+), 16 deletions(-) diff --git a/packages/api/routes/conversations.ts b/packages/api/routes/conversations.ts index f6f7081..4cdede5 100644 --- a/packages/api/routes/conversations.ts +++ b/packages/api/routes/conversations.ts @@ -19,8 +19,8 @@ export default function getConversationRoutes() { router.use(express.json()); - // get a conversation - router.get('/:conversationId', authCheck); + // get a conversation by id + router.get('/:conversationId', authCheck, getConversationById); // get all conversations that I am in // todo: add in pagination for performance, while allowing getting long polling updates? @@ -38,6 +38,24 @@ export default function getConversationRoutes() { return router; } +const getConversationById = async (req: Request, res: Response, next: NextFunction) => { + const { conversationId } = req.params; + + if (!conversationId) { + return next(Error('Must provide a conversation Id')); + } + + const conversationResult = await ConversationService.getConversationById(conversationId); + + const responseObj = new NirvanaResponse( + conversationResult, + undefined, + conversationResult ? 'here is the conversation' : 'No conversation found', + ); + + return res.json(responseObj); +}; + const getAllConversations = async (req: Request, res: Response, next: NextFunction) => { const userInfo = res.locals.userInfo as JwtClaims; diff --git a/packages/api/services/conversation.service.ts b/packages/api/services/conversation.service.ts index 06463c2..84dacca 100644 --- a/packages/api/services/conversation.service.ts +++ b/packages/api/services/conversation.service.ts @@ -3,6 +3,19 @@ import { ObjectId } from 'mongodb'; import { collections } from './database.service'; export default class ConversationService { + static async getConversationById(conversationId: string) { + const query = { _id: new ObjectId(conversationId) }; + + const res = await collections.conversations?.findOne(query); + + // exists + if (res?._id) { + return res as Conversation; + } + + return undefined; + } + static async createConversation(newConversation: Conversation) { return await collections.conversations?.insertOne(newConversation); } diff --git a/packages/desktop/src/api/NirvanaApi.tsx b/packages/desktop/src/api/NirvanaApi.tsx index b41626a..230da3f 100644 --- a/packages/desktop/src/api/NirvanaApi.tsx +++ b/packages/desktop/src/api/NirvanaApi.tsx @@ -89,3 +89,9 @@ export async function getConversations(): Promise> { return await NirvanaApi.fetch(`/conversations/check/${otherUserId}`, 'GET', true); } + +export async function getConversationById( + conversationId: string, +): Promise> { + return await NirvanaApi.fetch(`/conversations/${conversationId}`, 'GET', true); +} diff --git a/packages/desktop/src/providers/ConversationProvider.tsx b/packages/desktop/src/providers/ConversationProvider.tsx index ed82eec..0660066 100644 --- a/packages/desktop/src/providers/ConversationProvider.tsx +++ b/packages/desktop/src/providers/ConversationProvider.tsx @@ -1,8 +1,13 @@ +import { ConversationMap, MasterConversation } from '../util/types'; import React, { useCallback, useEffect, useState } from 'react'; -import { checkIfOnOnOneExists, createConversation, getConversations } from '../api/NirvanaApi'; +import { + checkIfOnOnOneExists, + createConversation, + getConversationById, + getConversations, +} from '../api/NirvanaApi'; import Conversation from '@nirvana/core/models/conversation.model'; -import { ConversationMap } from '../util/types'; import CreateConversationRequest from '@nirvana/core/requests/CreateConversationRequest.request'; import { Typography } from '@mui/material'; import User from '@nirvana/core/models/user.model'; @@ -13,7 +18,7 @@ import { useImmer } from 'use-immer'; interface IConversationContext { conversations: ConversationMap; - selectedConversation?: Conversation; + selectedConversation?: MasterConversation; // handleSetConversation?: (conversationId: string) => void; handleStartConversation?: (otherUsers: User[]) => void; @@ -30,7 +35,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode } // the map that we manage throughout the app const [conversationMap, setConversationMap] = useImmer({}); - const [selectedConversation, setSelectedConversation] = useState(undefined); + const [selectedConversation, setSelectedConversation] = useState(undefined); useEffect(() => { doFetch(); @@ -56,7 +61,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode } * temporaryOverrideSort: tell me if you want to temporarily prioritize this conversation above all others */ const selectConversation = useCallback( - (conversationId: string, temporaryOverrideSort = false) => { + async (conversationId: string, temporaryOverrideSort = false) => { /** * see if there is such a conversation in our map * if not, then go and fetch it from backend @@ -69,9 +74,29 @@ export function ConversationProvider({ children }: { children: React.ReactNode } toast.success('we have that conversation!!!'); setSelectedConversation(conversationMap[conversationId]); + + return; } + + // fetch and add to conversation map + const retrieveConversationResult = await getConversationById(conversationId); + if (!retrieveConversationResult.data) { + toast.error('unable to select conversation'); + return; + } + + setConversationMap((draft) => { + draft[conversationId] = { + ...retrieveConversationResult.data, + tunedInUsers: [], + connectedUserIds: [], + temporaryOverrideSort, + }; + + setSelectedConversation(draft[conversationId]); + }); }, - [conversationMap, setSelectedConversation], + [conversationMap, setSelectedConversation, setConversationMap], ); const handleStartConversation = useCallback( diff --git a/packages/desktop/src/util/types.ts b/packages/desktop/src/util/types.ts index f87d772..97d510f 100644 --- a/packages/desktop/src/util/types.ts +++ b/packages/desktop/src/util/types.ts @@ -2,15 +2,17 @@ import { ContentBlock } from '@nirvana/core/models/content.model'; import Conversation from '@nirvana/core/models/conversation.model'; import User from '@nirvana/core/models/user.model'; -export type ConversationMap = { - [conversationId: string]: Conversation & { - tunedInUsers: string[]; - connectedUserIds: string[]; +export type MasterConversation = Conversation & { + tunedInUsers: string[]; + connectedUserIds: string[]; - // allows client side to have this pushed up in the list and can uncheck it once user is done with this - // if action is take, normal ordering should take place with database upserts - temporaryOverrideSort?: boolean; - }; + // allows client side to have this pushed up in the list and can uncheck it once user is done with this + // if action is take, normal ordering should take place with database upserts + temporaryOverrideSort?: boolean; +}; + +export type ConversationMap = { + [conversationId: string]: MasterConversation; }; export type UserMap = {