Add list moons command #449
10 changed files with 235 additions and 3 deletions
|
@ -7,7 +7,7 @@
|
||||||
# any secret values.
|
# any secret values.
|
||||||
|
|
||||||
BOT_TOKEN=
|
BOT_TOKEN=
|
||||||
BOT_VER=3.2.1
|
BOT_VER=3.3.0
|
||||||
BOT_AUTHOR=Vylpes
|
BOT_AUTHOR=Vylpes
|
||||||
BOT_OWNERID=147392775707426816
|
BOT_OWNERID=147392775707426816
|
||||||
BOT_CLIENTID=682942374040961060
|
BOT_CLIENTID=682942374040961060
|
||||||
|
@ -23,4 +23,6 @@ DB_NAME=vylbot
|
||||||
DB_AUTH_USER=dev
|
DB_AUTH_USER=dev
|
||||||
DB_AUTH_PASS=dev
|
DB_AUTH_PASS=dev
|
||||||
DB_SYNC=true
|
DB_SYNC=true
|
||||||
DB_LOGGING=true
|
DB_LOGGING=true
|
||||||
|
DB_ROOT_HOST=0.0.0.0
|
||||||
|
DB_DATA_LOCATION=./.temp/database
|
||||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -106,4 +106,4 @@ dist
|
||||||
config.json
|
config.json
|
||||||
.DS_Store
|
.DS_Store
|
||||||
ormconfig.json
|
ormconfig.json
|
||||||
.temp/
|
.temp/
|
||||||
|
|
10
database/3.3.0/1719856023429-CreateMoon/Up/01-Moon.sql
Normal file
10
database/3.3.0/1719856023429-CreateMoon/Up/01-Moon.sql
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
CREATE TABLE `moon` (
|
||||||
VylpesTester marked this conversation as resolved
|
|||||||
|
`Id` varchar(255) NOT NULL,
|
||||||
|
`WhenCreated` datetime NOT NULL,
|
||||||
|
`WhenUpdated` datetime NOT NULL,
|
||||||
|
`MoonNumber` int NOT NULL,
|
||||||
|
`UserId` varchar(255) NOT NULL,
|
||||||
|
`Description` varchar(255) NOT NULL
|
||||||
|
`WhenArchived` datetime NULL,
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
14
src/buttonEvents/moons.ts
Normal file
14
src/buttonEvents/moons.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import {ButtonInteraction} from "discord.js";
|
||||||
|
import {ButtonEvent} from "../type/buttonEvent";
|
||||||
|
import List from "./moons/list";
|
||||||
|
|
||||||
|
export default class Moons extends ButtonEvent {
|
||||||
|
public override async execute(interaction: ButtonInteraction): Promise<void> {
|
||||||
|
const action = interaction.customId.split(" ")[1];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "list":
|
||||||
|
await List(interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
src/buttonEvents/moons/list.ts
Normal file
53
src/buttonEvents/moons/list.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import {ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder} from "discord.js";
|
||||||
|
import Moon from "../../database/entities/Moon";
|
||||||
|
import EmbedColours from "../../constants/EmbedColours";
|
||||||
|
|
||||||
|
export default async function List(interaction: ButtonInteraction) {
|
||||||
|
if (!interaction.guild) return;
|
||||||
|
|
||||||
|
const userId = interaction.customId.split(" ")[2];
|
||||||
|
const page = interaction.customId.split(" ")[3];
|
||||||
|
|
||||||
|
if (!userId || !page) return;
|
||||||
|
|
||||||
|
const pageNumber = Number(page);
|
||||||
|
|
||||||
|
const member = interaction.guild.members.cache.find(x => x.user.id == userId);
|
||||||
|
|
||||||
|
const pageLength = 10;
|
||||||
|
|
||||||
|
const moons = await Moon.FetchPaginatedMoonsByUserId(userId, pageLength, pageNumber);
|
||||||
|
|
||||||
|
if (!moons || moons[0].length == 0) {
|
||||||
|
await interaction.reply(`${member?.user.username ?? "This user"} does not have any moons or page is invalid.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(moons[1] / pageLength);
|
||||||
|
|
||||||
|
const description = moons[0].flatMap(x => `${x.MoonNumber}. ${x.Description.slice(0, 15)}`);
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(`${member?.user.username}'s Moons`)
|
||||||
|
.setColor(EmbedColours.Ok)
|
||||||
|
.setDescription(description.join("\n"))
|
||||||
|
.setFooter({ text: `Page ${page + 1} of ${totalPages} · ${moons[1]} moons` });
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`moons list ${userId} ${pageNumber - 1}`)
|
||||||
|
.setLabel("Previous")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(pageNumber == 0),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`moons list ${userId} ${pageNumber + 1}`)
|
||||||
|
.setLabel("Next")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(pageNumber + 1 == totalPages));
|
||||||
|
|
||||||
|
await interaction.update({
|
||||||
|
embeds: [ embed ],
|
||||||
|
components: [ row ],
|
||||||
|
});
|
||||||
|
}
|
35
src/commands/304276391837302787/moons.ts
Normal file
35
src/commands/304276391837302787/moons.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { Command } from "../../type/command";
|
||||||
|
import { CommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||||
|
import ListMoons from "./moons/list";
|
||||||
|
|
||||||
|
export default class Moons extends Command {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.CommandBuilder = new SlashCommandBuilder()
|
||||||
|
.setName("moons")
|
||||||
|
.setDescription("View and create moons")
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('list')
|
||||||
|
.setDescription('List moons you have obtained')
|
||||||
|
.addUserOption(option =>
|
||||||
|
option
|
||||||
|
.setName("user")
|
||||||
|
.setDescription("The user to view (Defaults to yourself)"))
|
||||||
|
.addNumberOption(option =>
|
||||||
|
option
|
||||||
|
.setName("page")
|
||||||
|
.setDescription("The page to start with")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async execute(interaction: CommandInteraction) {
|
||||||
|
if (!interaction.isChatInputCommand()) return;
|
||||||
|
|
||||||
|
switch (interaction.options.getSubcommand()) {
|
||||||
|
case "list":
|
||||||
|
await ListMoons(interaction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
src/commands/304276391837302787/moons/list.ts
Normal file
45
src/commands/304276391837302787/moons/list.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import {ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder} from "discord.js";
|
||||||
|
import Moon from "../../../database/entities/Moon";
|
||||||
|
import EmbedColours from "../../../constants/EmbedColours";
|
||||||
|
|
||||||
|
export default async function ListMoons(interaction: CommandInteraction) {
|
||||||
|
const user = interaction.options.get("user")?.user ?? interaction.user;
|
||||||
|
const page = interaction.options.get("page")?.value as number ?? 0;
|
||||||
|
|
||||||
|
const pageLength = 10;
|
||||||
|
|
||||||
|
const moons = await Moon.FetchPaginatedMoonsByUserId(user.id, pageLength, page);
|
||||||
|
|
||||||
|
if (!moons || moons[0].length == 0) {
|
||||||
|
await interaction.reply(`${user.username} does not have any moons or page is invalid.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(moons[1] / pageLength);
|
||||||
|
|
||||||
|
const description = moons[0].flatMap(x => `${x.MoonNumber}. ${x.Description.slice(0, 15)}`);
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(`${user.username}'s Moons`)
|
||||||
|
.setColor(EmbedColours.Ok)
|
||||||
|
.setDescription(description.join("\n"))
|
||||||
|
.setFooter({ text: `Page ${page + 1} of ${totalPages} · ${moons[1]} moons` });
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`moons list ${user.id} ${page - 1}`)
|
||||||
|
.setLabel("Previous")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(page == 0),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`moons list ${user.id} ${page + 1}`)
|
||||||
|
.setLabel("Next")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setDisabled(page + 1 == totalPages));
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
embeds: [ embed ],
|
||||||
|
components: [ row ],
|
||||||
|
});
|
||||||
|
}
|
49
src/database/entities/Moon.ts
Normal file
49
src/database/entities/Moon.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import { Column, Entity, IsNull } from "typeorm";
|
||||||
|
import BaseEntity from "../../contracts/BaseEntity";
|
||||||
|
import AppDataSource from "../dataSources/appDataSource";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export default class Moon extends BaseEntity {
|
||||||
|
constructor(moonNumber: number, description: string, userId: string) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.MoonNumber = moonNumber;
|
||||||
|
this.Description = description;
|
||||||
|
this.UserId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
MoonNumber: number;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
Description: string;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
WhenArchived?: Date;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
UserId: string;
|
||||||
|
|
||||||
|
public static async FetchMoonsByUserId(userId: string): Promise<Moon[] | null> {
|
||||||
|
const repository = AppDataSource.getRepository(Moon);
|
||||||
|
|
||||||
|
const all = await repository.find({ where: { UserId: userId } });
|
||||||
|
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async FetchPaginatedMoonsByUserId(userId: string, pageLength: number, page: number): Promise<[ Moon[], number ]> {
|
||||||
|
const rangeStart = page * pageLength;
|
||||||
|
|
||||||
|
const repository = AppDataSource.getRepository(Moon);
|
||||||
|
|
||||||
|
const moons = await repository.findAndCount({
|
||||||
|
where: { UserId: userId, WhenArchived: IsNull() },
|
||||||
|
order: { MoonNumber: "ASC" },
|
||||||
|
skip: rangeStart,
|
||||||
|
take: pageLength,
|
||||||
|
});
|
||||||
|
|
||||||
|
return moons;
|
||||||
|
}
|
||||||
|
}
|
15
src/database/migrations/3.3/1719856023429-CreateMoon.ts
Normal file
15
src/database/migrations/3.3/1719856023429-CreateMoon.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||||
|
import MigrationHelper from "../../../helpers/MigrationHelper"
|
||||||
|
|
||||||
|
export class CreateMoon1719856023429 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
MigrationHelper.Up('1719856023429-CreateMoon', '3.3.0', [
|
||||||
|
"01-Moon",
|
||||||
|
], queryRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,9 @@ import AddLobby from "./commands/501231711271780357/Lobby/add";
|
||||||
import RemoveLobby from "./commands/501231711271780357/Lobby/remove";
|
import RemoveLobby from "./commands/501231711271780357/Lobby/remove";
|
||||||
import ListLobby from "./commands/501231711271780357/Lobby/list";
|
import ListLobby from "./commands/501231711271780357/Lobby/list";
|
||||||
|
|
||||||
|
// Command Imports: Potato Talk
|
||||||
|
import Moons from "./commands/304276391837302787/moons";
|
||||||
|
|
||||||
// Event Imports
|
// Event Imports
|
||||||
import GuildMemberAdd from "./events/MemberEvents/GuildMemberAdd";
|
import GuildMemberAdd from "./events/MemberEvents/GuildMemberAdd";
|
||||||
import GuildMemberRemove from "./events/MemberEvents/GuildMemberRemove";
|
import GuildMemberRemove from "./events/MemberEvents/GuildMemberRemove";
|
||||||
|
@ -38,6 +41,7 @@ import MessageCreate from "./events/MessageEvents/MessageCreate";
|
||||||
|
|
||||||
// Button Event Imports
|
// Button Event Imports
|
||||||
import Verify from "./buttonEvents/verify";
|
import Verify from "./buttonEvents/verify";
|
||||||
|
import MoonsButtonEvent from "./buttonEvents/moons";
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
public static RegisterCommands() {
|
public static RegisterCommands() {
|
||||||
|
@ -68,12 +72,16 @@ export default class Registry {
|
||||||
CoreClient.RegisterCommand("listlobby", new ListLobby(), "501231711271780357");
|
CoreClient.RegisterCommand("listlobby", new ListLobby(), "501231711271780357");
|
||||||
CoreClient.RegisterCommand("entry", new Entry(), "501231711271780357");
|
CoreClient.RegisterCommand("entry", new Entry(), "501231711271780357");
|
||||||
|
|
||||||
|
// Exclusive Commands: Potato Talk
|
||||||
|
CoreClient.RegisterCommand("moons", new Moons(), "304276391837302787");
|
||||||
|
|
||||||
// Add Exclusive Commands to Test Server
|
// Add Exclusive Commands to Test Server
|
||||||
CoreClient.RegisterCommand("lobby", new Lobby(), "442730357897429002");
|
CoreClient.RegisterCommand("lobby", new Lobby(), "442730357897429002");
|
||||||
CoreClient.RegisterCommand("addlobby", new AddLobby(), "442730357897429002");
|
CoreClient.RegisterCommand("addlobby", new AddLobby(), "442730357897429002");
|
||||||
CoreClient.RegisterCommand("removelobby", new RemoveLobby(), "442730357897429002");
|
CoreClient.RegisterCommand("removelobby", new RemoveLobby(), "442730357897429002");
|
||||||
CoreClient.RegisterCommand("listlobby", new ListLobby(), "442730357897429002");
|
CoreClient.RegisterCommand("listlobby", new ListLobby(), "442730357897429002");
|
||||||
CoreClient.RegisterCommand("entry", new Entry(), "442730357897429002");
|
CoreClient.RegisterCommand("entry", new Entry(), "442730357897429002");
|
||||||
|
CoreClient.RegisterCommand("moons", new Moons(), "442730357897429002");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisterEvents() {
|
public static RegisterEvents() {
|
||||||
|
@ -88,5 +96,6 @@ export default class Registry {
|
||||||
|
|
||||||
public static RegisterButtonEvents() {
|
public static RegisterButtonEvents() {
|
||||||
CoreClient.RegisterButtonEvent("verify", new Verify());
|
CoreClient.RegisterButtonEvent("verify", new Verify());
|
||||||
|
CoreClient.RegisterButtonEvent("moons", new MoonsButtonEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue
Need to specify the primary key
I haven't for previous migrations, is it worth still doing?