Skip to content

Commit

Permalink
Merge pull request #11 from pattyjogal/queue_buttons
Browse files Browse the repository at this point in the history
Add button queue functionality
  • Loading branch information
pattyjogal authored Sep 17, 2021
2 parents 3b2255d + 4690c8e commit 2fa3fa7
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 35 deletions.
33 changes: 20 additions & 13 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
Client,
Intents,
} from "discord.js";
import { Client, Intents } from "discord.js";
import { Db } from "mongodb";

import cmd_register from './commands/register';
import cmd_tenmans from './commands/tenmans';
import cmd_register from "./commands/register";
import {
cmd_tenmans,
handleButton as tenmansHandleButton,
} from "./commands/tenmans";

export default (db: Db) => {
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
Expand All @@ -15,15 +15,22 @@ export default (db: Db) => {
});

client.on("interactionCreate", async (interaction) => {
if (!interaction.isCommand()) return;
if (interaction.isCommand()) {
const actions = {
register: cmd_register,
tenmans: cmd_tenmans,
};

const commands = {
"register": cmd_register,
"tenmans": cmd_tenmans
}
// Use function table to pass context to specific command
actions[interaction.commandName](interaction, db);
} else if (interaction.isButton()) {
const actions = {
tenmans: tenmansHandleButton,
};
const actionName = interaction.customId.split(".")[0];

// Use function table to pass context to specific command
commands[interaction.commandName](interaction, db);
actions[actionName](interaction, db);
}
});

return client;
Expand Down
17 changes: 13 additions & 4 deletions src/commands/command.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { CommandInteraction } from "discord.js";
import {
CommandInteraction,
MessageComponentInteraction,
} from "discord.js";
import { Db } from "mongodb";
import Member from "../models/member";

export abstract class Subcommand {
constructor(protected interaction: CommandInteraction, protected db: Db) {}
export type RepliableInteraction =
| MessageComponentInteraction
| CommandInteraction;

export abstract class MessageExecutable<T extends RepliableInteraction> {
constructor(protected interaction: T, protected db: Db) {}

abstract execute(): Promise<any>;
}

export abstract class RegisteredUserSubcommand extends Subcommand {
export abstract class RegisteredUserExecutable<
T extends RepliableInteraction
> extends MessageExecutable<T> {
protected user: Member;

async execute(): Promise<any> {
Expand Down
100 changes: 82 additions & 18 deletions src/commands/tenmans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,32 @@ import {
MessageEmbed,
TextChannel,
CommandInteraction,
MessageActionRow,
MessageButton,
Constants,
ButtonInteraction,
Interaction,
} from "discord.js";
import { Db } from "mongodb";
import Member from "../models/member";

import { RegisteredUserSubcommand, Subcommand } from "./command";
import {
MessageExecutable,
RegisteredUserExecutable,
RepliableInteraction,
} from "./command";

let tenmansQueue: Set<string> = new Set();
let tenmansQueue: Member[] = [];
let time: String | null;
let activeTenmansMessage: Message | null;

abstract class SubcommandTenmansQueue extends RegisteredUserSubcommand {
abstract class QueueAction<
T extends RepliableInteraction
> extends RegisteredUserExecutable<T> {
constructor(interaction: T, db: Db, protected queueId: string) {
super(interaction, db);
}

abstract updateQueue();

afterUserExecute(): Promise<any> {
Expand All @@ -32,27 +48,29 @@ abstract class SubcommandTenmansQueue extends RegisteredUserSubcommand {
}
}

class SubcommandTenmansJoin extends SubcommandTenmansQueue {
class JoinQueueButtonAction extends QueueAction<ButtonInteraction> {
updateQueue() {
tenmansQueue.add(this.user.gameTag);
tenmansQueue.push(this.user);
this.interaction.reply({
content: "Greetings! You've been added to the queue.",
ephemeral: true,
});
}
}

class SubcommandTenmansLeave extends SubcommandTenmansQueue {
class LeaveQueueButtonAction extends QueueAction<ButtonInteraction> {
updateQueue() {
tenmansQueue.delete(this.user.gameTag);
tenmansQueue = tenmansQueue.filter(
(member) => member.discordId !== this.user.discordId
);
this.interaction.reply({
content: "This is no problem; You've been removed from the queue.",
ephemeral: true,
});
}
}

class SubcommandTenmansStart extends Subcommand {
class SubcommandTenmansStart extends MessageExecutable<CommandInteraction> {
async execute(): Promise<any> {
const interaction_user = this.interaction.user;
const role = this.interaction.guild.roles.cache.find(
Expand All @@ -72,30 +90,55 @@ class SubcommandTenmansStart extends Subcommand {
return;
}
time = this.interaction.options.getString("time");
tenmansQueue.clear();
tenmansQueue = [];
const queueChannel = this.interaction.guild.channels.cache.get(
"887569137319149578"
) as TextChannel;

const queueId = "stub";

activeTenmansMessage = await queueChannel.send({
embeds: [createEmbed(time)],
components: [createQueueActionRow(queueId)],
});
}
}

async function cmd_tenmans(interaction, db: Db) {
export async function cmd_tenmans(interaction, db: Db) {
const commands: {
[key: string]: {
new (interaction: CommandInteraction, db: Db): Subcommand;
new (
interaction: Interaction,
db: Db
): MessageExecutable<CommandInteraction>;
};
} = {
join: SubcommandTenmansJoin,
leave: SubcommandTenmansLeave,
start: SubcommandTenmansStart,
};

// Wrap function call to pass same args to all methods
const call_fn = commands[interaction.options.getSubcommand()];
const command = new call_fn(interaction, db);
const Action = commands[interaction.options.getSubcommand()];
const command = new Action(interaction, db);
command.execute();
}

export async function handleButton(interaction: ButtonInteraction, db: Db) {
const commands: {
[key: string]: {
new (
interaction: ButtonInteraction,
db: Db,
queueId: string
): QueueAction<ButtonInteraction>;
};
} = {
join: JoinQueueButtonAction,
leave: LeaveQueueButtonAction,
};
const actionParts = interaction.customId.split(".");
const [commandName, queueId] = actionParts[actionParts.length - 1].split(":");
const Action = commands[commandName];
const command = new Action(interaction, db, queueId);
command.execute();
}

Expand All @@ -104,10 +147,31 @@ const createEmbed = (time) =>
.setColor("#0099ff")
.setTitle(`Ten Mans: ${time}`)
.addField(
"Queue",
tenmansQueue.size > 0 ? Array.from(tenmansQueue).join("\n") : "No Players"
"Discord Member",
tenmansQueue.length > 0
? tenmansQueue.map((member) => `<@${member.discordId}>`).join("\n")
: "No Players",
true
)
.addField(
"Valorant Tag",
tenmansQueue.length > 0
? tenmansQueue.map((member) => "`" + member.gameTag + "`").join("\n")
: "❌",
true
)
.setTimestamp()
.setFooter("Last Updated");

export default cmd_tenmans;
const createQueueActionRow = (queueId) => {
return new MessageActionRow().addComponents(
new MessageButton()
.setCustomId(`tenmans.join:${queueId}`)
.setLabel("Join")
.setStyle(Constants.MessageButtonStyles.SUCCESS),
new MessageButton()
.setCustomId(`tenmans.leave:${queueId}`)
.setLabel("Leave")
.setStyle(Constants.MessageButtonStyles.DANGER)
);
};

0 comments on commit 2fa3fa7

Please sign in to comment.