typing indicator, mentions + bug fixes
This commit is contained in:
@@ -26,7 +26,14 @@ export default defineEventHandler(async (event) => {
|
||||
name: true,
|
||||
server: {
|
||||
select: {
|
||||
id: true
|
||||
id: true,
|
||||
name: true,
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
messages: {
|
||||
@@ -41,12 +48,16 @@ export default defineEventHandler(async (event) => {
|
||||
},
|
||||
invites: {
|
||||
select: {
|
||||
id: true,
|
||||
id: true,
|
||||
server: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
participants: true
|
||||
participants: {
|
||||
select: {
|
||||
id: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,37 @@ export default defineEventHandler(async (event) => {
|
||||
]
|
||||
}
|
||||
},
|
||||
include: {
|
||||
channels: true,
|
||||
participants: true,
|
||||
roles: true
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
name: true
|
||||
}
|
||||
},
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
},
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
administrator: true,
|
||||
owner: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as IServer;
|
||||
}) as unknown as IServer;
|
||||
|
||||
return server
|
||||
})
|
||||
@@ -62,8 +62,17 @@ export default defineEventHandler(async (event) => {
|
||||
dmParticipants: { connect: [{ id: event.context.user.id }, { id: partner.id }] },
|
||||
DM: true
|
||||
},
|
||||
include: {
|
||||
dmParticipants: true
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
messages: false,
|
||||
DM: true,
|
||||
dmParticipants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as IChannel
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { IChannel, IServer, SafeUser, IMessage } from '~/types'
|
||||
import { Server } from 'socket.io'
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { registerRuntimeHelpers } from '@vue/compiler-core'
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
declare global {
|
||||
@@ -28,20 +29,67 @@ export default defineEventHandler(async (event) => {
|
||||
where: {
|
||||
id: channelId
|
||||
},
|
||||
include: {
|
||||
dmParticipants: true
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
messages: false,
|
||||
DM: true,
|
||||
dmParticipants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as IChannel
|
||||
}) as IChannel | null;
|
||||
|
||||
if (!channel) {
|
||||
event.node.res.statusCode = 404;
|
||||
return {
|
||||
message: `Channel with id "${channelId}" not found.`
|
||||
}
|
||||
}
|
||||
|
||||
if (!channel.DM) {
|
||||
const server = await prisma.server.findFirst({
|
||||
where: {
|
||||
id: channel.serverId
|
||||
},
|
||||
include: {
|
||||
participants: true
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
name: true
|
||||
}
|
||||
},
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
},
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
administrator: true,
|
||||
owner: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as IServer
|
||||
}) as IServer | null;
|
||||
|
||||
if (!server) {
|
||||
throw new Error(`server with id "${channel.serverId}" is not found but channel with id "${channel.id}" is not a dm?`)
|
||||
}
|
||||
|
||||
const userInServer: SafeUser | undefined = server.participants.find((e: SafeUser) => e.id === event.context.user.id)
|
||||
|
||||
@@ -69,11 +117,11 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
const matches = body.match(/<&([a-z]|[0-9]){25}>/g);
|
||||
const inviteCodes = body.match(/<&([a-z]|[0-9]){25}>/g);
|
||||
|
||||
let invites: { id: string; }[] = [];
|
||||
if (matches) {
|
||||
matches.forEach((e: string) => {
|
||||
if (inviteCodes) {
|
||||
inviteCodes.forEach((e: string) => {
|
||||
if (!e) return
|
||||
const opBody = body;
|
||||
body = body.split(e).join('')
|
||||
|
||||
@@ -71,10 +71,35 @@ export default defineEventHandler(async (event) => {
|
||||
]
|
||||
}
|
||||
},
|
||||
include: {
|
||||
participants: true,
|
||||
channels: true,
|
||||
roles: true
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
name: true
|
||||
}
|
||||
},
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
},
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
administrator: true,
|
||||
owner: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as unknown as IServer
|
||||
|
||||
|
||||
@@ -25,51 +25,8 @@ export default defineEventHandler(async (event) => {
|
||||
username: true,
|
||||
passwordhash: true,
|
||||
email: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
messages: false,
|
||||
DM: true,
|
||||
dmParticipants: true,
|
||||
serverId: true
|
||||
}
|
||||
},
|
||||
servers: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
name: true,
|
||||
serverId: true
|
||||
}
|
||||
},
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
},
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
administrator: true,
|
||||
owner: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}) as unknown
|
||||
}) as unknown as IUser
|
||||
|
||||
const isCorrect = await bcryptjs.compare(body.password, user.passwordhash)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import bcryptjs from "bcryptjs";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { SafeUser } from "~/types";
|
||||
import { IUser, SafeUser } from "~/types";
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
@@ -45,53 +45,8 @@ export default defineEventHandler(async (event) => {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
passwordhash: true,
|
||||
email: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
messages: false,
|
||||
DM: true,
|
||||
dmParticipants: true,
|
||||
serverId: true
|
||||
}
|
||||
},
|
||||
servers: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
name: true,
|
||||
serverId: true
|
||||
}
|
||||
},
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
},
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
administrator: true,
|
||||
owner: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}) as unknown
|
||||
}) as unknown as IUser
|
||||
|
||||
const token = uuidv4()
|
||||
|
||||
|
||||
23
server/api/user/logout.ts
Normal file
23
server/api/user/logout.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { sessionToken } = parseCookies(event)
|
||||
|
||||
if (!sessionToken) {
|
||||
event.node.res.statusCode = 400;
|
||||
return {
|
||||
message: 'A session token is required to logout duh'
|
||||
}
|
||||
}
|
||||
|
||||
await prisma.session.delete({
|
||||
where: {
|
||||
token: sessionToken
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
message: `successfully logged out`
|
||||
}
|
||||
})
|
||||
@@ -1,14 +1,119 @@
|
||||
// server/middleware/socket.ts
|
||||
import { Server } from 'socket.io'
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { IChannel, IServer, IUser, SafeUser } from '~~/types'
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
declare global {
|
||||
var io: Server | undefined
|
||||
let io: Server | undefined
|
||||
}
|
||||
|
||||
export default defineEventHandler(({ node }) => {
|
||||
if (!global.io) {
|
||||
global.io = new Server(node.res.socket?.server);
|
||||
|
||||
global.io.on('connection', (socket) => { })
|
||||
global.io.on('connection', async (socket) => {
|
||||
const token = socket.handshake.auth.token;
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.time()
|
||||
const { user } = await prisma.session.findFirst({
|
||||
where: {
|
||||
token
|
||||
},
|
||||
select: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
servers: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
administrator: true,
|
||||
owner: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
server: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
participants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
roles: {
|
||||
select: {
|
||||
id: true,
|
||||
administrator: true,
|
||||
owner: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
channels: {
|
||||
select: {
|
||||
id: true,
|
||||
DM: true,
|
||||
dmParticipants: {
|
||||
select: {
|
||||
id: true,
|
||||
username: true
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}) as { user: IUser } | null;
|
||||
console.timeEnd();
|
||||
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
socket.on('typing', async (ev) => {
|
||||
if (!ev) {
|
||||
return;
|
||||
}
|
||||
|
||||
let channel = user.channels.find((c: IChannel) => c.id === ev) || user.servers.find((s: IServer) => s.channels.some((c: IChannel) => c.id === ev))
|
||||
if (channel.DM === undefined) {
|
||||
// assume its a server
|
||||
channel = channel.channels.find((c: IChannel) => c.id === ev)
|
||||
}
|
||||
|
||||
if (!channel) return;
|
||||
|
||||
if (!channel.dmParticipants?.find((e: SafeUser) => e.id === user.id)) {
|
||||
if (!channel.server || !channel.server.participants.find((e: SafeUser) => e.id === user.id)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
global.io.emit(`typing-${channel.id}`, user.username)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user