Skip to content

Commit

Permalink
feat(anilist): add hide option (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranet authored Oct 27, 2024
1 parent 734fff9 commit 28e1a2d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 20 deletions.
11 changes: 6 additions & 5 deletions src/commands/search/anime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import { Command, RegisterCommand } from '@skyra/http-framework';
import { applyLocalizedBuilder } from '@skyra/http-framework-i18n';
import { ApplicationIntegrationType, InteractionContextType } from 'discord-api-types/v10';

const Root = LanguageKeys.Commands.AniList.Anime;
const Root = LanguageKeys.Commands.AniList;

@RegisterCommand((builder) =>
applyLocalizedBuilder(builder, Root.RootName, Root.RootDescription)
applyLocalizedBuilder(builder, Root.Anime.RootName, Root.Anime.RootDescription)
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall)
.setContexts(InteractionContextType.Guild, InteractionContextType.BotDM, InteractionContextType.PrivateChannel)
.addIntegerOption((option) => applyLocalizedBuilder(option, Root.OptionsAnime).setRequired(true).setAutocomplete(true))
.addIntegerOption((option) => applyLocalizedBuilder(option, Root.Anime.OptionsAnime).setRequired(true).setAutocomplete(true))
.addBooleanOption((option) => applyLocalizedBuilder(option, Root.OptionsHide))
)
export class UserCommand extends AnimeCommand<'anime'> {
public override async chatInputRun(interaction: Command.ChatInputInteraction, { anime }: AnimeCommand.Arguments<'anime'>) {
return this.handleResult(interaction, await anilistAnimeGet(anime), 'anime');
public override async chatInputRun(interaction: Command.ChatInputInteraction, { anime, hide }: AnimeCommand.Arguments<'anime'>) {
return this.handleResult(interaction, await anilistAnimeGet(anime), 'anime', hide);
}

protected override autocompleteFetch(options: AnimeCommand.AutocompleteArguments<'anime'>) {
Expand Down
11 changes: 6 additions & 5 deletions src/commands/search/manga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import { Command, RegisterCommand } from '@skyra/http-framework';
import { applyLocalizedBuilder } from '@skyra/http-framework-i18n';
import { ApplicationIntegrationType, InteractionContextType } from 'discord-api-types/v10';

const Root = LanguageKeys.Commands.AniList.Manga;
const Root = LanguageKeys.Commands.AniList;

@RegisterCommand((builder) =>
applyLocalizedBuilder(builder, Root.RootName, Root.RootDescription)
applyLocalizedBuilder(builder, Root.Manga.RootName, Root.Manga.RootDescription)
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall)
.setContexts(InteractionContextType.Guild, InteractionContextType.BotDM, InteractionContextType.PrivateChannel)
.addIntegerOption((option) => applyLocalizedBuilder(option, Root.OptionsManga).setRequired(true).setAutocomplete(true))
.addIntegerOption((option) => applyLocalizedBuilder(option, Root.Manga.OptionsManga).setRequired(true).setAutocomplete(true))
.addBooleanOption((option) => applyLocalizedBuilder(option, Root.OptionsHide))
)
export class UserCommand extends AnimeCommand<'manga'> {
public override async chatInputRun(interaction: Command.ChatInputInteraction, { manga }: AnimeCommand.Arguments<'manga'>) {
return this.handleResult(interaction, await anilistMangaGet(manga), 'manga');
public override async chatInputRun(interaction: Command.ChatInputInteraction, { manga, hide }: AnimeCommand.Arguments<'manga'>) {
return this.handleResult(interaction, await anilistMangaGet(manga), 'manga', hide);
}

protected override autocompleteFetch(options: AnimeCommand.AutocompleteArguments<'manga'>) {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/i18n/LanguageKeys/Commands/AniList.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { T } from '@skyra/http-framework-i18n';

export const OptionsHide = 'commands/anilist:optionsHide';

export * as Anime from '#lib/i18n/LanguageKeys/Commands/AniList/Anime';
export * as Manga from '#lib/i18n/LanguageKeys/Commands/AniList/Manga';

Expand Down
26 changes: 16 additions & 10 deletions src/lib/structures/AnimeCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { minutes } from '#lib/utilities/time-utilities';
import { EmbedBuilder, bold, hideLinkEmbed, hyperlink } from '@discordjs/builders';
import type { Result } from '@sapphire/result';
import { cutText, filterNullish, isNullishOrEmpty, isNullishOrZero } from '@sapphire/utilities';
import { Command, type AutocompleteInteractionArguments } from '@skyra/http-framework';
import { Command, type AutocompleteInteractionArguments, type MessageResponseOptions } from '@skyra/http-framework';
import { getSupportedLanguageT, getSupportedUserLanguageT, resolveUserKey, type TFunction, type TypedT } from '@skyra/http-framework-i18n';
import type { FetchError } from '@skyra/safe-fetch';
import { MessageFlags, type APIEmbed, type LocaleString } from 'discord-api-types/v10';
import { MessageFlags, type LocaleString } from 'discord-api-types/v10';

const Root = LanguageKeys.Commands.AniList;

Expand Down Expand Up @@ -49,19 +49,24 @@ export abstract class AnimeCommand<Kind extends 'anime' | 'manga'> extends Comma
return `${cutText(title, 100 - description.length)}${description}`;
}

protected handleResult(interaction: Command.ChatInputInteraction, result: Result<AnilistEntryTypeByKind<Kind> | null, FetchError>, kind: Kind) {
protected handleResult(
interaction: Command.ChatInputInteraction,
result: Result<AnilistEntryTypeByKind<Kind> | null, FetchError>,
kind: Kind,
hide: boolean | null | undefined
) {
hide ??= false;

const t = hide ? getSupportedUserLanguageT(interaction) : getSupportedLanguageT(interaction);
const response = result.match({
ok: (value) =>
isNullishOrEmpty(value)
? this.createErrorResponse(interaction, kind)
: this.createResponse(value, getSupportedLanguageT(interaction)),
ok: (value) => (isNullishOrEmpty(value) ? this.createErrorResponse(interaction, kind) : this.createResponse(value, t, hide)),
err: () => this.createErrorResponse(interaction, kind)
});
return interaction.reply(response);
}

protected createResponse(value: AnilistEntryTypeByKind<Kind>, t: TFunction): { embeds: APIEmbed[] } {
return { embeds: [this.createEmbed(value, t).toJSON()] };
protected createResponse(value: AnilistEntryTypeByKind<Kind>, t: TFunction, hide: boolean): MessageResponseOptions {
return { embeds: [this.createEmbed(value, t).toJSON()], flags: hide ? MessageFlags.Ephemeral : undefined };
}

protected createErrorResponse(interaction: Command.ChatInputInteraction, kind: Kind) {
Expand Down Expand Up @@ -164,4 +169,5 @@ export namespace AnimeCommand {
export type AutocompleteArguments<Kind extends 'anime' | 'manga'> = AutocompleteInteractionArguments<MakeArguments<Kind, string>>;
}

type MakeArguments<Kind extends 'anime' | 'manga', Value extends string | number> = Kind extends 'anime' ? { anime: Value } : { manga: Value };
type Pretty<Type extends object> = { [K in keyof Type]: Type[K] };
type MakeArguments<Kind extends 'anime' | 'manga', Value extends string | number> = Pretty<{ [key in Kind]: Value } & { hide?: boolean }>;
2 changes: 2 additions & 0 deletions src/locales/en-US/commands/anilist.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"optionsHideName": "hide",
"optionsHideDescription": "Whether to hide the response (default: False)",
"embedTitles": {
"chapters": "Amount of chapters",
"countryOfOrigin": "Country of origin",
Expand Down

0 comments on commit 28e1a2d

Please # to comment.