From 8ac59567b9f117d7293278a6b574b60fc183639d Mon Sep 17 00:00:00 2001 From: Michel Fedde Date: Tue, 27 May 2025 19:20:10 +0200 Subject: [PATCH] Adds icons to group list and adds new playdate --- public/icons/people-group-solid.svg | 1 + source/Discord/Commands/Groups.ts | 31 ++++++++++++++++++++--- source/Icons/IconCache.ts | 13 ++++++++-- source/Repositories/PlaydateRepository.ts | 16 ++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 public/icons/people-group-solid.svg diff --git a/public/icons/people-group-solid.svg b/public/icons/people-group-solid.svg new file mode 100644 index 0000000..16e3fd8 --- /dev/null +++ b/public/icons/people-group-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/Discord/Commands/Groups.ts b/source/Discord/Commands/Groups.ts index be96284..0b29d5c 100644 --- a/source/Discord/Commands/Groups.ts +++ b/source/Discord/Commands/Groups.ts @@ -3,7 +3,13 @@ import { Interaction, CommandInteraction, ChatInputCommandInteraction, - MessageFlags, GuildMemberRoleManager, InteractionReplyOptions, GuildMember, EmbedBuilder, AutocompleteInteraction + MessageFlags, + GuildMemberRoleManager, + InteractionReplyOptions, + GuildMember, + EmbedBuilder, + AutocompleteInteraction, + formatEmoji, roleMention, time } from "discord.js"; import {AutocompleteCommand, ChatInteractionCommand, Command} from "./Command"; import {GroupModel} from "../../Models/GroupModel"; @@ -17,6 +23,9 @@ import {GroupConfigurationRenderer} from "../../Groups/GroupConfigurationRendere import {GroupConfigurationHandler} from "../../Groups/GroupConfigurationHandler"; import {GroupConfigurationTransformers} from "../../Groups/GroupConfigurationTransformers"; import {GroupConfigurationRepository} from "../../Repositories/GroupConfigurationRepository"; +import {IconCache} from "../../Icons/IconCache"; +import {PlaydateRepository} from "../../Repositories/PlaydateRepository"; +import playdate from "../../Database/tables/Playdate"; export class GroupCommand implements Command, ChatInteractionCommand, AutocompleteCommand { private static GOODBYE_MESSAGES: string[] = [ @@ -109,15 +118,29 @@ export class GroupCommand implements Command, ChatInteractionCommand, Autocomple const repo = Container.get(GroupRepository.name); const groups = repo.findGroupsByMember(interaction.member); + const playdateRepo = Container.get(PlaydateRepository.name); + + const iconCache = Container.get(IconCache.name); + const embed = new EmbedBuilder() .setTitle("Your groups on this server:") .setFields( groups.map(group => { + const nextPlaydate = playdateRepo.getNextPlaydateForGroup(group); + + const values = [ + `${iconCache.getEmoji("people_group_solid")} ${roleMention(group.role.roleid)}` + ]; + + if (nextPlaydate) { + values.push( + `${iconCache.getEmoji("calendar_days_solid")} ${time(nextPlaydate.from_time, "F")}` + ) + } + return { name: group.name, - value: ` - Role: <@&${group.role.roleid}> - ` + value: values.join("\n") } }) ) diff --git a/source/Icons/IconCache.ts b/source/Icons/IconCache.ts index bc8ac02..65830b2 100644 --- a/source/Icons/IconCache.ts +++ b/source/Icons/IconCache.ts @@ -1,4 +1,4 @@ -import {Routes} from "discord.js"; +import {formatEmoji, Routes, Snowflake} from "discord.js"; import {DiscordClient} from "../Discord/DiscordClient"; export class IconCache { @@ -10,7 +10,7 @@ export class IconCache { } - public get(iconName: string): string | null { + public get(iconName: string): Snowflake | null { if (!this.existingIcons?.has(iconName)) { return null; } @@ -18,6 +18,15 @@ export class IconCache { return this.existingIcons?.get(iconName) ?? null; } + public getEmoji(iconName: string): string { + const id = this.get(iconName); + + return formatEmoji({ + id: id, + name: iconName + }); + } + public async set(iconName: string, pngBuffer: Buffer) { const pngBase64 = pngBuffer.toString("base64"); const iconDataUrl = `data:image/png;base64,${pngBase64}`; diff --git a/source/Repositories/PlaydateRepository.ts b/source/Repositories/PlaydateRepository.ts index d69b17f..55f0197 100644 --- a/source/Repositories/PlaydateRepository.ts +++ b/source/Repositories/PlaydateRepository.ts @@ -58,6 +58,22 @@ export class PlaydateRepository extends Repository { return finds.map((playdate) => this.convertToModelType(playdate, group)); } + getNextPlaydateForGroup(group: GroupModel): PlaydateModel | null { + let sql = `SELECT * FROM ${this.schema.name} WHERE groupid = ? AND time_from > ? ORDER BY time_from ASC LIMIT 1`; + + const find = this.database.fetch( + sql, + group.id, + Date.now() + ) + + if (!find) { + return null; + } + + return this.convertToModelType(find, group) + } + protected convertToModelType(intermediateModel: DBPlaydate | undefined, fixedGroup: Nullable = null): PlaydateModel { if (!intermediateModel) { throw new Error("Unable to convert the playdate model");