diff --git a/packages/api/routes/line.ts b/packages/api/routes/line.ts index d681012..18823a5 100644 --- a/packages/api/routes/line.ts +++ b/packages/api/routes/line.ts @@ -16,6 +16,7 @@ import MasterLineData from "@nirvana/core/models/masterLineData.model"; import NirvanaResponse from "../../core/responses/nirvanaResponse"; import { ObjectId } from "mongodb"; import Relationship from "@nirvana/core/models/relationship.model"; +import { User } from "@nirvana/core/models/user.model"; import { UserService } from "../services/user.service"; import { collections } from "../services/database.service"; @@ -122,42 +123,89 @@ async function getUserLines(req: Request, res: Response) { const userInfo = res.locals.userInfo as JwtClaims; // get all of user's lineMember entries - const lineMembers = await LineService.getLineMembersByUserId( + const userLineMembers = await LineService.getLineMembersByUserId( userInfo.userId ); - if (!lineMembers?.length) { + if (!userLineMembers?.length) { res.status(400).json(); return; } - const lineIds = lineMembers?.map((lineMem) => lineMem.lineId) ?? []; + const lineIds = + userLineMembers?.map((lineMember) => lineMember.lineId) ?? []; + + // this will include the current user lineMember association to the line + const allLineMembers = await LineService.getLineMembersInLines(lineIds); + + const allLinesUsers: ObjectId[] = []; + allLineMembers?.map((currentLineMember) => { + if (currentLineMember?._id) allLinesUsers.push(currentLineMember.userId); + }) ?? []; + + // get all users relevant here + const allRelevantUsers = await UserService.getUsersByIds(allLinesUsers); // get all lines from the list of relevant lines const lines = (await LineService.getLinesByIds(lineIds)) ?? []; - const masterLines = - lines.map((currentLine) => { - const associatedLineMember = lineMembers.find((lineMember) => - lineMember.lineId.equals(currentLine._id!) - ); + const masterLines: MasterLineData[] = []; - // TODO: get all of the other members on the line + // TODO: get the latest audio blocks for this line...maybe like today and yesterday or by block count - // TODO: get the latest audio blocks for this line...maybe like today and yesterday or by block count + lines.map((currentLine) => { + let associatedLineMembersForLine: LineMember[] = []; - return new MasterLineData( - currentLine._id!, - currentLine.createdDate, - currentLine.lastUpdatedDate, - associatedLineMember - ); + // get all of the line members for this Line + // make sure that we don't add line member if it's the current user + allLineMembers?.map((lineMember) => { + if (currentLine._id) { + if (lineMember.lineId.equals(currentLine._id)) + associatedLineMembersForLine.push(lineMember); + } }) ?? []; - const resObj = new GetUserLinesResponse(lines); + // get the user lineMember assoc out of the list of the lineMembers for this line + const userLineMember = associatedLineMembersForLine?.find( + (currentLineMemberForLine) => + currentLineMemberForLine.userId.toString() === userInfo.userId + ); - res.json(masterLines); + console.log(associatedLineMembersForLine); + + if (userLineMember) { + // take out the current user from the "other" line members list now + + associatedLineMembersForLine = associatedLineMembersForLine.filter( + (currentLineMember) => + currentLineMember.userId.toString() !== userInfo.userId + ); + + // get the user objects for all of the other members + const otherUsers: User[] = []; + associatedLineMembersForLine.forEach((currentLineMember) => { + const foundUserObject = allRelevantUsers?.find( + (currentUser) => currentUser._id === currentLineMember.userId + ); + + if (foundUserObject) otherUsers.push(foundUserObject); + }); + + masterLines.push( + new MasterLineData( + currentLine, + userLineMember, + associatedLineMembersForLine, + otherUsers + ) + ); + } + }); + + const resObj = new GetUserLinesResponse(masterLines); + + res.json(new NirvanaResponse(resObj)); } catch (error) { res.status(500).json(error); } diff --git a/packages/api/services/line.service.ts b/packages/api/services/line.service.ts index 9a7eed1..6e40f3d 100644 --- a/packages/api/services/line.service.ts +++ b/packages/api/services/line.service.ts @@ -46,6 +46,20 @@ export class LineService { return null; } + /** Get all of the members associated to the given list of lines */ + static async getLineMembersInLines(lineIds: ObjectId[]) { + const query = { lineId: { $in: lineIds } }; + + const lineMembersRes = await collections.lineMembers?.find(query).toArray(); + + // exists + if (lineMembersRes?.length) { + return lineMembersRes as LineMember[]; + } + + return null; + } + static async createLine(line: Line, lineMembers: LineMember[]) { const session = client.startSession(); try { diff --git a/packages/api/services/user.service.ts b/packages/api/services/user.service.ts index b06d454..443ba9a 100644 --- a/packages/api/services/user.service.ts +++ b/packages/api/services/user.service.ts @@ -19,6 +19,19 @@ export class UserService { return null; } + static async getUsersByIds(userIds: ObjectId[]) { + const query = { _id: { $in: userIds } }; + + const res = await collections.users?.find(query).toArray(); + + // exists + if (res?.length) { + return res as User[]; + } + + return undefined; + } + static async getUserByGoogleId(googleUserId: string) { const query = { googleId: googleUserId }; diff --git a/packages/core/models/masterLineData.model.ts b/packages/core/models/masterLineData.model.ts index cb2091c..132f4d4 100644 --- a/packages/core/models/masterLineData.model.ts +++ b/packages/core/models/masterLineData.model.ts @@ -1,22 +1,23 @@ -import AudioClip from "./audioClip.model"; -import { LineMember } from "./line.model"; -import { ObjectId } from "mongodb"; +import { Line, LineMember } from "./line.model"; +import AudioClip from "./audioClip.model"; +import { ObjectId } from "mongodb"; +import { User } from "./user.model"; + +// why do we have separate full objects being sent? +// speed...I'm developing full stack and I just want all of the data and don't want to change this model +// repeatedly and trace data back and forth export default class MasterLineData { constructor( - // attributes of conversation - public id: ObjectId, // id of the conversation + // full line object + public lineDetails: Line, - public createdDate: Date, - public lastUpdatedDate: Date, - - // compiled data for easy client read - public currentUserMember?: LineMember, + // requesting user's association to the line + public currentUserMember: LineMember, + // all other members in the convo as well as their user object to see the member details public otherMembers?: LineMember[], - public audioClips: AudioClip[] = [], - - public name?: string + public otherUserObjects?: User[] /**public audioClips: AudioClip[] = [], // public media: Media[] */ ) {} } diff --git a/packages/core/responses/getUserLines.response.ts b/packages/core/responses/getUserLines.response.ts index b5ee047..06ddf6a 100644 --- a/packages/core/responses/getUserLines.response.ts +++ b/packages/core/responses/getUserLines.response.ts @@ -1,5 +1,6 @@ import { Line } from "../models/line.model"; +import MasterLineData from "../models/masterLineData.model"; export default class GetUserLinesResponse { - constructor(public lines: Line[]) {} + constructor(public masterLines: MasterLineData[]) {} } diff --git a/packages/desktop/src/controller/index.tsx b/packages/desktop/src/controller/index.tsx index 981d3ff..27f7304 100644 --- a/packages/desktop/src/controller/index.tsx +++ b/packages/desktop/src/controller/index.tsx @@ -37,10 +37,11 @@ export function useUserSearch(searchQuery: string) { }); } -export function useUserConvos() { - // todo: merge with sockets + audio clip data + master data + convomember data +export function useUserLines() { + // todo: base/source of truth for getting all of the lines for the user + // merge with sockets + audio clip data + master data + convomember data - return useQuery("USER_CONVERSATIONS", ApiCalls.getUserConversations); + return useQuery("USER_LINES", ApiCalls.getUserLines); } // =========== MUTATIONS diff --git a/packages/desktop/src/controller/nirvanaApi.ts b/packages/desktop/src/controller/nirvanaApi.ts index 5b79905..6d94b19 100644 --- a/packages/desktop/src/controller/nirvanaApi.ts +++ b/packages/desktop/src/controller/nirvanaApi.ts @@ -3,7 +3,7 @@ import axios, { AxiosRequestConfig, AxiosResponse, Method } from "axios"; import CreateLineRequest from "@nirvana/core/requests/createLine.request"; import { Line } from "@nirvana/core/models/line.model"; import LoginResponse from "../../../core/responses/login.response"; -import MasterConversation from "@nirvana/core/models/masterLineData.model"; +import MasterLineData from "@nirvana/core/models/masterLineData.model"; import NirvanaResponse from "../../../core/responses/nirvanaResponse"; import { User } from "@nirvana/core/models"; import UserDetailsResponse from "../../../core/responses/userDetails.response"; @@ -82,7 +82,7 @@ async function userSearch(searchQuery: string): Promise { ); } -async function getUserConversations(): Promise { +async function getUserLines(): Promise> { return await NirvanaApi.fetch(`/lines`, "GET", true); } @@ -101,7 +101,7 @@ export const ApiCalls = { authCheck, getUserDetails, userSearch, - getUserConversations, + getUserLines, getDmByUserId, createLine, };