From b9f93d741d08d8fa2ce5a89f32f612d2bc7ed6df Mon Sep 17 00:00:00 2001 From: talksik Date: Sun, 20 Mar 2022 18:24:50 -0400 Subject: [PATCH] working displaying contacts, but of course not nice --- packages/api/routes/contacts.ts | 35 +++++++++++++++---- packages/api/services/contact.service.ts | 11 ++++++ .../core/responses/getContacts.response.ts | 12 +++++++ packages/desktop/src/controller/index.tsx | 25 +++++++++++++ .../src/pages/Home/conversations/index.tsx | 25 +++++++++++++ 5 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 packages/core/responses/getContacts.response.ts diff --git a/packages/api/routes/contacts.ts b/packages/api/routes/contacts.ts index 79f3fdb..61b00da 100644 --- a/packages/api/routes/contacts.ts +++ b/packages/api/routes/contacts.ts @@ -1,3 +1,6 @@ +import GetContactsResponse, { + ContactDetails, +} from "../../core/responses/getContacts.response"; import Relationship, { RelationshipState, } from "@nirvana/core/models/relationship.model"; @@ -6,6 +9,7 @@ import express, { Application, Request, Response } from "express"; import { ContactService } from "../services/contact.service"; import { ObjectId } from "mongodb"; import UpdateRelationshipStateRequest from "../../core/requests/updateRelationshipState.request"; +import { UserService } from "../services/user.service"; import { authCheck } from "../middleware/auth"; import { collections } from "../services/database.service"; @@ -25,16 +29,35 @@ export default function getContactsRoutes() { return router; } +// todo optimization with mongo lookups and such async function getAllContacts(req: Request, res: Response) { try { - const { email } = res.locals; + const { userId } = res.locals; - if (!email) { - res.status(400).send("No email of user!"); - return; - } + const resultRelationships = await ContactService.getAllUserRelationships( + userId + ); - // todo: fetch all of my contacts + const responseObj = new GetContactsResponse(); + + // get all of the other users based on these relationships and join them + await Promise.all( + resultRelationships.map(async (relationship) => { + const otherUserId = + relationship.receiverUserId === userId + ? relationship.senderUserId + : relationship.receiverUserId; + + const otherUser = await UserService.getUserByGoogleId(otherUserId); + + if (otherUser) + responseObj.contactsDetails.push( + new ContactDetails(otherUser, relationship) + ); + }) + ); + + res.status(200).send(responseObj); } catch (error) { console.log(error); res.status(500).send(`something went wrong`); diff --git a/packages/api/services/contact.service.ts b/packages/api/services/contact.service.ts index 89d5861..c7151a5 100644 --- a/packages/api/services/contact.service.ts +++ b/packages/api/services/contact.service.ts @@ -6,6 +6,17 @@ import Relationship, { import { collections } from "./database.service"; export class ContactService { + static async getAllUserRelationships(userId: string) { + const query = { + $or: [{ senderUserId: userId }, { receiverUserId: userId }], + }; + const res = (await collections.relationships + ?.find(query) + .toArray()) as Relationship[]; + + return res; + } + static async getRelationship( myGoogleUserId: string, otherGoogleUserId: string diff --git a/packages/core/responses/getContacts.response.ts b/packages/core/responses/getContacts.response.ts new file mode 100644 index 0000000..bc29daf --- /dev/null +++ b/packages/core/responses/getContacts.response.ts @@ -0,0 +1,12 @@ +import Relationship from "../models/relationship.model"; +import { User } from "../models/user.model"; + +export default class GetContactsResponse { + contactsDetails: ContactDetails[] = []; + + constructor() {} +} + +export class ContactDetails { + constructor(public otherUser: User, public relationship: Relationship) {} +} diff --git a/packages/desktop/src/controller/index.tsx b/packages/desktop/src/controller/index.tsx index 7d3cc9b..5b25b7e 100644 --- a/packages/desktop/src/controller/index.tsx +++ b/packages/desktop/src/controller/index.tsx @@ -2,6 +2,7 @@ import { $authTokens, $searchQuery } from "./recoil"; import axios, { AxiosResponse } from "axios"; import { useMutation, useQuery } from "react-query"; +import GetContactsResponse from "../../../core/responses/getContacts.response"; import GetConversationDetailsResponse from "@nirvana/core/responses/getConversationDetails.response"; import { ObjectId } from "mongodb"; import { RelationshipState } from "@nirvana/core/models/relationship.model"; @@ -77,11 +78,23 @@ const updateContactRequestState = async ( return response.data; }; +const getContactsBasicDetails = async (idToken: string) => { + const response = await axios.get( + localHost + `/contacts`, + { + headers: { Authorization: idToken }, + } + ); + + return response.data; +}; + // ====== QUERIES export enum Querytypes { GET_USER_DETAILS = "GET_USER_DETAILS", GET_SEARCH_RESULTS = "GET_SEARCH_RESULTS", GET_CONVERSATION_DETAILS = "GET_CONVERSATION_DETAILS", + GET_CONTACTS_RELATIONSHIPS = "GET_CONTACTS_RELATIONSHIPS", } export function useGetUserDetails() { const authTokens = useRecoilValue($authTokens); @@ -117,6 +130,18 @@ export function useConversationDetails(otherUserGoogleId: string) { ); } +export function useGetAllContactBasicDetails() { + const authTokens = useRecoilValue($authTokens); + + return useQuery( + Querytypes.GET_CONTACTS_RELATIONSHIPS, + () => getContactsBasicDetails(authTokens.idToken), + { + refetchOnWindowFocus: false, + } + ); +} + // =========== MUTATIONS export function useSendContactRequest() { diff --git a/packages/desktop/src/pages/Home/conversations/index.tsx b/packages/desktop/src/pages/Home/conversations/index.tsx index 10d4333..449730f 100644 --- a/packages/desktop/src/pages/Home/conversations/index.tsx +++ b/packages/desktop/src/pages/Home/conversations/index.tsx @@ -1,8 +1,14 @@ import { Add, LinkRounded } from "@mui/icons-material"; +import { Avatar } from "antd"; import { FaVolumeUp } from "react-icons/fa"; +import SkeletonLoader from "../../../components/loading/skeleton"; +import { useGetAllContactBasicDetails } from "../../../controller"; export default function Conversations() { + const { data: contactDetailsListResponse, isLoading } = + useGetAllContactBasicDetails(); + /** Data we need: have this huge data store client side to be able to access * for now, need a simple list of contacts * - first list is the live/pinned @@ -12,6 +18,7 @@ export default function Conversations() { * web sockets for all of my active contacts * - actually play messages if pinned contact for me */ + return ( <> {/* actions navbar */} @@ -38,6 +45,24 @@ export default function Conversations() { Mark Conversations as Pinned to Hear Them Live + + {isLoading ? : null} +
+ {contactDetailsListResponse?.contactsDetails.map((contactDetail) => { + return ( +
+ + + + {contactDetail.otherUser.name} + + {contactDetail.otherUser.status} + + speaking... +
+ ); + })} +
); }