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 ||
|