fetching convos with current state for user and combining to master convos

This commit is contained in:
talksik
2022-04-03 10:29:52 -04:00
parent d6eadab3c1
commit 87335cbdb6
8 changed files with 154 additions and 15 deletions
+49
View File
@@ -11,6 +11,7 @@ import { ConversationService } from "../services/conversation.service";
import CreateConvoRequest from "../../core/requests/createConvo.request"; import CreateConvoRequest from "../../core/requests/createConvo.request";
import GetConversationDetailsResponse from "@nirvana/core/responses/getConversationDetails.response"; import GetConversationDetailsResponse from "@nirvana/core/responses/getConversationDetails.response";
import GetDmConversationByOtherUserIdResponse from "../../core/responses/getDmConversationByOtherUserId.response"; import GetDmConversationByOtherUserIdResponse from "../../core/responses/getDmConversationByOtherUserId.response";
import GetUserConversationsResponse from "../../core/responses/getUserConversations.response";
import MasterConversation from "../../core/models/masterConversation.model"; import MasterConversation from "../../core/models/masterConversation.model";
import { ObjectId } from "mongodb"; import { ObjectId } from "mongodb";
import Relationship from "@nirvana/core/models/relationship.model"; import Relationship from "@nirvana/core/models/relationship.model";
@@ -28,6 +29,9 @@ export default function getConversationRoutes() {
// create a convo // create a convo
router.post("/", authCheck, createConversation); router.post("/", authCheck, createConversation);
// get all of user's convos
router.get("/", authCheck, getUserConvos);
// get conversation between user and other user // get conversation between user and other user
router.get("/dm/:otherUserId", authCheck, getDmByOtherUserId); router.get("/dm/:otherUserId", authCheck, getDmByOtherUserId);
@@ -99,3 +103,48 @@ async function createConversation(req: Request, res: Response) {
res.status(500).json(error); res.status(500).json(error);
} }
} }
async function getUserConvos(req: Request, res: Response) {
try {
const userInfo = res.locals.userInfo as JwtClaims;
// get all of user's convoMember entries
const convoMembers =
await ConversationService.getConversationsMembersByUserId(
userInfo.userId
);
if (!convoMembers?.length) {
res.status(400).json();
return;
}
const convoIds =
convoMembers?.map((convoMem) => convoMem.conversationId) ?? [];
// get all convos from the list of relevant convos
const convos =
(await ConversationService.getConversationsByIds(convoIds)) ?? [];
const masterConvos =
convos.map((convo) => {
const assocConvoMember = convoMembers.find((convMem) =>
convMem.conversationId.equals(convo._id!)
);
return new MasterConversation(
convo._id!,
convo.createdDate,
convo.lastUpdatedDate,
assocConvoMember
);
}) ?? [];
const resObj = new GetUserConversationsResponse(convos);
res.json(masterConvos);
} catch (error) {
res.status(500).json(error);
}
}
@@ -21,6 +21,34 @@ export class ConversationService {
// return null; // return null;
} }
static async getConversationsByIds(convoIds: ObjectId[]) {
const query = { _id: { $in: convoIds } };
const convosRes = await collections.conversations?.find(query).toArray();
// exists
if (convosRes?.length) {
return convosRes as Conversation[];
}
return null;
}
static async getConversationsMembersByUserId(userId: string) {
const query = { userId: new ObjectId(userId) };
const convoMembersRes = await collections.conversationMembers
?.find(query)
.toArray();
// exists
if (convoMembersRes?.length) {
return convoMembersRes as ConversationMember[];
}
return null;
}
static async createConversation( static async createConversation(
convo: Conversation, convo: Conversation,
convoMembers: ConversationMember[] convoMembers: ConversationMember[]
@@ -3,15 +3,20 @@ import { ConversationMember } from "./conversation.model";
import { ObjectId } from "mongodb"; import { ObjectId } from "mongodb";
export default class MasterConversation { export default class MasterConversation {
// attributes of conversation constructor(
id: ObjectId; // id of the conversation // attributes of conversation
name?: string; public id: ObjectId, // id of the conversation
createdDate: Date;
lastUpdatedDate: Date;
// compiled data for easy client read public createdDate: Date,
currentUserMember: ConversationMember; public lastUpdatedDate: Date,
otherMembers: ConversationMember[];
audioClips: AudioClip[]; // compiled data for easy client read
public currentUserMember?: ConversationMember,
public otherMembers?: ConversationMember[],
public audioClips: AudioClip[] = [],
public name?: string
) {}
} }
@@ -0,0 +1,5 @@
import { Conversation } from "../models/conversation.model";
export default class GetUserConversationsResponse {
constructor(public convos: Conversation[]) {}
}
@@ -0,0 +1,33 @@
import MasterConversation from "../../../../core/models/masterConversation.model";
import UserStatusText from "../User/userStatusText";
export default function BasicConversationRow({
masterConvo,
}: {
masterConvo: MasterConversation;
}) {
const isSelected = false;
return (
<div
key={masterConvo.id.toString()}
className={`flex flex-row items-center hover:bg-zinc-600 group py-4 px-2 cursor-pointer ${
isSelected ? "bg-zinc-600" : ""
} rounded`}
>
{/* <UserAvatarWithStatus user={contactDetail.otherUser} /> */}
<span className="text-white font-semibold ml-2">{masterConvo.name}</span>
<span className="text-white font-semibold ml-2">
{masterConvo.id.toString()}
</span>
{/* <span className="ml-2">
<UserStatusText status={contactDetail.otherUser.status} />
</span> */}
{/* {speakingRooms.includes(contactDetail.relationship._id.toString()) ? (
<span className="ml-auto">speaking...</span>
) : null} */}
</div>
);
}
@@ -30,6 +30,12 @@ export function useUserSearch(searchQuery: string) {
}); });
} }
export function useUserConvos() {
// todo: merge with sockets + audio clip data + master data + convomember data
return useQuery("USER_CONVERSATIONS", ApiCalls.getUserConversations);
}
// =========== MUTATIONS // =========== MUTATIONS
export function useGetDmByUserId() { export function useGetDmByUserId() {
return useMutation(ApiCalls.getDmByUserId); return useMutation(ApiCalls.getDmByUserId);
@@ -3,6 +3,7 @@ import axios, { AxiosRequestConfig, AxiosResponse, Method } from "axios";
import { Conversation } from "../../../core/models/conversation.model"; import { Conversation } from "../../../core/models/conversation.model";
import CreateConvoRequest from "../../../core/requests/createConvo.request"; import CreateConvoRequest from "../../../core/requests/createConvo.request";
import LoginResponse from "../../../core/responses/login.response"; import LoginResponse from "../../../core/responses/login.response";
import MasterConversation from "../../../core/models/masterConversation.model";
import { User } from "@nirvana/core/models"; import { User } from "@nirvana/core/models";
import UserDetailsResponse from "../../../core/responses/userDetails.response"; import UserDetailsResponse from "../../../core/responses/userDetails.response";
import UserSearchResponse from "../../../core/responses/userSearch.response"; import UserSearchResponse from "../../../core/responses/userSearch.response";
@@ -80,6 +81,10 @@ async function userSearch(searchQuery: string): Promise<UserSearchResponse> {
); );
} }
async function getUserConversations(): Promise<MasterConversation[]> {
return await NirvanaApi.fetch(`/conversations`, "GET", true);
}
async function getDmByUserId(otherUserId: string): Promise<Conversation> { async function getDmByUserId(otherUserId: string): Promise<Conversation> {
return await NirvanaApi.fetch( return await NirvanaApi.fetch(
`/conversations/dm/${otherUserId}`, `/conversations/dm/${otherUserId}`,
@@ -102,6 +107,7 @@ export const ApiCalls = {
authCheck, authCheck,
getUserDetails, getUserDetails,
userSearch, userSearch,
getUserConversations,
getDmByUserId, getDmByUserId,
createConversation, createConversation,
}; };
@@ -11,6 +11,7 @@ import {
} from "../../../../../core/models/conversation.model"; } from "../../../../../core/models/conversation.model";
import { useRecoilState, useSetRecoilState } from "recoil"; import { useRecoilState, useSetRecoilState } from "recoil";
import BasicConversationRow from "../../../components/conversation/basicRow";
import { ContactDetails } from "@nirvana/core/responses/getContacts.response"; import { ContactDetails } from "@nirvana/core/responses/getContacts.response";
import { FaVolumeUp } from "react-icons/fa"; import { FaVolumeUp } from "react-icons/fa";
import MasterConversation from "../../../../../core/models/masterConversation.model"; import MasterConversation from "../../../../../core/models/masterConversation.model";
@@ -19,6 +20,7 @@ import UserAvatarWithStatus from "../../../components/User/userAvatarWithStatus"
import UserStatusText from "../../../components/User/userStatusText"; import UserStatusText from "../../../components/User/userStatusText";
import useSocketData from "../../../controller/sockets"; import useSocketData from "../../../controller/sockets";
import { useState } from "react"; import { useState } from "react";
import { useUserConvos } from "../../../controller/index";
enum ConvoTab { enum ConvoTab {
LIVE = "LIVE", LIVE = "LIVE",
@@ -57,22 +59,21 @@ export default function Conversations() {
setSelectedConvo(googleUserId); setSelectedConvo(googleUserId);
}; };
// fake data of conversations const { data: userConverstionsData } = useUserConvos();
const allMasterConvos = [] as MasterConversation[];
// render right content based on selected tab // render right content based on selected tab
const renderConversationContent = () => { const renderConversationContent = () => {
// if no content for a tab, then show stale text // if no content for a tab, then show stale text
const invitedConvos = allMasterConvos.filter( const invitedConvos = userConverstionsData?.filter(
(masterConvo) => (masterConvo) =>
masterConvo.currentUserMember.state === ConversationMemberState.INVITED masterConvo.currentUserMember.state === ConversationMemberState.INVITED
); );
const inboxConvos = allMasterConvos.filter( const inboxConvos = userConverstionsData?.filter(
(masterConvo) => (masterConvo) =>
masterConvo.currentUserMember.state === ConversationMemberState.INBOX masterConvo.currentUserMember.state === ConversationMemberState.INBOX
); );
const tunedConvos = allMasterConvos.filter( const tunedConvos = userConverstionsData?.filter(
(masterConvo) => (masterConvo) =>
masterConvo.currentUserMember.state === ConversationMemberState.TUNED masterConvo.currentUserMember.state === ConversationMemberState.TUNED
); );
@@ -94,7 +95,13 @@ export default function Conversations() {
return <span>Pin a channel to turn it into a walkie talkie.</span>; return <span>Pin a channel to turn it into a walkie talkie.</span>;
case ConvoTab.INBOX: case ConvoTab.INBOX:
if (inboxConvos?.length) { if (inboxConvos?.length) {
return <span>displaying all inbox convos</span>; return (
<>
{inboxConvos.map((convo) => (
<BasicConversationRow masterConvo={convo} />
))}
</>
);
} }
return <span>Connect with someone and start talking!</span>; return <span>Connect with someone and start talking!</span>;
case ConvoTab.REQUESTS: case ConvoTab.REQUESTS: