3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-15 05:41:51 +00:00

feat: add start_new_row option for role button options

This commit is contained in:
Dragory 2022-04-23 18:51:28 +03:00
parent 5042d9997f
commit 4a9ece8e3b
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
6 changed files with 57 additions and 35 deletions

View file

@ -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"]);
}
}
}
}

View file

@ -0,0 +1 @@
export class TooManyComponentsError extends Error {}

View file

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

View file

@ -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;
}

View file

@ -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;
});
}

View file

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