All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.freya022.botcommands.api.pagination.menu.buttonized.ButtonMenu.kt Maven / Gradle / Ivy

package io.github.freya022.botcommands.api.pagination.menu.buttonized

import io.github.freya022.botcommands.api.components.event.ButtonEvent
import io.github.freya022.botcommands.api.components.utils.ButtonContent
import io.github.freya022.botcommands.api.core.BContext
import io.github.freya022.botcommands.api.pagination.Paginators
import io.github.freya022.botcommands.api.pagination.menu.AbstractMenu
import net.dv8tion.jda.api.interactions.components.ActionRow
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder

/**
 * A paginator where each page is filled with a list of entries.
 *
 * @param E Type of the entries
 *
 * @see Paginators.buttonMenu
 */
class ButtonMenu internal constructor(
    context: BContext,
    builder: ButtonMenuBuilder
) : AbstractMenu>(
    context,
    builder,
    makePages(builder.entries, builder.transformer, builder.rowPrefixSupplier, builder.maxEntriesPerPage)
) {
    /**
     * A [ButtonContent] supplier for use in different paginators,
     * allowing you to use your own text and emojis on buttons.
     *
     * @param T Item type
     *
     * @see ButtonContent.fromLabel
     * @see ButtonContent.fromEmoji
     */
    fun interface ButtonContentSupplier {
        /**
         * Returns a [ButtonContent] based on the given item and the current page number of the paginator
         *
         * @param item  The item bound to this button
         * @param index The index of this item on the current page number of the paginator
         * @return The [ButtonContent] of this item
         */
        fun apply(item: T, index: Int): ButtonContent
    }

    private val buttonContentSupplier: ButtonContentSupplier = builder.buttonContentSupplier
    private val callback: SuspendingChoiceCallback = builder.callback
    private val reusable: Boolean = builder.reusable

    override fun putComponents(builder: MessageCreateBuilder) {
        super.putComponents(builder)

        pages[page]!!.entries
            .mapIndexed { i, item ->
                val styledContent = buttonContentSupplier.apply(item, i)
                buttons.of(styledContent).ephemeral()
                    .bindTo { event: ButtonEvent ->
                        if (reusable) {
                            restartTimeout()
                        } else {
                            cleanup()
                        }
                        callback(event, item)
                    }
                    .constraints(constraints)
                    .build()
            }
            .chunked(5, ActionRow::of)
            .also(builder::addComponents)
    }

    object Defaults {
        /** @see ButtonMenuBuilder.setReusable */
        @JvmStatic
        var reusable: Boolean = false
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy