Skip to content

Commit

Permalink
fix: ヘルプコマンドのボタンをコマンド発行者しか押せないように修正 (#666)
Browse files Browse the repository at this point in the history
* Add ReplyPagesOptions

* Specify usersCanPaginate
  • Loading branch information
MikuroXina authored Jan 14, 2023
1 parent 7330886 commit 8d04ec8
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 45 deletions.
98 changes: 55 additions & 43 deletions src/adaptor/proxy/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
import { Schema, makeError } from '../../model/command-schema.js';
import type { EmbedPage } from '../../model/embed-message.js';
import type { RawMessage } from './middleware.js';
import type { ReplyPagesOptions } from '../../service/command/command-message.js';
import type { Snowflake } from '../../model/id.js';
import { convertEmbed } from '../embed-convert.js';
import { parseStrings } from './command/schema.js';
Expand Down Expand Up @@ -132,50 +133,61 @@ const CONTROLS_DISABLED: APIActionRowComponent<APIMessageActionRowComponent> =
const pagesFooter = (currentPage: number, pagesLength: number) =>
`ページ ${currentPage + 1}/${pagesLength}`;

const replyPages = (message: RawMessage) => async (pages: EmbedPage[]) => {
if (pages.length === 0) {
throw new Error('pages must not be empty array');
}
const replyPages =
(message: RawMessage) =>
async (pages: EmbedPage[], options?: ReplyPagesOptions) => {
if (pages.length === 0) {
throw new Error('pages must not be empty array');
}

const generatePage = (index: number) =>
convertEmbed(pages[index]).setFooter({
text: pagesFooter(index, pages.length)
});

const paginated = await message.reply({
embeds: [generatePage(0)],
components: [CONTROLS]
});

const generatePage = (index: number) =>
convertEmbed(pages[index]).setFooter({
text: pagesFooter(index, pages.length)
const collector = paginated.createMessageComponentCollector({
time: ONE_MINUTE_MS
});

const paginated = await message.reply({
embeds: [generatePage(0)],
components: [CONTROLS]
});

const collector = paginated.createMessageComponentCollector({
time: ONE_MINUTE_MS
});

let currentPage = 0;
collector.on('collect', async (interaction) => {
switch (interaction.customId) {
case 'prev':
if (0 < currentPage) {
currentPage -= 1;
} else {
currentPage = pages.length - 1;
}
break;
case 'next':
if (currentPage < pages.length - 1) {
currentPage += 1;
} else {
currentPage = 0;
}
break;
default:
const isLimitedToPaginate = options?.usersCanPaginate !== undefined;

let currentPage = 0;
collector.on('collect', async (interaction) => {
if (
isLimitedToPaginate &&
!options?.usersCanPaginate?.includes(interaction.user.id as Snowflake)
) {
return;
}
await interaction.update({ embeds: [generatePage(currentPage)] });
});
collector.on('end', async () => {
if (paginated.editable) {
await paginated.edit({ components: [CONTROLS_DISABLED] });
}
});
};
}

switch (interaction.customId) {
case 'prev':
if (0 < currentPage) {
currentPage -= 1;
} else {
currentPage = pages.length - 1;
}
break;
case 'next':
if (currentPage < pages.length - 1) {
currentPage += 1;
} else {
currentPage = 0;
}
break;
default:
return;
}
await interaction.update({ embeds: [generatePage(currentPage)] });
});
collector.on('end', async () => {
if (paginated.editable) {
await paginated.edit({ components: [CONTROLS_DISABLED] });
}
});
};
18 changes: 17 additions & 1 deletion src/service/command/command-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ import type { ParsedSchema, Schema } from '../../model/command-schema.js';

import type { Snowflake } from '../../model/id.js';

/**
* `CommandMessage.replyPages` のオプション。
*
* @export
* @interface ReplyPagesOptions
*/
export interface ReplyPagesOptions {
/**
* ページネーションのボタンを操作できるユーザの ID のリスト。
*
* @type {readonly Snowflake[]}
* @memberof ReplyPagesOptions
*/
readonly usersCanPaginate?: readonly Snowflake[];
}

/**
* コマンド形式のメッセージの抽象。
*
Expand Down Expand Up @@ -73,7 +89,7 @@ export interface CommandMessage<S extends Schema> {
* @param pages
* @memberof CommandMessage
*/
replyPages(pages: EmbedPage[]): Promise<void>;
replyPages(pages: EmbedPage[], options?: ReplyPagesOptions): Promise<void>;

/**
* このメッセージに `emoji` の絵文字でリアクションする。
Expand Down
4 changes: 3 additions & 1 deletion src/service/command/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ export class HelpCommand implements CommandResponder<typeof SCHEMA> {
const pages: EmbedPage[] = helpAndSchema.map((helpScheme) =>
this.buildField(helpScheme)
);
await message.replyPages(pages);
await message.replyPages(pages, {
usersCanPaginate: [message.senderId]
});
}

private buildField({
Expand Down

0 comments on commit 8d04ec8

Please sign in to comment.