diff options
author | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-09-19 19:09:13 +0200 |
---|---|---|
committer | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-09-19 19:09:13 +0200 |
commit | ffe179758e640b37596cce4ecfc3e11624df1518 (patch) | |
tree | 6f519f84ed729bc1e9d16cf68df3e9a8dc731c96 /util/src/entities/Channel.ts | |
parent | :art: add orphanedRowAction and cascade onDelete to entities (diff) | |
parent | :truck: move file handle to utility (diff) | |
download | server-ffe179758e640b37596cce4ecfc3e11624df1518.tar.xz |
Merge branch 'master' into auto-delete-relations
Diffstat (limited to 'util/src/entities/Channel.ts')
-rw-r--r-- | util/src/entities/Channel.ts | 120 |
1 files changed, 117 insertions, 3 deletions
diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts index 0196fb3e..b1f75f33 100644 --- a/util/src/entities/Channel.ts +++ b/util/src/entities/Channel.ts @@ -11,16 +11,17 @@ import { } 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 { Message } from "./Message"; import { ReadState } from "./ReadState"; import { Invite } from "./Invite"; import { VoiceState } from "./VoiceState"; import { Webhook } from "./Webhook"; +import { DmChannelDTO } from "../dtos"; export enum ChannelType { GUILD_TEXT = 0, // a text channel within a server @@ -214,6 +215,119 @@ export class Channel extends BaseClass { 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; } |