diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-06-19 17:08:00 -0400 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-06-19 17:08:00 -0400 |
commit | e17419dcb00b228afdc0ffca5b987e1e2da70065 (patch) | |
tree | 4f014c5a4454478b483015058c142a0d359107a9 /src/commands | |
parent | 8ef314c63ad5c3fa160b5ad876ef7ec315c7aa9e (diff) | |
download | tanzanite-e17419dcb00b228afdc0ffca5b987e1e2da70065.tar.gz tanzanite-e17419dcb00b228afdc0ffca5b987e1e2da70065.tar.bz2 tanzanite-e17419dcb00b228afdc0ffca5b987e1e2da70065.zip |
actually fix highlight (un)block
Diffstat (limited to 'src/commands')
-rw-r--r-- | src/commands/utilities/highlight-!.ts | 245 | ||||
-rw-r--r-- | src/commands/utilities/highlight-add.ts | 30 | ||||
-rw-r--r-- | src/commands/utilities/highlight-block.ts | 70 | ||||
-rw-r--r-- | src/commands/utilities/highlight-clear.ts | 2 | ||||
-rw-r--r-- | src/commands/utilities/highlight-matches.ts | 10 | ||||
-rw-r--r-- | src/commands/utilities/highlight-remove.ts | 12 | ||||
-rw-r--r-- | src/commands/utilities/highlight-show.ts | 11 | ||||
-rw-r--r-- | src/commands/utilities/highlight-unblock.ts | 66 |
8 files changed, 237 insertions, 209 deletions
diff --git a/src/commands/utilities/highlight-!.ts b/src/commands/utilities/highlight-!.ts index 6847737..a4b8f42 100644 --- a/src/commands/utilities/highlight-!.ts +++ b/src/commands/utilities/highlight-!.ts @@ -1,84 +1,142 @@ import { BushCommand, clientSendAndPermCheck, Highlight, HighlightWord, type SlashMessage } from '#lib'; import { Flag, type ArgumentGeneratorReturn, type SlashOption } from 'discord-akairo'; -import { - ApplicationCommandOptionType, - ApplicationCommandSubCommandData, - type AutocompleteInteraction, - type CacheType -} from 'discord.js'; +import { ApplicationCommandOptionType, Constants, type AutocompleteInteraction, type CacheType } from 'discord.js'; +import { DeepWritable } from 'ts-essentials'; -type Unpacked<T> = T extends (infer U)[] ? U : T; - -export const highlightCommandArgs: { - [Command in keyof typeof highlightSubcommands]: (Unpacked<Required<ApplicationCommandSubCommandData['options']>> & { - retry?: string; - })[]; -} = { - add: [ - { - name: 'word', - description: 'What word do you want to highlight?', - retry: '{error} Enter a valid word.', - type: ApplicationCommandOptionType.String, - required: true - } - // { - // name: 'regex', - // description: 'Should the word be matched using regular expression?', - // type: ApplicationCommandOptionType.Boolean, - // required: false - // } - ], - remove: [ - { - name: 'word', - description: 'Which word do you want to stop highlighting?', - retry: '{error} Enter a valid word.', - type: ApplicationCommandOptionType.String, - required: true, - autocomplete: true - } - ], - block: [ - { - name: 'target', - description: 'What user/channel would you like to prevent from triggering your highlights?', - retry: '{error} Enter a valid user or channel.', - type: ApplicationCommandOptionType.String, - required: true - } - ], - unblock: [ - { - name: 'target', - description: 'What user/channel would you like to allow triggering your highlights again?', - retry: '{error} Enter a valid user or channel.', - type: ApplicationCommandOptionType.String, - required: true - } - ], - show: [], - clear: [], - matches: [ - { - name: 'phrase', - description: 'What phrase would you like to test your highlighted words against?', - retry: '{error} Enter a valid phrase to test.', - type: ApplicationCommandOptionType.String, - required: true - } - ] -}; +function deepWriteable<T>(obj: T): DeepWritable<T> { + return obj as DeepWritable<T>; +} -export const highlightSubcommands = { - add: 'Add a word to highlight.', - remove: 'Stop highting a word.', - block: 'Block a user or channel from triggering your highlights.', - unblock: 'Re-allow a user or channel to triggering your highlights.', - show: 'List all your current highlighted words.', - clear: 'Remove all of your highlighted words.', - matches: 'Test a phrase to see if it matches your current highlighted words.' -} as const; +export const highlightSubcommands = deepWriteable({ + add: { + description: 'Add a word to highlight.', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'word', + description: 'What word do you want to highlight?', + retry: '{error} Enter a valid word.', + type: ApplicationCommandOptionType.String, + required: true + } + /* { + name: 'regex', + description: 'Should the word be matched using regular expression?', + type: ApplicationCommandOptionType.Boolean, + required: false + } */ + ] + }, + remove: { + description: 'Stop highting a word.', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'word', + description: 'Which word do you want to stop highlighting?', + retry: '{error} Enter a valid word.', + type: ApplicationCommandOptionType.String, + required: true, + autocomplete: true + } + ] + }, + block: { + description: 'Block a user or channel from triggering your highlights.', + type: ApplicationCommandOptionType.SubcommandGroup, + options: [ + { + name: 'user', + description: 'Block a user from triggering your highlights.', + start: 'What user/channel would you like to prevent from triggering your highlights?', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'target', + description: 'What user would you like to prevent from triggering your highlights?', + retry: '{error} Enter a valid user or channel.', + type: ApplicationCommandOptionType.User, + resolve: 'Member', + required: true + } + ] + }, + { + name: 'channel', + description: 'Block a channel from triggering your highlights.', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'target', + description: 'What channel would you like to prevent from triggering your highlights?', + type: ApplicationCommandOptionType.Channel, + channelTypes: Constants.TextBasedChannelTypes, + required: true + } + ] + } + ] + }, + unblock: { + description: 'Re-allow a user or channel to triggering your highlights.', + type: ApplicationCommandOptionType.SubcommandGroup, + options: [ + { + name: 'user', + description: 'Re-allow a user to triggering your highlights', + start: 'What user/channel would you like to allow triggering your highlights again?', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'target', + description: 'What user would you like to allow triggering your highlights again?', + retry: '{error} Enter a valid user or channel.', + type: ApplicationCommandOptionType.User, + resolve: 'Member', + required: true + } + ] + }, + { + name: 'channel', + description: 'Re-allow a channel to triggering your highlights.', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'target', + description: 'What channel would you like to prevent from triggering your highlights?', + type: ApplicationCommandOptionType.Channel, + channelTypes: Constants.TextBasedChannelTypes, + required: true + } + ] + } + ] + }, + show: { + description: 'List all your current highlighted words.', + type: ApplicationCommandOptionType.Subcommand, + options: [] + }, + clear: { + description: 'Remove all of your highlighted words.', + type: ApplicationCommandOptionType.Subcommand, + options: [] + }, + matches: { + description: 'Test a phrase to see if it matches your current highlighted words.', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'phrase', + description: 'What phrase would you like to test your highlighted words against?', + retry: '{error} Enter a valid phrase to test.', + type: ApplicationCommandOptionType.String, + required: true + } + ] + } +} as const); export default class HighlightCommand extends BushCommand { public constructor() { @@ -104,23 +162,9 @@ export default class HighlightCommand extends BushCommand { 'highlight clear', 'highlight matches I really like to eat bacon with my spaghetti' ], - slashOptions: Object.entries(highlightSubcommands).map((args) => { - // typescript being annoying - const [subcommand, description] = args as [keyof typeof highlightSubcommands, typeof args[1]]; - - return { - name: subcommand, - description, - type: ApplicationCommandOptionType.Subcommand, - options: highlightCommandArgs[subcommand].map((arg) => ({ - name: arg.name, - description: arg.description, - type: arg.type, - required: arg.required, - autocomplete: arg.autocomplete - })) - } as SlashOption; - }), + slashOptions: Object.entries(highlightSubcommands).map( + ([subcommand, options]) => ({ name: subcommand, ...options } as SlashOption) + ), slash: true, channel: 'guild', clientPermissions: (m) => clientSendAndPermCheck(m), @@ -143,9 +187,16 @@ export default class HighlightCommand extends BushCommand { return Flag.continue(`highlight-${subcommand}`); } - public override async execSlash(message: SlashMessage, args: { subcommand: keyof typeof highlightSubcommands }) { + public override async exec() { + throw new Error('This command is not meant to be executed directly.'); + } + + public override async execSlash( + message: SlashMessage, + args: { subcommand: keyof typeof highlightSubcommands; subcommandGroup?: string } + ) { // manual `Flag.continue` - const subcommand = this.handler.modules.get(`highlight-${args.subcommand}`)!; + const subcommand = this.handler.modules.get(`highlight-${args.subcommandGroup ?? args.subcommand}`)!; return subcommand.exec(message, args); } @@ -153,7 +204,7 @@ export default class HighlightCommand extends BushCommand { if (!interaction.inCachedGuild()) return interaction.respond([{ name: 'You must be in a server to use this command.', value: 'error' }]); - switch (interaction.options.getSubcommand(true)) { + switch (interaction.options.getSubcommandGroup(false) ?? interaction.options.getSubcommand(true)) { case 'word': { const { words } = (await Highlight.findOne({ where: { guild: interaction.guild.id, user: interaction.user.id } diff --git a/src/commands/utilities/highlight-add.ts b/src/commands/utilities/highlight-add.ts index 3547c90..facee2c 100644 --- a/src/commands/utilities/highlight-add.ts +++ b/src/commands/utilities/highlight-add.ts @@ -1,34 +1,34 @@ import { AllowedMentions, BushCommand, emojis, format, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; +import { highlightSubcommands } from './highlight-!.js'; export default class HighlightAddCommand extends BushCommand { public constructor() { super('highlight-add', { aliases: [], category: 'utilities', - description: highlightSubcommands.add, + description: highlightSubcommands.add.description, args: [ { id: 'word', - description: highlightCommandArgs.add[0].description, + description: highlightSubcommands.add.options[0].description, type: 'string', match: 'rest', - prompt: highlightCommandArgs.add[0].description, - retry: highlightCommandArgs.add[0].retry, - optional: !highlightCommandArgs.add[0].required, + prompt: highlightSubcommands.add.options[0].description, + retry: highlightSubcommands.add.options[0].retry, + optional: !highlightSubcommands.add.options[0].required, only: 'text', slashType: false } - // { - // id: 'regex', - // description: highlightCommandArgs.add[1].description, - // match: 'flag', - // flag: '--regex', - // prompt: highlightCommandArgs.add[1].description, - // only: 'text', - // slashType: false - // } + /* { + id: 'regex', + description: highlightSubcommands.add.options[1].description, + match: 'flag', + flag: '--regex', + prompt: highlightSubcommands.add.options[1].description, + only: 'text', + slashType: false + } */ ], usage: [], examples: [], diff --git a/src/commands/utilities/highlight-block.ts b/src/commands/utilities/highlight-block.ts index 5429071..9ee8a5a 100644 --- a/src/commands/utilities/highlight-block.ts +++ b/src/commands/utilities/highlight-block.ts @@ -1,25 +1,16 @@ -import { - addToArray, - AllowedMentions, - Arg, - BushCommand, - emojis, - Highlight, - type ArgType, - type CommandMessage, - type SlashMessage -} from '#lib'; +import { AllowedMentions, BushCommand, emojis, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { Argument, ArgumentGeneratorReturn } from 'discord-akairo'; -import { Channel, GuildMember } from 'discord.js'; -import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; +import { Channel, GuildMember, User } from 'discord.js'; +import { BlockResult } from '../../lib/common/HighlightManager.js'; +import { highlightSubcommands } from './highlight-!.js'; export default class HighlightBlockCommand extends BushCommand { public constructor() { super('highlight-block', { aliases: [], category: 'utilities', - description: highlightSubcommands.block, + description: highlightSubcommands.block.description, usage: [], examples: [], clientPermissions: [], @@ -28,24 +19,26 @@ export default class HighlightBlockCommand extends BushCommand { } public override *args(): ArgumentGeneratorReturn { - const target: ArgType<'member' | 'channel'> = yield { - type: Argument.union('member', 'channel'), + const target: ArgType<'member' | 'textBasedChannel'> = yield { + type: Argument.union('member', 'textBasedChannel'), match: 'rest', prompt: { - start: highlightCommandArgs.block[0].description, - retry: highlightCommandArgs.block[0].retry, - optional: !highlightCommandArgs.block[0].required + start: highlightSubcommands.block.options[0].start, + retry: highlightSubcommands.block.options[0].options[0].retry, + optional: !highlightSubcommands.block.options[0].options[0].required } }; return { target }; } - public override async exec(message: CommandMessage | SlashMessage, args: { target: string | ArgType<'member' | 'channel'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { target: ArgType<'member' | 'textBasedChannel'> }) { assert(message.inGuild()); - args.target = - typeof args.target === 'string' ? (await Arg.cast(Arg.union('member', 'channel'), message, args.target))! : args.target; + if (args.target instanceof User && message.util.isSlashMessage(message)) + args.target = message.interaction.options.getMember('target')!; + + if (!args.target) return message.util.reply(`${emojis.error} Could not resolve member.`); if (!args.target || !(args.target instanceof GuildMember || args.target instanceof Channel)) return await message.util.reply(`${emojis.error} You can only block users or channels.`); @@ -53,26 +46,21 @@ export default class HighlightBlockCommand extends BushCommand { if (args.target instanceof Channel && !args.target.isTextBased()) return await message.util.reply(`${emojis.error} You can only block text-based channels.`); - const [highlight] = await Highlight.findOrCreate({ - where: { guild: message.guild.id, user: message.author.id } - }); - - const key = `blacklisted${args.target instanceof Channel ? 'Channels' : 'Users'}` as const; + const res = await this.client.highlightManager.addBlock(message.guildId, message.author.id, args.target); - if (highlight[key].includes(args.target.id)) - return await message.util.reply({ - // eslint-disable-next-line @typescript-eslint/no-base-to-string - content: `${emojis.error} You have already blocked ${args.target}.`, - allowedMentions: AllowedMentions.none() - }); - - highlight[key] = addToArray(highlight[key], args.target.id); - await highlight.save(); + /* eslint-disable @typescript-eslint/no-base-to-string */ + const content = (() => { + switch (res) { + case BlockResult.ALREADY_BLOCKED: + return `${emojis.error} You have already blocked ${args.target}.`; + case BlockResult.ERROR: + return `${emojis.error} An error occurred while blocking ${args.target}.`; + case BlockResult.SUCCESS: + return `${emojis.success} Successfully blocked ${args.target} from triggering your highlights.`; + } + })(); + /* eslint-enable @typescript-eslint/no-base-to-string */ - return await message.util.reply({ - // eslint-disable-next-line @typescript-eslint/no-base-to-string - content: `${emojis.success} Successfully blocked ${args.target} from triggering your highlights.`, - allowedMentions: AllowedMentions.none() - }); + return await message.util.reply({ content, allowedMentions: AllowedMentions.none() }); } } diff --git a/src/commands/utilities/highlight-clear.ts b/src/commands/utilities/highlight-clear.ts index 9e1ed62..a5ff19e 100644 --- a/src/commands/utilities/highlight-clear.ts +++ b/src/commands/utilities/highlight-clear.ts @@ -7,7 +7,7 @@ export default class HighlightClearCommand extends BushCommand { super('highlight-clear', { aliases: [], category: 'utilities', - description: highlightSubcommands.clear, + description: highlightSubcommands.clear.description, usage: [], examples: [], clientPermissions: [], diff --git a/src/commands/utilities/highlight-matches.ts b/src/commands/utilities/highlight-matches.ts index 7bf94fd..8964af8 100644 --- a/src/commands/utilities/highlight-matches.ts +++ b/src/commands/utilities/highlight-matches.ts @@ -2,14 +2,14 @@ import { BushCommand, ButtonPaginator, chunk, colors, emojis, type ArgType, type import assert from 'assert'; import { type ArgumentGeneratorReturn } from 'discord-akairo'; import { type APIEmbed } from 'discord.js'; -import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; +import { highlightSubcommands } from './highlight-!.js'; export default class HighlightMatchesCommand extends BushCommand { public constructor() { super('highlight-matches', { aliases: [], category: 'utilities', - description: highlightSubcommands.matches, + description: highlightSubcommands.matches.description, usage: [], examples: [], clientPermissions: [], @@ -22,9 +22,9 @@ export default class HighlightMatchesCommand extends BushCommand { type: 'string', match: 'rest', prompt: { - start: highlightCommandArgs.matches[0].description, - retry: highlightCommandArgs.matches[0].retry, - optional: !highlightCommandArgs.matches[0].required + start: highlightSubcommands.matches.options[0].description, + retry: highlightSubcommands.matches.options[0].retry, + optional: !highlightSubcommands.matches.options[0].required } }; diff --git a/src/commands/utilities/highlight-remove.ts b/src/commands/utilities/highlight-remove.ts index 4dddff6..67cf029 100644 --- a/src/commands/utilities/highlight-remove.ts +++ b/src/commands/utilities/highlight-remove.ts @@ -1,22 +1,22 @@ import { AllowedMentions, BushCommand, emojis, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; +import { highlightSubcommands } from './highlight-!.js'; export default class HighlightRemoveCommand extends BushCommand { public constructor() { super('highlight-remove', { aliases: [], category: 'utilities', - description: highlightSubcommands.remove, + description: highlightSubcommands.remove.description, args: [ { id: 'word', - description: highlightCommandArgs.remove[0].description, + description: highlightSubcommands.remove.options[0].description, type: 'string', match: 'rest', - prompt: highlightCommandArgs.remove[0].description, - retry: highlightCommandArgs.remove[0].retry, - optional: !highlightCommandArgs.remove[0].required, + prompt: highlightSubcommands.remove.options[0].description, + retry: highlightSubcommands.remove.options[0].retry, + optional: !highlightSubcommands.remove.options[0].required, only: 'text', slashType: false } diff --git a/src/commands/utilities/highlight-show.ts b/src/commands/utilities/highlight-show.ts index 0558005..48b4971 100644 --- a/src/commands/utilities/highlight-show.ts +++ b/src/commands/utilities/highlight-show.ts @@ -8,7 +8,7 @@ export default class HighlightShowCommand extends BushCommand { super('highlight-show', { aliases: [], category: 'utilities', - description: highlightSubcommands.show, + description: highlightSubcommands.show.description, usage: [], examples: [], clientPermissions: [], @@ -19,9 +19,7 @@ export default class HighlightShowCommand extends BushCommand { public override async exec(message: CommandMessage | SlashMessage) { assert(message.inGuild()); - const [highlight] = await Highlight.findOrCreate({ - where: { guild: message.guild.id, user: message.author.id } - }); + const [highlight] = await Highlight.findOrCreate({ where: { guild: message.guild.id, user: message.author.id } }); void this.client.highlightManager.syncCache(); @@ -60,9 +58,6 @@ export default class HighlightShowCommand extends BushCommand { } ]); - return await message.util.reply({ - embeds: [embed], - allowedMentions: AllowedMentions.none() - }); + return await message.util.reply({ embeds: [embed], allowedMentions: AllowedMentions.none() }); } } diff --git a/src/commands/utilities/highlight-unblock.ts b/src/commands/utilities/highlight-unblock.ts index 7f416eb..d70fb28 100644 --- a/src/commands/utilities/highlight-unblock.ts +++ b/src/commands/utilities/highlight-unblock.ts @@ -1,24 +1,16 @@ -import { - AllowedMentions, - BushCommand, - emojis, - Highlight, - removeFromArray, - type ArgType, - type CommandMessage, - type SlashMessage -} from '#lib'; +import { AllowedMentions, BushCommand, emojis, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { Argument, ArgumentGeneratorReturn } from 'discord-akairo'; -import { Channel, GuildMember } from 'discord.js'; -import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; +import { Channel, GuildMember, User } from 'discord.js'; +import { UnblockResult } from '../../lib/common/HighlightManager.js'; +import { highlightSubcommands } from './highlight-!.js'; export default class HighlightUnblockCommand extends BushCommand { public constructor() { super('highlight-unblock', { aliases: [], category: 'utilities', - description: highlightSubcommands.unblock, + description: highlightSubcommands.unblock.description, usage: [], examples: [], clientPermissions: [], @@ -27,46 +19,48 @@ export default class HighlightUnblockCommand extends BushCommand { } public override *args(): ArgumentGeneratorReturn { - const target: ArgType<'member' | 'channel'> = yield { - type: Argument.union('member', 'channel'), + const target: ArgType<'member' | 'textBasedChannel'> = yield { + type: Argument.union('member', 'textBasedChannel'), match: 'rest', prompt: { - start: highlightCommandArgs.unblock[0].description, - retry: highlightCommandArgs.unblock[0].retry, - optional: !highlightCommandArgs.unblock[0].required + start: highlightSubcommands.unblock.options[0].start, + retry: highlightSubcommands.unblock.options[0].options[0].retry, + optional: !highlightSubcommands.unblock.options[0].options[0].retry } }; return { target }; } - public override async exec(message: CommandMessage | SlashMessage, args: { target: ArgType<'user' | 'role' | 'member'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { target: ArgType<'member' | 'textBasedChannel'> }) { assert(message.inGuild()); + if (args.target instanceof User && message.util.isSlashMessage(message)) + args.target = message.interaction.options.getMember('target')!; + + if (!args.target) return message.util.reply(`${emojis.error} Could not resolve member.`); + if (!(args.target instanceof GuildMember || args.target instanceof Channel)) return await message.util.reply(`${emojis.error} You can only unblock users or channels.`); if (args.target instanceof Channel && !args.target.isTextBased()) return await message.util.reply(`${emojis.error} You can only unblock text-based channels.`); - const [highlight] = await Highlight.findOrCreate({ - where: { guild: message.guild.id, user: message.author.id } - }); - - const key = `blacklisted${args.target instanceof Channel ? 'Channels' : 'Users'}` as const; + const res = await this.client.highlightManager.removeBlock(message.guildId, message.author.id, args.target); - if (!highlight[key].includes(args.target.id)) - return await message.util.reply({ - content: `${emojis.error} ${args.target} is not blocked so cannot be unblock.`, - allowedMentions: AllowedMentions.none() - }); - - highlight[key] = removeFromArray(highlight[key], args.target.id); - await highlight.save(); + /* eslint-disable @typescript-eslint/no-base-to-string */ + const content = (() => { + switch (res) { + case UnblockResult.NOT_BLOCKED: + return `${emojis.error} ${args.target} is not blocked so cannot be unblock.`; + case UnblockResult.ERROR: + return `${emojis.error} An error occurred while unblocking ${args.target}.`; + case UnblockResult.SUCCESS: + return `${emojis.success} Successfully allowed ${args.target} to trigger your highlights.`; + } + })(); + /* eslint-enable @typescript-eslint/no-base-to-string */ - return await message.util.reply({ - content: `${emojis.success} Successfully allowed ${args.target} to trigger your highlights.`, - allowedMentions: AllowedMentions.none() - }); + return await message.util.reply({ content, allowedMentions: AllowedMentions.none() }); } } |