1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-23 19:02:37 +01:00

Removed ChannelService, more fixes

This commit is contained in:
AlTech98 2021-09-18 18:36:29 +02:00
parent 97e0c8709b
commit ada95b6c39
11 changed files with 131 additions and 139 deletions

View File

@ -1,4 +1,4 @@
import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelService, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util";
import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { handleFile, route } from "@fosscord/api";
@ -28,7 +28,7 @@ router.delete("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request
]);
} else if (channel.type === ChannelType.GROUP_DM) {
await ChannelService.removeRecipientFromChannel(channel, req.user_id)
await Channel.removeRecipientFromChannel(channel, req.user_id)
} else {
//TODO messages in this channel should be deleted before deleting the channel
await Promise.all([

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { Attachment, Channel, ChannelType, DmChannelDTO, Embed, emitEvent, getPermission, Message, MessageCreateEvent } from "@fosscord/util";
import { Attachment, Channel, ChannelType, DmChannelDTO, Embed, emitEvent, getPermission, Message, MessageCreateEvent, Recipient } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { handleMessage, postHandleMessage, route } from "@fosscord/api";
import multer from "multer";
@ -150,7 +150,6 @@ router.post(
return res.status(400).json(error);
}
}
//TODO querying the DB at every message post should be avoided, caching maybe?
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] })
const embeds = [];
@ -184,7 +183,8 @@ router.post(
}
}
await Promise.all(channel.recipients!.map(async r => {
//Only one recipients should be closed here, since in group DMs the recipient is deleted not closed
await Promise.all(channel.recipients!.filter(r => r.closed).map(async r => {
r.closed = false;
return await r.save()
}));

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { Channel, ChannelRecipientAddEvent, ChannelService, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util";
import { Channel, ChannelRecipientAddEvent, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util";
const router: Router = Router();
@ -13,7 +13,7 @@ router.put("/:user_id", async (req: Request, res: Response) => {
user_id
].unique()
const new_channel = await ChannelService.createDMChannel(recipients, req.user_id)
const new_channel = await Channel.createDMChannel(recipients, req.user_id)
return res.status(201).json(new_channel);
} else {
if (channel.recipients!.map(r => r.user_id).includes(user_id)) {
@ -49,7 +49,7 @@ router.delete("/:user_id", async (req: Request, res: Response) => {
throw DiscordApiErrors.INVALID_RECIPIENT //TODO is this the right error?
}
await ChannelService.removeRecipientFromChannel(channel, user_id)
await Channel.removeRecipientFromChannel(channel, user_id)
return res.sendStatus(204);
});

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { Recipient, ChannelService, DmChannelDTO } from "@fosscord/util";
import { Recipient, DmChannelDTO, Channel } from "@fosscord/util";
import { route } from "@fosscord/api";
const router: Router = Router();
@ -16,7 +16,7 @@ export interface DmChannelCreateSchema {
router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => {
const body = req.body as DmChannelCreateSchema;
res.json(await ChannelService.createDMChannel(body.recipients, req.user_id, body.name));
res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name));
});
export default router;

View File

@ -32,7 +32,7 @@ export async function setupListener(this: WebSocket) {
});
const guilds = members.map((x) => x.guild);
const recipients = await Recipient.find({
where: { user_id: this.user_id },
where: { user_id: this.user_id, closed: false },
relations: ["channel"],
});
const dm_channels = recipients.map((x) => x.channel);

View File

@ -1,11 +1,13 @@
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { User } from "./User";
import { PublicUserProjection, User } from "./User";
import { HTTPError } from "lambert-server";
import { emitEvent, getPermission, Snowflake } from "../util";
import { ChannelCreateEvent } from "../interfaces";
import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial } from "../util";
import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces";
import { Recipient } from "./Recipient";
import { DmChannelDTO } from "../dtos";
import { Message } from "./Message";
export enum ChannelType {
GUILD_TEXT = 0, // a text channel within a server
@ -97,7 +99,6 @@ export class Channel extends BaseClass {
@Column({ nullable: true })
topic?: string;
// TODO: DM channel
static async createChannel(
channel: Partial<Channel>,
user_id: string = "0",
@ -150,16 +151,123 @@ export class Channel extends BaseClass {
new Channel(channel).save(),
!opts?.skipEventEmit
? emitEvent({
event: "CHANNEL_CREATE",
data: channel,
guild_id: channel.guild_id,
} as ChannelCreateEvent)
event: "CHANNEL_CREATE",
data: channel,
guild_id: channel.guild_id,
} as ChannelCreateEvent)
: Promise.resolve(),
]);
return channel;
}
static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) {
recipients = recipients.unique().filter((x) => x !== creator_user_id);
const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });
// TODO: check config for max number of recipients
if (otherRecipientsUsers.length !== recipients.length) {
throw new HTTPError("Recipient/s not found");
}
const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM;
let channel = null;
const channelRecipients = [...recipients, creator_user_id]
const userRecipients = await Recipient.find({ where: { user_id: creator_user_id }, relations: ["channel", "channel.recipients"] })
for (let ur of userRecipients) {
let re = ur.channel.recipients!.map(r => r.user_id)
if (re.length === channelRecipients.length) {
if (containsAll(re, channelRecipients)) {
if (channel == null) {
channel = ur.channel
await ur.assign({ closed: false }).save()
}
}
}
}
if (channel == null) {
name = trimSpecial(name);
channel = await new Channel({
name,
type,
owner_id: (type === ChannelType.DM ? undefined : creator_user_id),
created_at: new Date(),
last_message_id: null,
recipients: channelRecipients.map((x) => new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })),
}).save();
}
const channel_dto = await DmChannelDTO.from(channel)
if (type === ChannelType.GROUP_DM) {
for (let recipient of channel.recipients!) {
await emitEvent({
event: "CHANNEL_CREATE",
data: channel_dto.excludedRecipients([recipient.user_id]),
user_id: recipient.user_id
})
}
} else {
await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });
}
return channel_dto.excludedRecipients([creator_user_id])
}
static async removeRecipientFromChannel(channel: Channel, user_id: string) {
await Recipient.delete({ channel_id: channel.id, user_id: user_id })
channel.recipients = channel.recipients?.filter(r => r.user_id !== user_id)
if (channel.recipients?.length === 0) {
await Channel.deleteChannel(channel);
await emitEvent({
event: "CHANNEL_DELETE",
data: await DmChannelDTO.from(channel, [user_id]),
user_id: user_id
});
return
}
await emitEvent({
event: "CHANNEL_DELETE",
data: await DmChannelDTO.from(channel, [user_id]),
user_id: user_id
});
//If the owner leave we make the first recipient in the list the new owner
if (channel.owner_id === user_id) {
channel.owner_id = channel.recipients!.find(r => r.user_id !== user_id)!.user_id //Is there a criteria to choose the new owner?
await emitEvent({
event: "CHANNEL_UPDATE",
data: await DmChannelDTO.from(channel, [user_id]),
channel_id: channel.id
});
}
await channel.save()
await emitEvent({
event: "CHANNEL_RECIPIENT_REMOVE", data: {
channel_id: channel.id,
user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection })
}, channel_id: channel.id
} as ChannelRecipientRemoveEvent);
}
static async deleteChannel(channel: Channel) {
await Message.delete({ channel_id: channel.id }) //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util
//TODO before deleting the channel we should check and delete other relations
await Channel.delete({ id: channel.id })
}
isDm() {
return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM
}

View File

@ -4,7 +4,6 @@ import "reflect-metadata";
export * from "./util/index";
export * from "./interfaces/index";
export * from "./entities/index";
export * from "./services/index";
export * from "./dtos/index";
// import Config from "../util/Config";

View File

@ -1,118 +0,0 @@
import { Channel, ChannelType, Message, PublicUserProjection, Recipient, User } from "../entities";
import { HTTPError } from "lambert-server";
import { emitEvent, trimSpecial } from "../util";
import { DmChannelDTO } from "../dtos";
import { ChannelRecipientRemoveEvent } from "../interfaces";
export function checker(arr: any[], target: any[]) {
return target.every(v => arr.includes(v));
}
export class ChannelService {
public static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) {
recipients = recipients.unique().filter((x) => x !== creator_user_id);
const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });
// TODO: check config for max number of recipients
if (otherRecipientsUsers.length !== recipients.length) {
throw new HTTPError("Recipient/s not found");
}
const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM;
let channel = null;
const channelRecipients = [...recipients, creator_user_id]
const userRecipients = await Recipient.find({ where: { user_id: creator_user_id }, relations: ["channel", "channel.recipients"] })
for (let ur of userRecipients) {
let re = ur.channel.recipients!.map(r => r.user_id)
if (re.length === channelRecipients.length) {
if (checker(re, channelRecipients)) {
if (channel == null) {
channel = ur.channel
await ur.assign({ closed: false }).save()
}
}
}
}
if (channel == null) {
name = trimSpecial(name);
channel = await new Channel({
name,
type,
owner_id: (type === ChannelType.DM ? undefined : creator_user_id),
created_at: new Date(),
last_message_id: null,
recipients: channelRecipients.map((x) => new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })),
}).save();
}
const channel_dto = await DmChannelDTO.from(channel)
if (type === ChannelType.GROUP_DM) {
for (let recipient of channel.recipients!) {
await emitEvent({
event: "CHANNEL_CREATE",
data: channel_dto.excludedRecipients([recipient.user_id]),
user_id: recipient.user_id
})
}
} else {
await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });
}
return channel_dto.excludedRecipients([creator_user_id])
}
public static async removeRecipientFromChannel(channel: Channel, user_id: string) {
await Recipient.delete({ channel_id: channel.id, user_id: user_id })
channel.recipients = channel.recipients?.filter(r => r.user_id !== user_id)
if (channel.recipients?.length === 0) {
await ChannelService.deleteChannel(channel);
await emitEvent({
event: "CHANNEL_DELETE",
data: await DmChannelDTO.from(channel, [user_id]),
user_id: user_id
});
return
}
await emitEvent({
event: "CHANNEL_DELETE",
data: await DmChannelDTO.from(channel, [user_id]),
user_id: user_id
});
//If the owner leave we make the first recipient in the list the new owner
if (channel.owner_id === user_id) {
channel.owner_id = channel.recipients!.find(r => r.user_id !== user_id)!.user_id //Is there a criteria to choose the new owner?
await emitEvent({
event: "CHANNEL_UPDATE",
data: await DmChannelDTO.from(channel, [user_id]),
channel_id: channel.id
});
}
await channel.save()
await emitEvent({
event: "CHANNEL_RECIPIENT_REMOVE", data: {
channel_id: channel.id,
user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection })
}, channel_id: channel.id
} as ChannelRecipientRemoveEvent);
}
public static async deleteChannel(channel: Channel) {
await Message.delete({ channel_id: channel.id }) //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util
//TODO before deleting the channel we should check and delete other relations
await Channel.delete({ id: channel.id })
}
}

View File

@ -1 +0,0 @@
export * from "./ChannelService";

3
util/src/util/Array.ts Normal file
View File

@ -0,0 +1,3 @@
export function containsAll(arr: any[], target: any[]) {
return target.every(v => arr.includes(v));
}

View File

@ -12,3 +12,4 @@ export * from "./RabbitMQ";
export * from "./Regex";
export * from "./Snowflake";
export * from "./String";
export * from "./Array";