summary refs log tree commit diff
path: root/src/api
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-10-04 23:21:50 +1100
committerMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-10-04 23:40:05 +1100
commit7795f1b36ba03877ec222531326664661a93628a (patch)
treec5f062a76971711cbfb1abf80015cd1aaa68f3eb /src/api
parentMerge pull request #1099 from CyberL1/master (diff)
downloadserver-7795f1b36ba03877ec222531326664661a93628a.tar.xz
refactor channel positions in guild
Diffstat (limited to 'src/api')
-rw-r--r--src/api/routes/guilds/#guild_id/channels.ts84
-rw-r--r--src/api/routes/guilds/#guild_id/index.ts16
-rw-r--r--src/api/routes/guilds/#guild_id/widget.json.ts7
3 files changed, 61 insertions, 46 deletions
diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts
index 1d5897a5..671d07ea 100644
--- a/src/api/routes/guilds/#guild_id/channels.ts
+++ b/src/api/routes/guilds/#guild_id/channels.ts
@@ -22,10 +22,10 @@ import {
 	ChannelModifySchema,
 	ChannelReorderSchema,
 	ChannelUpdateEvent,
+	Guild,
 	emitEvent,
 } from "@spacebar/util";
 import { Request, Response, Router } from "express";
-import { HTTPError } from "lambert-server";
 const router = Router();
 
 router.get(
@@ -96,44 +96,72 @@ router.patch(
 		const { guild_id } = req.params;
 		const body = req.body as ChannelReorderSchema;
 
-		await Promise.all([
-			body.map(async (x) => {
-				if (x.position == null && !x.parent_id)
-					throw new HTTPError(
-						`You need to at least specify position or parent_id`,
-						400,
-					);
+		const guild = await Guild.findOneOrFail({
+			where: { id: guild_id },
+			select: { channelOrdering: true },
+		});
+
+		// The channels not listed for this query
+		const notMentioned = guild.channelOrdering.filter(
+			(x) => !body.find((c) => c.id == x),
+		);
 
-				const opts: Partial<Channel> = {};
-				if (x.position != null) opts.position = x.position;
-
-				if (x.parent_id) {
-					opts.parent_id = x.parent_id;
-					const parent_channel = await Channel.findOneOrFail({
-						where: { id: x.parent_id, guild_id },
-						select: ["permission_overwrites"],
-					});
-					if (x.lock_permissions) {
-						opts.permission_overwrites =
-							parent_channel.permission_overwrites;
-					}
-				}
-
-				await Channel.update({ guild_id, id: x.id }, opts);
+		const withParents = body.filter((x) => x.parent_id != undefined);
+		const withPositions = body.filter((x) => x.position != undefined);
+
+		await Promise.all(
+			withPositions.map(async (opt) => {
 				const channel = await Channel.findOneOrFail({
-					where: { guild_id, id: x.id },
+					where: { id: opt.id },
 				});
 
+				channel.position = opt.position as number;
+				notMentioned.splice(opt.position as number, 0, channel.id);
+
 				await emitEvent({
 					event: "CHANNEL_UPDATE",
 					data: channel,
-					channel_id: x.id,
+					channel_id: channel.id,
 					guild_id,
 				} as ChannelUpdateEvent);
 			}),
-		]);
+		);
+
+		// have to do the parents after the positions
+		await Promise.all(
+			withParents.map(async (opt) => {
+				const [channel, parent] = await Promise.all([
+					Channel.findOneOrFail({
+						where: { id: opt.id },
+					}),
+					Channel.findOneOrFail({
+						where: { id: opt.parent_id as string },
+						select: { permission_overwrites: true },
+					}),
+				]);
+
+				if (opt.lock_permissions)
+					await Channel.update(
+						{ id: channel.id },
+						{ permission_overwrites: parent.permission_overwrites },
+					);
+
+				const parentPos = notMentioned.indexOf(parent.id);
+				notMentioned.splice(parentPos + 1, 0, channel.id);
+				channel.position = (parentPos + 1) as number;
+
+				await emitEvent({
+					event: "CHANNEL_UPDATE",
+					data: channel,
+					channel_id: channel.id,
+					guild_id,
+				} as ChannelUpdateEvent);
+			}),
+		);
+
+		await Guild.update({ id: guild_id }, { channelOrdering: notMentioned });
 
-		res.sendStatus(204);
+		return res.sendStatus(204);
 	},
 );
 
diff --git a/src/api/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts
index df21cf95..839ec363 100644
--- a/src/api/routes/guilds/#guild_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/index.ts
@@ -161,12 +161,6 @@ router.patch(
 		guild.assign(body);
 
 		if (body.public_updates_channel_id == "1") {
-			// move all channels up 1
-			await Channel.createQueryBuilder("channels")
-				.where({ guild: { id: guild_id } })
-				.update({ position: () => "position + 1" })
-				.execute();
-
 			// create an updates channel for them
 			const channel = await Channel.createChannel(
 				{
@@ -188,6 +182,8 @@ router.patch(
 				{ skipPermissionCheck: true },
 			);
 
+			await Guild.insertChannelInOrder(guild.id, channel.id, 0, guild);
+
 			guild.public_updates_channel_id = channel.id;
 		} else if (body.public_updates_channel_id != undefined) {
 			// ensure channel exists in this guild
@@ -198,12 +194,6 @@ router.patch(
 		}
 
 		if (body.rules_channel_id == "1") {
-			// move all channels up 1
-			await Channel.createQueryBuilder("channels")
-				.where({ guild: { id: guild_id } })
-				.update({ position: () => "position + 1" })
-				.execute();
-
 			// create a rules for them
 			const channel = await Channel.createChannel(
 				{
@@ -225,6 +215,8 @@ router.patch(
 				{ skipPermissionCheck: true },
 			);
 
+			await Guild.insertChannelInOrder(guild.id, channel.id, 0, guild);
+
 			guild.rules_channel_id = channel.id;
 		} else if (body.rules_channel_id != undefined) {
 			// ensure channel exists in this guild
diff --git a/src/api/routes/guilds/#guild_id/widget.json.ts b/src/api/routes/guilds/#guild_id/widget.json.ts
index 69b5d48c..39f49804 100644
--- a/src/api/routes/guilds/#guild_id/widget.json.ts
+++ b/src/api/routes/guilds/#guild_id/widget.json.ts
@@ -77,12 +77,7 @@ router.get(
 		// Fetch voice channels, and the @everyone permissions object
 		const channels: { id: string; name: string; position: number }[] = [];
 
-		(
-			await Channel.find({
-				where: { guild_id: guild_id, type: 2 },
-				order: { position: "ASC" },
-			})
-		).filter((doc) => {
+		(await Channel.getOrderedChannels(guild.id, guild)).filter((doc) => {
 			// Only return channels where @everyone has the CONNECT permission
 			if (
 				doc.permission_overwrites === undefined ||