feat: add start_new_row option for role button options
This commit is contained in:
parent
5042d9997f
commit
4a9ece8e3b
6 changed files with 57 additions and 35 deletions
|
@ -8,6 +8,8 @@ import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin";
|
|||
import { StrictValidationError } from "../../validatorUtils";
|
||||
import { onButtonInteraction } from "./events/buttonInteraction";
|
||||
import { pluginInfo } from "./info";
|
||||
import { createButtonComponents } from "./functions/createButtonComponents";
|
||||
import { TooManyComponentsError } from "./functions/TooManyComponentsError";
|
||||
|
||||
export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
||||
name: "role_buttons",
|
||||
|
@ -26,10 +28,6 @@ export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
|||
|
||||
if (buttonsConfig) {
|
||||
buttonsConfig.name = name;
|
||||
// 5 action rows * 5 buttons
|
||||
if (buttonsConfig.options?.length > 25) {
|
||||
throw new StrictValidationError(["A single message can have at most 25 role buttons"]);
|
||||
}
|
||||
|
||||
if (buttonsConfig.message) {
|
||||
if ("message_id" in buttonsConfig.message) {
|
||||
|
@ -39,6 +37,17 @@ export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
|||
seenMessages.add(buttonsConfig.message.message_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (buttonsConfig.options) {
|
||||
try {
|
||||
createButtonComponents(buttonsConfig);
|
||||
} catch (err) {
|
||||
if (err instanceof TooManyComponentsError) {
|
||||
throw new StrictValidationError(["Too many options; can only have max 5 buttons per row on max 5 rows."]);
|
||||
}
|
||||
throw new StrictValidationError(["Error validating options"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export class TooManyComponentsError extends Error {}
|
|
@ -4,8 +4,8 @@ import { isSnowflake, snowflakeRegex } from "../../../utils";
|
|||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { Message, MessageButton, MessageEditOptions, MessageOptions, Snowflake } from "discord.js";
|
||||
import { RoleButtonsItem } from "../../../data/entities/RoleButtonsItem";
|
||||
import { splitButtonsIntoRows } from "./splitButtonsIntoRows";
|
||||
import { buildCustomId } from "../../../utils/buildCustomId";
|
||||
import { createButtonComponents } from "./createButtonComponents";
|
||||
|
||||
const channelMessageRegex = new RegExp(`^(${snowflakeRegex.source})-(${snowflakeRegex.source})$`);
|
||||
|
||||
|
@ -104,24 +104,8 @@ export async function applyRoleButtons(
|
|||
}
|
||||
|
||||
// Apply role buttons
|
||||
const buttons = configItem.options.map((opt, index) => {
|
||||
const button = new MessageButton()
|
||||
.setLabel(opt.label ?? "")
|
||||
.setStyle(opt.style ?? "PRIMARY")
|
||||
.setCustomId(buildCustomId("roleButtons", { name: configItem.name, index }));
|
||||
|
||||
if (opt.emoji) {
|
||||
const emo = pluginData.client.emojis.resolve(opt.emoji as Snowflake) ?? opt.emoji;
|
||||
button.setEmoji(emo);
|
||||
}
|
||||
|
||||
return button;
|
||||
});
|
||||
const rows = splitButtonsIntoRows(buttons);
|
||||
|
||||
await message.edit({
|
||||
components: rows,
|
||||
});
|
||||
const components = createButtonComponents(configItem);
|
||||
await message.edit({ components });
|
||||
|
||||
return {
|
||||
channel_id: message.channelId,
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { MessageActionRow, MessageButton, Snowflake } from "discord.js";
|
||||
import { chunkArray } from "../../../utils";
|
||||
import { RoleButtonsPluginType, TRoleButtonOption, TRoleButtonsConfigItem } from "../types";
|
||||
import { buildCustomId } from "../../../utils/buildCustomId";
|
||||
import { GuildPluginData } from "knub";
|
||||
import { TooManyComponentsError } from "./TooManyComponentsError";
|
||||
|
||||
export function createButtonComponents(configItem: TRoleButtonsConfigItem): MessageActionRow[] {
|
||||
const rows: MessageActionRow[] = [];
|
||||
|
||||
let currentRow = new MessageActionRow();
|
||||
for (const [index, option] of configItem.options.entries()) {
|
||||
if (currentRow.components.length === 5 || (currentRow.components.length > 0 && option.start_new_row)) {
|
||||
rows.push(currentRow);
|
||||
currentRow = new MessageActionRow();
|
||||
}
|
||||
|
||||
const button = new MessageButton()
|
||||
.setLabel(option.label ?? "")
|
||||
.setStyle(option.style ?? "PRIMARY")
|
||||
.setCustomId(buildCustomId("roleButtons", { name: configItem.name, index }));
|
||||
|
||||
if (option.emoji) {
|
||||
button.setEmoji(option.emoji);
|
||||
}
|
||||
|
||||
currentRow.components.push(button);
|
||||
}
|
||||
|
||||
if (currentRow.components.length > 0) {
|
||||
rows.push(currentRow);
|
||||
}
|
||||
|
||||
if (rows.length > 5) {
|
||||
throw new TooManyComponentsError();
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import { MessageActionRow, MessageButton } from "discord.js";
|
||||
import { chunkArray } from "../../../utils";
|
||||
|
||||
export function splitButtonsIntoRows(buttons: MessageButton[]): MessageActionRow[] {
|
||||
// Max 5 buttons per row
|
||||
const buttonChunks = chunkArray(buttons, 5);
|
||||
return buttonChunks.map((chunk) => {
|
||||
const row = new MessageActionRow();
|
||||
row.setComponents(chunk);
|
||||
return row;
|
||||
});
|
||||
}
|
|
@ -16,6 +16,7 @@ const RoleButtonOption = t.type({
|
|||
label: tNullable(t.string),
|
||||
emoji: tNullable(t.string),
|
||||
style: tNullable(t.keyof(ButtonStyles)), // https://discord.js.org/#/docs/discord.js/v13/typedef/MessageButtonStyle
|
||||
start_new_row: tNullable(t.boolean),
|
||||
});
|
||||
export type TRoleButtonOption = t.TypeOf<typeof RoleButtonOption>;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue