From e8f1ea024bc6add1974eb8be413e7524e69a7f69 Mon Sep 17 00:00:00 2001 From: Jonathan <54381371+yaboyaxis@users.noreply.github.com> Date: Tue, 6 Apr 2021 02:51:07 -0400 Subject: [PATCH] feat: Custom status limit and multiple mention support --- backend/src/data/AFK.ts | 5 +++ backend/src/plugins/AFK/AFKPlugin.ts | 15 ++++++++ backend/src/plugins/AFK/commands/AFKCmd.ts | 9 ++--- .../plugins/AFK/events/AFKNotificationEvt.ts | 28 ++++++++++----- .../plugins/AFK/functions/buildAFKMessages.ts | 35 ++++++++++++++----- backend/src/plugins/AFK/types.ts | 5 +-- 6 files changed, 75 insertions(+), 22 deletions(-) diff --git a/backend/src/data/AFK.ts b/backend/src/data/AFK.ts index 483f47e4..a65bde24 100644 --- a/backend/src/data/AFK.ts +++ b/backend/src/data/AFK.ts @@ -28,4 +28,9 @@ export class AFK extends BaseRepository { return await this.afk.delete({ user_id }); } + + async isAfk(user_id: string) { + const afk = await this.afk.findOne({ user_id }); + return !!afk?.status; + } } diff --git a/backend/src/plugins/AFK/AFKPlugin.ts b/backend/src/plugins/AFK/AFKPlugin.ts index 839d6650..14ba1a3d 100644 --- a/backend/src/plugins/AFK/AFKPlugin.ts +++ b/backend/src/plugins/AFK/AFKPlugin.ts @@ -5,12 +5,15 @@ import { AFK } from "src/data/AFK"; import { AfkSetCmd } from "./commands/AFKCmd"; import { AFKNotificationEvt } from "./events/AFKNotificationEvt"; +import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; +import { StrictValidationError } from "../../validatorUtils"; const defaultOptions: PluginOptions = { config: { can_afk: false, allow_links: false, allow_invites: false, + max_status_limit: 12 }, overrides: [ { @@ -19,11 +22,22 @@ const defaultOptions: PluginOptions = { can_afk: true, allow_links: true, allow_invites: true, + max_status_limit: 12, } } ] } +const configPreprocessor: ConfigPreprocessorFn = options => { + if (options.config.max_status_limit) { + const max_limit = options.config.max_status_limit; + if (max_limit > 24) throw new StrictValidationError([ + `max_status_limit needs to be under 24 characters.` + ]); + } + return options; +} + export const AFKPlugin = zeppelinGuildPlugin()("afk", { showInDocs: true, info: { @@ -33,6 +47,7 @@ export const AFKPlugin = zeppelinGuildPlugin()("afk", { configSchema: ConfigSchema, defaultOptions, + configPreprocessor, commands: [AfkSetCmd], events: [AFKNotificationEvt], diff --git a/backend/src/plugins/AFK/commands/AFKCmd.ts b/backend/src/plugins/AFK/commands/AFKCmd.ts index ee34a235..4e6518f6 100644 --- a/backend/src/plugins/AFK/commands/AFKCmd.ts +++ b/backend/src/plugins/AFK/commands/AFKCmd.ts @@ -15,12 +15,13 @@ export const AfkSetCmd = afkCmd({ // Checks if the user is AFK, if so, return. const isAfk = await pluginData.state.afkUsers.getUserAFKStatus(msg.author.id); if (isAfk) return; - + const status = args.status.join(" "); // Check status length - if (status.length > 124) { - sendErrorMessage(pluginData, msg.channel, "Status length is above **124** characters."); + const maxStatusLength = pluginData.config.getForMember(msg.member).max_status_limit ?? 12; + if (status.length > maxStatusLength) { + sendErrorMessage(pluginData, msg.channel, `Status length is above **${maxStatusLength}** characters.`); return; } @@ -43,4 +44,4 @@ export const AfkSetCmd = afkCmd({ users: false, }); } -}) \ No newline at end of file +}) diff --git a/backend/src/plugins/AFK/events/AFKNotificationEvt.ts b/backend/src/plugins/AFK/events/AFKNotificationEvt.ts index 626a4bd7..e35381d2 100644 --- a/backend/src/plugins/AFK/events/AFKNotificationEvt.ts +++ b/backend/src/plugins/AFK/events/AFKNotificationEvt.ts @@ -7,22 +7,34 @@ export const AFKNotificationEvt = afkEvt({ listener: async ({ pluginData, args: { message } }) => { // Mention Check (if someone mentions the AFK user) if (message.mentions.length) { - const afk = await pluginData.state.afkUsers.getUserAFKStatus(message.mentions[0].id); - if (!afk) return; - - sendUserMentionMessage(message, afk.status); + const mentionedMembers: Array<{ id: string, status: string }> = []; + for (const user of message.mentions) { + const isAfk = await pluginData.state.afkUsers.isAfk(user.id); + if (isAfk) { + const afk = (await pluginData.state.afkUsers.getUserAFKStatus(user.id))!; + mentionedMembers.push({ + id: afk.user_id, + status: afk.status, + }); + } + } + + const user = mentionedMembers.length > 1 + ? mentionedMembers.map((u) => `<@!${u.id}>: **${u.status}**`) + : mentionedMembers[0]; + await sendUserMentionMessage(message, user); return; } // Self AFK Check (if user is the one that's AFK) - const afk = await pluginData.state.afkUsers.getUserAFKStatus(message.author.id); - if (!afk) return; + const user = await pluginData.state.afkUsers.getUserAFKStatus(message.author.id); + if (!user) return; try { await pluginData.state.afkUsers.clearAFKStatus(message.author.id); } catch (err) {} - sendWelcomeBackMessage(message); + await sendWelcomeBackMessage(message); } -}); \ No newline at end of file +}); diff --git a/backend/src/plugins/AFK/functions/buildAFKMessages.ts b/backend/src/plugins/AFK/functions/buildAFKMessages.ts index 8d858744..f4b183e9 100644 --- a/backend/src/plugins/AFK/functions/buildAFKMessages.ts +++ b/backend/src/plugins/AFK/functions/buildAFKMessages.ts @@ -1,14 +1,33 @@ import { Message } from "eris"; -export function sendUserMentionMessage(message: Message, status: string) { - return message.channel.createMessage({ +export function sendUserMentionMessage(message: Message, mentionedMembers: string[] | { id: string, status: string }) { + if (!(mentionedMembers instanceof Array)) { + const member = mentionedMembers as { id: string, status: string }; + return message.channel.createMessage({ allowedMentions: { - users: [message.author.id], - everyone: false, - roles: false, + users: [message.author.id], + everyone: false, + roles: false, }, - content: `<@!${message.author.id}>, the user mentioned is currently AFK: **${status}**`, - }); + content: `<@!${message.author.id}>, <@!${member.id}> is currently AFK: **${member.status}**`, + }); + } else { + const deliveredLength = mentionedMembers.length; + const arr = mentionedMembers.length > 3 ? mentionedMembers.splice(3) : mentionedMembers; + + return message.channel.createMessage({ + allowedMentions: { + users: [message.author.id], + everyone: false, + roles: false, + }, + content: `<@!${message.author.id}>, the following users mentioned are AFK:\n\n${mentionedMembers.join('\n')}${ + deliveredLength > 3 + ? `\n*+${arr.length} more...*` + : '' + }`, + }); + } } export function sendWelcomeBackMessage(message: Message) { @@ -20,4 +39,4 @@ export function sendWelcomeBackMessage(message: Message) { }, content: `<@!${message.author.id}>, welcome back!`, }); -} \ No newline at end of file +} diff --git a/backend/src/plugins/AFK/types.ts b/backend/src/plugins/AFK/types.ts index bf80a3f4..baed155d 100644 --- a/backend/src/plugins/AFK/types.ts +++ b/backend/src/plugins/AFK/types.ts @@ -6,6 +6,7 @@ export const ConfigSchema = t.type({ can_afk: t.boolean, allow_links: t.boolean, allow_invites: t.boolean, + max_status_limit: t.number, }); export type TConfigSchema = t.TypeOf; @@ -13,8 +14,8 @@ export interface AFKPluginType extends BasePluginType { config: TConfigSchema; state: { afkUsers: AFK; - } + } } export const afkCmd = guildCommand(); -export const afkEvt = guildEventListener(); \ No newline at end of file +export const afkEvt = guildEventListener();