Skip to content

Commit

Permalink
Merge pull request #53 from tarolling/24-improved-leaderboards-format
Browse files Browse the repository at this point in the history
Improve leaderboards format
  • Loading branch information
tarolling authored Jul 14, 2024
2 parents 5f5da4b + 15863b1 commit 3e9aa60
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
69 changes: 65 additions & 4 deletions commands/rps/leaderboard.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,84 @@
const { SlashCommandBuilder } = require('discord.js');
const { SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, ComponentType } = require('discord.js');
const { fetchLeaderboards } = require('../../src/db');
const { leaderboard } = require('../../src/embeds');

const MAX_PAGES = 5;
const MAX_PLAYERS = 50;


module.exports = {
data: new SlashCommandBuilder()
.setName('lb')
.setDescription('View the global leaderboard.'),
async execute(interaction) {
await interaction.deferReply();

const { client } = interaction;

let players;
try {
await interaction.deferReply();
const players = await fetchLeaderboards();
players = await fetchLeaderboards(MAX_PLAYERS);
if (!players) {
return interaction.editReply({ content: 'Huh. I guess there are no active players.', ephemeral: true });
}
return interaction.editReply({ embeds: [leaderboard(players)] });
} catch (err) {
console.error(err);
return interaction.editReply({ content: 'An error occurred while trying to fetch the leaderboards.', ephemeral: true });
}

let playerInfo = [];

const lazyLoad = async (startIndex, endIndex) => {
for (let i = startIndex; i < endIndex; i++) {
playerInfo.push({
player: await client.users.fetch(players[i].user_id),
elo: players[i].elo
});
}
};

const numPerPage = MAX_PLAYERS / MAX_PAGES;
let currentPageIndex = 0;

await lazyLoad(currentPageIndex * numPerPage, (currentPageIndex * numPerPage) + numPerPage);

const backButton = new ButtonBuilder()
.setCustomId('back')
.setLabel('Back')
.setStyle(ButtonStyle.Secondary);
const forwardButton = new ButtonBuilder()
.setCustomId('forward')
.setLabel('Forward')
.setStyle(ButtonStyle.Secondary);
let row = new ActionRowBuilder()
.addComponents(forwardButton);
const message = await interaction.editReply({
embeds: [leaderboard(playerInfo.slice(currentPageIndex * numPerPage, (currentPageIndex * numPerPage) + numPerPage))],
components: [row]
});

const buttonFilter = i => i.user.id === interaction.user.id;
const collector = message.createMessageComponentCollector({ filter: buttonFilter, componentType: ComponentType.Button, idle: 60_000 });

collector.on('collect', async i => {
i.deferUpdate();
if (i.customId === 'back') {
currentPageIndex = Math.max(0, currentPageIndex - 1);
row.components = (currentPageIndex === 0) ? [forwardButton] : [backButton, forwardButton];
} else if (i.customId === 'forward') {
currentPageIndex = Math.min(MAX_PAGES - 1, currentPageIndex + 1);
if (playerInfo.length === currentPageIndex * numPerPage) await lazyLoad(currentPageIndex * numPerPage, (currentPageIndex * numPerPage) + numPerPage);
row.components = (currentPageIndex === MAX_PAGES - 1) ? [backButton] : [backButton, forwardButton];
}
await interaction.editReply({
embeds: [leaderboard(playerInfo.slice(currentPageIndex * numPerPage, (currentPageIndex * numPerPage) + numPerPage))],
components: [row]
});
collector.resetTimer({ idle: 60_000 });
});

collector.on('end', () => {
interaction.editReply({ components: [] });
});
}
};
4 changes: 2 additions & 2 deletions src/db/fetchLeaderboards.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { MongoClient, ServerApiVersion } = require('mongodb');


module.exports = async () => {
module.exports = async (numPlayers) => {
const dbClient = new MongoClient(process.env.DB_URI, {
serverApi: {
version: ServerApiVersion.v1,
Expand All @@ -14,7 +14,7 @@ module.exports = async () => {
await dbClient.connect();
const collection = dbClient.db('rps').collection('players');

const players = await collection.find().sort({ elo: -1 }).limit(10).toArray();
const players = await collection.find().sort({ elo: -1 }).limit(numPlayers).toArray();
if (!players || players?.length === 0) return null;

return players;
Expand Down
5 changes: 4 additions & 1 deletion src/embeds/leaderboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ module.exports = (data) => {
return new EmbedBuilder()
.setColor(defaultColor)
.setTitle('Global Leaderboard')
.addFields(data.map(({ user_id, elo }) => ({ name: `${elo}`, value: `<@${user_id}>` })))
.addFields(data.map(({ player, elo }) => ({
name: `${elo}`,
value: `${player.username} (<@${player.id}>)`
})))
.setFooter(footer);
};

0 comments on commit 3e9aa60

Please sign in to comment.