Skip to content

Commit 2fc6b09

Browse files
authored
Merge pull request #44 from Kasper24/call-routes
feat: add call routes
2 parents 61fc24e + fa03e8e commit 2fc6b09

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { and, desc, eq, isNotNull } from "drizzle-orm";
2+
import { formatDistanceStrict } from "date-fns";
3+
import {
4+
createTypiRouter,
5+
createTypiRoute,
6+
createTypiRouteHandler,
7+
} from "@repo/typiserver";
8+
import { db } from "@repo/database";
9+
import { callParticipants, calls, chats, users } from "@repo/database/schema";
10+
import authMiddleware from "@repo/api/middlewares/auth";
11+
12+
const callRouter = createTypiRouter({
13+
"/": createTypiRoute({
14+
get: createTypiRouteHandler({
15+
middlewares: [authMiddleware],
16+
handler: async (ctx) => {
17+
const userId = ctx.data.userId;
18+
19+
const userCalls = await db
20+
.select({
21+
call: calls,
22+
chat: chats,
23+
self: callParticipants,
24+
})
25+
.from(calls)
26+
.innerJoin(callParticipants, eq(callParticipants.callId, calls.id))
27+
.innerJoin(chats, eq(calls.chatId, chats.id))
28+
.where(
29+
and(
30+
eq(callParticipants.userId, userId),
31+
isNotNull(callParticipants.joinedAt),
32+
isNotNull(callParticipants.leftAt)
33+
)
34+
)
35+
.orderBy(desc(callParticipants.joinedAt));
36+
37+
const result = await Promise.all(
38+
userCalls.map(async (call) => {
39+
const participants = await db
40+
.select({
41+
user: users,
42+
callParticipant: callParticipants,
43+
})
44+
.from(callParticipants)
45+
.innerJoin(users, eq(callParticipants.userId, users.id))
46+
.where(eq(callParticipants.callId, call.call.id));
47+
48+
const duration = formatDistanceStrict(
49+
call.self.leftAt || new Date(),
50+
call.self.joinedAt || new Date()
51+
);
52+
53+
const isCaller = call.call.createdBy === userId;
54+
const status = isCaller
55+
? participants.some(
56+
(p) =>
57+
p.user.id !== userId &&
58+
p.callParticipant.status === "answered"
59+
)
60+
? "answered"
61+
: "missed"
62+
: participants.find((p) => p.user.id === userId)?.callParticipant
63+
.status || "missed";
64+
65+
const participantsWithoutSelf = participants.filter(
66+
(participant) => participant.user.id !== userId
67+
);
68+
69+
return {
70+
call: {
71+
...call.call,
72+
status,
73+
duration: duration,
74+
},
75+
chat: call.chat,
76+
participants: participantsWithoutSelf,
77+
self: call.self,
78+
};
79+
})
80+
);
81+
82+
return ctx.success({
83+
calls: result,
84+
});
85+
},
86+
}),
87+
}),
88+
});
89+
90+
export default callRouter;

apps/api/src/modules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { createTypiRouter } from "@repo/typiserver";
22
import blockRouter from "./block/block.route";
33
import authRouter from "./auth/auth.route";
4+
import callRouter from "./call/call.route";
45
import chatRouter from "./chat/chat.route";
56
import friendsRouter from "./friends/friends.route";
67
import userRouter from "./user/user.route";
78

89
const rootRouter = createTypiRouter({
910
"/auth": authRouter,
1011
"/block": blockRouter,
12+
"/call": callRouter,
1113
"/chat": chatRouter,
1214
"/friends": friendsRouter,
1315
"/user": userRouter,

0 commit comments

Comments
 (0)