вложения, канальчики, бим-бим + бам-бам
This commit is contained in:
111
server/routes/chat.ts
Normal file
111
server/routes/chat.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import type { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox'
|
||||
import { Type } from 'typebox'
|
||||
import { ChatMessageSchema, NewChatMessageSchema } from '../schemas/chat.ts'
|
||||
|
||||
const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
|
||||
fastify.post(
|
||||
'/chat/send',
|
||||
{
|
||||
schema: {
|
||||
summary: 'Send message',
|
||||
tags: ['Chat'],
|
||||
operationId: 'chat.send',
|
||||
body: NewChatMessageSchema,
|
||||
response: {
|
||||
200: ChatMessageSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (req, reply) => {
|
||||
const user = req.user!
|
||||
|
||||
const message = await fastify.prisma.message.create({
|
||||
data: {
|
||||
text: req.body.text,
|
||||
senderId: user.id,
|
||||
attachments: {
|
||||
create: (req.body.attachments ?? []).map((attachmentId) => {
|
||||
return {
|
||||
attachment: {
|
||||
connect: {
|
||||
id: attachmentId,
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!message) {
|
||||
return reply.unprocessableEntity()
|
||||
}
|
||||
|
||||
const response = {
|
||||
id: message.id,
|
||||
senderId: user.id,
|
||||
text: message.text,
|
||||
createdAt: message.createdAt.toISOString(),
|
||||
updatedAt: message.updatedAt.toISOString(),
|
||||
attachments: req.body.attachments ?? [],
|
||||
}
|
||||
|
||||
fastify.bus.emit('chat:new-message', response)
|
||||
|
||||
return response
|
||||
},
|
||||
)
|
||||
|
||||
fastify.get(
|
||||
'/chat',
|
||||
{
|
||||
schema: {
|
||||
summary: 'Get messages',
|
||||
tags: ['Chat'],
|
||||
operationId: 'chat.messages',
|
||||
querystring: Type.Object({
|
||||
cursor: Type.Optional(Type.String({ format: 'uuid', description: 'Cursor to message' })),
|
||||
limit: Type.Number({ minimum: 1, maximum: 100, default: 10 }),
|
||||
}),
|
||||
response: {
|
||||
200: Type.Object({
|
||||
messages: Type.Array(ChatMessageSchema),
|
||||
nextCursor: Type.Optional(Type.String({ format: 'uuid', description: 'Cursor to last message' })),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
// eslint-disable-next-line ts/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
async (req) => {
|
||||
const messages = await fastify.prisma.message.findMany({
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: req.query.limit + 1,
|
||||
include: { attachments: true },
|
||||
...(req.query.cursor && {
|
||||
cursor: {
|
||||
id: req.query.cursor,
|
||||
},
|
||||
// skip: 1,
|
||||
}),
|
||||
})
|
||||
|
||||
const hasMore = messages.length > req.query.limit
|
||||
const cursorMessage = hasMore ? messages.pop() : undefined
|
||||
|
||||
return {
|
||||
messages: messages.map((message) => {
|
||||
return {
|
||||
...message,
|
||||
createdAt: message.createdAt.toISOString(),
|
||||
updatedAt: message.updatedAt.toISOString(),
|
||||
attachments: message.attachments.map(({ attachmentId }) => attachmentId),
|
||||
}
|
||||
}),
|
||||
nextCursor: cursorMessage?.id,
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export default plugin
|
||||
Reference in New Issue
Block a user