From ceb770fb5b6648c18d66d6997c8916ed60b8c192 Mon Sep 17 00:00:00 2001 From: AlTech98 Date: Sat, 18 Sep 2021 18:36:29 +0200 Subject: Removed ChannelService, more fixes --- util/src/entities/Channel.ts | 124 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 8 deletions(-) (limited to 'util/src/entities') diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts index aa2bfab3..ea632778 100644 --- a/util/src/entities/Channel.ts +++ b/util/src/entities/Channel.ts @@ -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, 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 } -- cgit 1.4.1