underctrl-io / commandkit

Only focus on what matters - Let CommandKit handle your commands and events in your Discord.js projects!
https://commandkit.js.org
MIT License
86 stars 11 forks source link

feat: add signal and buttonkit #21

Closed twlite closed 10 months ago

twlite commented 10 months ago

This PR introduces ButtonKit (ButtonBuilder) and signals.

Example

https://github.com/underctrl-io/commandkit/assets/46562212/af59023c-0813-4e34-86e8-91d107ee40e6

Code

import type { SlashCommandProps, CommandOptions, CommandData } from 'commandkit';
import { ButtonKit, createEffect, createSignal } from 'commandkit';

import { ButtonStyle, ActionRowBuilder, type ButtonInteraction } from 'discord.js';

export const data: CommandData = {
    name: 'count',
    description: 'Counter boi!',
};

function getButtons() {
    const dec = new ButtonKit()
        .setEmoji('βž–')
        .setStyle(ButtonStyle.Primary)
        .setCustomId('decrement');

    const reset = new ButtonKit()
        .setEmoji('0️⃣')
        .setStyle(ButtonStyle.Primary)
        .setCustomId('reset');

    const inc = new ButtonKit()
        .setEmoji('βž•')
        .setStyle(ButtonStyle.Primary)
        .setCustomId('increment');

    const trash = new ButtonKit()
        .setEmoji('πŸ—‘οΈ')
        .setStyle(ButtonStyle.Danger)
        .setCustomId('trash');

    const row = new ActionRowBuilder<ButtonKit>()
        .addComponents(dec, reset, inc, trash);

    return { dec, reset, inc, trash, row };
}

export async function run({ interaction }: SlashCommandProps) {
    const [count, setCount, dispose] = createSignal(0);
    const { dec, reset, inc, trash, row } = getButtons();

    let inter: ButtonInteraction;

    const message = await interaction.reply({
        content: `Count is ${count()}`,
        components: [row],
        fetchReply: true,
    });

    createEffect(() => {
        const value = count();

        inter?.update(`Count is ${value}`);
    });

    dec.onClick((interaction) => {
        inter = interaction;
        setCount((prev) => prev - 1);
    }, { message });

    reset.onClick((interaction) => {
        inter = interaction;
        setCount(0);
    }, { message });

    inc.onClick((interaction) => {
        inter = interaction;
        setCount((prev) => prev + 1);
    }, { message });

    trash.onClick(async (interaction) => {
        const disposed = row.setComponents(
            row.components.map((button) => button.setDisabled(true).onClick(null)),
        );

        dispose();

        await interaction.update({
            content: 'Finished counting!',
            components: [disposed],
        });
    }, { message });
}

export const options: CommandOptions = {
    devOnly: true,
};
netlify[bot] commented 10 months ago

Deploy Preview for commandkit ready!

Name Link
Latest commit ce59f5a3e359d6b6dfddf5ca6f38e501624ae04f
Latest deploy log https://app.netlify.com/sites/commandkit/deploys/6538b443e5c39b0008092f48
Deploy Preview https://deploy-preview-21--commandkit.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.