Skip to content
Advertisement

members map with a limit per page

how could I make a member limit on a page? for example: only 10 members would appear on the first page, and to see the second page you would have to react with ⏩

const { MessageEmbed } = require('discord.js');


module.exports.run = async (client, message, args) => {
const role = message.mentions.roles.first() ||  message.guild.roles.cache.get(args[0]) || message.guild.roles.cache.find(r => r.name === args.slice(0).join(" "));

const embed = new MessageEmbed()
            .setTitle(`Members with a role`)
            .addFields(
        { name: 'alphabetical list', value: ````fixn${message.guild.roles.cache.get(role.id).members.map(m => m.user.tag.toUpperCase()).sort().join('n') || 'none'}````}
            )

        return message.channel.send(embed);
}

Advertisement

Answer

I would get the list of users as an array, then use slice to return a portion of the array. In your case I would do:

//Get a list of all user tags
    const list = msg.guild.roles.cache.get(role.id).members.map(m => m.user.tag.toUpperCase()).sort();

    //Let the user define the starting page
    var pageNum = (parseInt(args[0]) * 10) - 10;

    //Set a default option
    if (!pageNum) {
        pageNum = 0;
    };

    //Get 10 members, starting at the defined page
    //Ex: if args[0] was "2", it would give you entries 10-19 of the array
    var userList = list.slice(pageNum, pageNum + 9).join("n");

Now that you can get users based off of a page number, you just need a way to set it! createReactionCollector is what you’re looking for in this case. The discordjs.guide website has a great example of this that we can modify to fit our needs:

//Only respond to the two emojis, and only if the member who reacted is the message author
    const filter = (reaction, user) => ["◀️", "▶️"].includes(reaction.emoji.name) && user.id === msg.author.id;

    //Setting the time is generally a good thing to do, so that your bot isn't constantly waiting for new reactions
    //It's set to 2 minutes in this case, which should be plenty of time
    const collector = msg.createReactionCollector(filter, {
        time: 120000
    });

    collector.on('collect', (reaction, user) => {
        //Do stuff here
    });

    //We can just return when the reactor ends, send a message that the time is up, whatever we want!
    collector.on('end', collected => {
        return msg.channel.send("I'm done looking for reactions on the message!");
    });

Now that we can get users and await reactions, we only need to put everything together. I would put the list retrieval in a seperate function that you can call easily:

//Initially take the page number from user input if requested
    var page = parseInt(args[0]);

    if (!page) {
        page = 1;
    };

    //Send the message in a way that lets us edit it later
    const listMsg = await msg.channel.send("This is what will be reacted to!");

    //React in order
    await listMsg.react("◀️");
    await listMsg.react("▶️");

    const filter = (reaction, user) => ["◀️", "▶️"].includes(reaction.emoji.name) && user.id === msg.author.id;

    const collector = listMsg.createReactionCollector(filter, {
        time: 120000
    });

    collector.on('collect', (reaction, user) => {
        reaction.emoji.reaction.users.remove(user.id);

        switch (reaction.emoji.name) {
            case "◀️":
                //Decrement the page number
                --page;

                //Make sure we don't go back too far
                if (page < 1) {
                    page = 1;
                };

                listMsg.edit(getUsers(page));

                break;

            case "▶️":
                //Increment the page number
                ++page;

                listMsg.edit(getUsers(page));

                break;
        };
    });

    collector.on('end', collected => {
        return msg.channel.send("I'm done looking for reactions on the message!");
    });

    function getUsers(n) {
        const list = msg.guild.roles.cache.get(role.id).members.map(m => m.user.tag.toUpperCase()).sort();

        //Take the page from the function params
        var pageNum = (n * 10) - 10;

        if (!pageNum) {
            pageNum = 0;
        };

        return list.slice(pageNum, pageNum + 9).join("n");
    };

That’s pretty much it! Obviously you’ll have to tweak this to fit your own bot, but this code should be a great starting point.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement