fix: channel ordering
This commit is contained in:
@@ -234,6 +234,9 @@ export const ChannelPositionUpdateRequest = z.array(
|
||||
id: SnowflakeType.describe('The ID of the channel to reposition'),
|
||||
position: z.number().int().nonnegative().optional().describe('New position for the channel'),
|
||||
parent_id: SnowflakeType.nullish().describe('New parent category ID'),
|
||||
preceding_sibling_id: SnowflakeType.nullish().describe(
|
||||
'ID of the sibling channel that should directly precede this channel after reordering',
|
||||
),
|
||||
lock_permissions: z.boolean().optional().describe('Whether to sync permissions with the new parent'),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -67,7 +67,52 @@ export function compareChannelOrdering<Id extends string | bigint>(
|
||||
export function sortChannelsForOrdering<Id extends string | bigint, Channel extends ChannelOrderingChannel<Id>>(
|
||||
channels: ReadonlyArray<Channel>,
|
||||
): Array<Channel> {
|
||||
return [...channels].sort(compareChannelOrdering);
|
||||
const channelById = new Map<Id, Channel>(channels.map((channel) => [channel.id, channel]));
|
||||
const childrenByParent = new Map<Id, Array<Channel>>();
|
||||
const rootChannels: Array<Channel> = [];
|
||||
|
||||
for (const channel of channels) {
|
||||
const parentId = channel.parentId ?? null;
|
||||
if (parentId === null || !channelById.has(parentId)) {
|
||||
rootChannels.push(channel);
|
||||
continue;
|
||||
}
|
||||
|
||||
const existingChildren = childrenByParent.get(parentId);
|
||||
if (existingChildren) {
|
||||
existingChildren.push(channel);
|
||||
} else {
|
||||
childrenByParent.set(parentId, [channel]);
|
||||
}
|
||||
}
|
||||
|
||||
const orderedChannels: Array<Channel> = [];
|
||||
const seen = new Set<Id>();
|
||||
|
||||
const sortedRoots = [...rootChannels].sort(compareChannelOrdering);
|
||||
for (const root of sortedRoots) {
|
||||
orderedChannels.push(root);
|
||||
seen.add(root.id);
|
||||
|
||||
if (root.type !== ChannelTypes.GUILD_CATEGORY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const children = childrenByParent.get(root.id);
|
||||
if (!children) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const child of [...children].sort(compareChannelOrdering)) {
|
||||
orderedChannels.push(child);
|
||||
seen.add(child.id);
|
||||
}
|
||||
}
|
||||
|
||||
const remaining = channels.filter((channel) => !seen.has(channel.id)).sort(compareChannelOrdering);
|
||||
orderedChannels.push(...remaining);
|
||||
|
||||
return orderedChannels;
|
||||
}
|
||||
|
||||
export function computeChannelMoveBlockIds<Id extends string | bigint, Channel extends ChannelOrderingChannel<Id>>({
|
||||
|
||||
Reference in New Issue
Block a user