feat: add block movement and deletion functionality in interactive editor
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
MessageFlags,
|
||||
TextChannel,
|
||||
} from "discord.js";
|
||||
import { ComponentType, TextInputStyle } from "discord-api-types/v10";
|
||||
import { ComponentType, TextInputStyle, ButtonStyle } from "discord-api-types/v10";
|
||||
import logger from "../../../core/lib/logger";
|
||||
import {CommandMessage} from "../../../core/types/commands";
|
||||
import {listVariables} from "../../../core/lib/vars";
|
||||
@@ -202,6 +202,113 @@ async function handleButtonInteraction(
|
||||
await handleCoverImage(interaction, editorMessage, originalMessage, blockState);
|
||||
break;
|
||||
|
||||
case "move_block": {
|
||||
const options = blockState.components.map((c: any, idx: number) => ({
|
||||
label: c.type === 10 ? `Texto: ${c.content?.slice(0, 30) || '...'}` : c.type === 14 ? 'Separador' : c.type === 12 ? `Imagen: ${c.url?.slice(-30) || '...'}` : `Componente ${c.type}`,
|
||||
value: String(idx),
|
||||
description: c.type === 10 && (c.thumbnail || c.linkButton) ? (c.thumbnail ? 'Con thumbnail' : 'Con botón link') : undefined,
|
||||
}));
|
||||
|
||||
await interaction.reply({
|
||||
flags: MessageFlags.Ephemeral,
|
||||
content: 'Selecciona el bloque que quieres mover:',
|
||||
components: [
|
||||
{ type: 1, components: [ { type: 3, custom_id: 'move_block_select', placeholder: 'Elige un bloque', options } ] },
|
||||
],
|
||||
});
|
||||
const replyMsg = await interaction.fetchReply();
|
||||
// @ts-ignore
|
||||
const selCollector = replyMsg.createMessageComponentCollector({ componentType: ComponentType.StringSelect, max: 1, time: 60000, filter: (it: any) => it.user.id === originalMessage.author.id });
|
||||
selCollector.on('collect', async (sel: any) => {
|
||||
const idx = parseInt(sel.values[0]);
|
||||
await sel.update({
|
||||
content: '¿Quieres mover este bloque?',
|
||||
components: [
|
||||
{ type: 1, components: [
|
||||
{ type: 2, style: ButtonStyle.Secondary, label: '⬆️ Subir', custom_id: `move_up_${idx}`, disabled: idx === 0 },
|
||||
{ type: 2, style: ButtonStyle.Secondary, label: '⬇️ Bajar', custom_id: `move_down_${idx}`, disabled: idx === blockState.components.length - 1 },
|
||||
]},
|
||||
],
|
||||
});
|
||||
// @ts-ignore
|
||||
const btnCollector = replyMsg.createMessageComponentCollector({ componentType: ComponentType.Button, max: 1, time: 60000, filter: (b: any) => b.user.id === originalMessage.author.id });
|
||||
btnCollector.on('collect', async (b: any) => {
|
||||
if (b.customId.startsWith('move_up_')) {
|
||||
const i2 = parseInt(b.customId.replace('move_up_', ''));
|
||||
if (i2 > 0) {
|
||||
const item = blockState.components[i2];
|
||||
blockState.components.splice(i2, 1);
|
||||
blockState.components.splice(i2 - 1, 0, item);
|
||||
}
|
||||
await b.update({ content: '✅ Bloque movido arriba.', components: [] });
|
||||
} else if (b.customId.startsWith('move_down_')) {
|
||||
const i2 = parseInt(b.customId.replace('move_down_', ''));
|
||||
if (i2 < blockState.components.length - 1) {
|
||||
const item = blockState.components[i2];
|
||||
blockState.components.splice(i2, 1);
|
||||
blockState.components.splice(i2 + 1, 0, item);
|
||||
}
|
||||
await b.update({ content: '✅ Bloque movido abajo.', components: [] });
|
||||
}
|
||||
|
||||
await updateEditor(editorMessage, {
|
||||
display: await DisplayComponentUtils.renderPreview(blockState, originalMessage.member!, originalMessage.guild!),
|
||||
components: DisplayComponentUtils.createEditorButtons(false),
|
||||
});
|
||||
btnCollector.stop();
|
||||
selCollector.stop();
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "delete_block": {
|
||||
const options: any[] = [];
|
||||
if (blockState.coverImage) options.push({ label: '🖼️ Imagen de Portada', value: 'cover_image', description: 'Imagen principal del bloque' });
|
||||
blockState.components.forEach((c: any, idx: number) => options.push({
|
||||
label: c.type === 10 ? `Texto: ${c.content?.slice(0, 30) || '...'}` : c.type === 14 ? `Separador ${c.divider ? '(Visible)' : '(Invisible)'}` : c.type === 12 ? `Imagen: ${c.url?.slice(-30) || '...'}` : `Componente ${c.type}`,
|
||||
value: String(idx),
|
||||
description: c.type === 10 && (c.thumbnail || c.linkButton) ? (c.thumbnail ? 'Con thumbnail' : 'Con botón link') : undefined,
|
||||
}));
|
||||
|
||||
if (options.length === 0) {
|
||||
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||
// @ts-ignore
|
||||
await interaction.editReply({ content: '❌ No hay elementos para eliminar.' });
|
||||
break;
|
||||
}
|
||||
|
||||
await interaction.reply({
|
||||
flags: MessageFlags.Ephemeral,
|
||||
content: 'Selecciona el elemento que quieres eliminar:',
|
||||
components: [
|
||||
{ type: 1, components: [ { type: 3, custom_id: 'delete_block_select', placeholder: 'Elige un elemento', options } ] },
|
||||
],
|
||||
});
|
||||
const replyMsg = await interaction.fetchReply();
|
||||
// @ts-ignore
|
||||
const selCollector = replyMsg.createMessageComponentCollector({ componentType: ComponentType.StringSelect, max: 1, time: 60000, filter: (it: any) => it.user.id === originalMessage.author.id });
|
||||
selCollector.on('collect', async (sel: any) => {
|
||||
const selectedValue = sel.values[0];
|
||||
if (selectedValue === 'cover_image') {
|
||||
// @ts-ignore
|
||||
blockState.coverImage = null;
|
||||
await sel.update({ content: '✅ Imagen de portada eliminada.', components: [] });
|
||||
} else {
|
||||
const idx = parseInt(selectedValue);
|
||||
blockState.components.splice(idx, 1);
|
||||
await sel.update({ content: '✅ Elemento eliminado.', components: [] });
|
||||
}
|
||||
|
||||
await updateEditor(editorMessage, {
|
||||
display: await DisplayComponentUtils.renderPreview(blockState, originalMessage.member!, originalMessage.guild!),
|
||||
components: DisplayComponentUtils.createEditorButtons(false),
|
||||
});
|
||||
selCollector.stop();
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "show_variables":
|
||||
await handleShowVariables(interaction);
|
||||
break;
|
||||
@@ -221,7 +328,7 @@ async function handleButtonInteraction(
|
||||
default:
|
||||
await interaction.reply({
|
||||
content: `⚠️ Funcionalidad \`${customId}\` en desarrollo.`,
|
||||
flags: MessageFlags.Ephemeral
|
||||
flags: MessageFlags.Ephemeral,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user