summary refs log tree commit diff
path: root/util/src/services/ChannelService.ts
diff options
context:
space:
mode:
Diffstat (limited to 'util/src/services/ChannelService.ts')
-rw-r--r--util/src/services/ChannelService.ts88
1 files changed, 88 insertions, 0 deletions
diff --git a/util/src/services/ChannelService.ts b/util/src/services/ChannelService.ts
new file mode 100644
index 00000000..7cded10f
--- /dev/null
+++ b/util/src/services/ChannelService.ts
@@ -0,0 +1,88 @@
+import { Channel, ChannelType, 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 })) });
+
+		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 })
+
+		await emitEvent({
+			event: "CHANNEL_DELETE",
+			data: await DmChannelDTO.from(channel, [user_id]),
+			user_id: user_id
+		});
+
+		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);
+	}
+}
\ No newline at end of file