From 5056b4376a7a5aaada3a6a2a070d1023cba4affd Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Tue, 15 Dec 2020 15:18:08 +0200 Subject: [PATCH] Add pagination to !cases -mod --- backend/src/data/GuildCases.ts | 13 ++- backend/src/plugins/Cases/CasesPlugin.ts | 5 ++ .../Cases/functions/getRecentCasesByMod.ts | 12 +++ .../Cases/functions/getTotalCasesByMod.ts | 6 ++ .../ModActions/commands/CasesModCmd.ts | 82 ++++++++++++------- 5 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 backend/src/plugins/Cases/functions/getRecentCasesByMod.ts create mode 100644 backend/src/plugins/Cases/functions/getTotalCasesByMod.ts diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index 8404f8f1..67a1ad41 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -82,7 +82,17 @@ export class GuildCases extends BaseGuildRepository { }); } - async getRecentByModId(modId: string, count: number): Promise { + async getTotalCasesByModId(modId: string): Promise { + return this.cases.count({ + where: { + guild_id: this.guildId, + mod_id: modId, + is_hidden: 0, + }, + }); + } + + async getRecentByModId(modId: string, count: number, skip = 0): Promise { return this.cases.find({ relations: this.getRelations(), where: { @@ -90,6 +100,7 @@ export class GuildCases extends BaseGuildRepository { mod_id: modId, is_hidden: 0, }, + skip, take: count, order: { case_number: "DESC", diff --git a/backend/src/plugins/Cases/CasesPlugin.ts b/backend/src/plugins/Cases/CasesPlugin.ts index b4ce8e7f..f6f202bc 100644 --- a/backend/src/plugins/Cases/CasesPlugin.ts +++ b/backend/src/plugins/Cases/CasesPlugin.ts @@ -14,6 +14,8 @@ import { trimPluginDescription } from "../../utils"; import { getCaseSummary } from "./functions/getCaseSummary"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { mapToPublicFn } from "../../pluginUtils"; +import { getTotalCasesByMod } from "./functions/getTotalCasesByMod"; +import { getRecentCasesByMod } from "./functions/getRecentCasesByMod"; const defaultOptions = { config: { @@ -64,6 +66,9 @@ export const CasesPlugin = zeppelinGuildPlugin()("cases", { }; }, + getTotalCasesByMod: mapToPublicFn(getTotalCasesByMod), + getRecentCasesByMod: mapToPublicFn(getRecentCasesByMod), + getCaseEmbed: mapToPublicFn(getCaseEmbed), getCaseSummary: mapToPublicFn(getCaseSummary), }, diff --git a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts new file mode 100644 index 00000000..89ec703c --- /dev/null +++ b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts @@ -0,0 +1,12 @@ +import { GuildPluginData } from "knub"; +import { CasesPluginType } from "../types"; +import { Case } from "../../../data/entities/Case"; + +export function getRecentCasesByMod( + pluginData: GuildPluginData, + modId: string, + count: number, + skip = 0, +): Promise { + return pluginData.state.cases.getRecentByModId(modId, count, skip); +} diff --git a/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts b/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts new file mode 100644 index 00000000..5753f12e --- /dev/null +++ b/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts @@ -0,0 +1,6 @@ +import { GuildPluginData } from "knub"; +import { CasesPluginType } from "../types"; + +export function getTotalCasesByMod(pluginData: GuildPluginData, modId: string): Promise { + return pluginData.state.cases.getTotalCasesByModId(modId); +} diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 0757ee0b..6d84fc77 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -1,18 +1,21 @@ import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { trimLines, createChunkedMessage, emptyEmbedValue, sorter } from "../../../utils"; +import { trimLines, createChunkedMessage, emptyEmbedValue, sorter, resolveUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { asyncMap } from "../../../utils/async"; -import { EmbedOptions } from "eris"; +import { EmbedOptions, User } from "eris"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; +import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; const opts = { - mod: ct.resolvedMember({ option: true }), + mod: ct.userId({ option: true }), }; +const casesPerPage = 5; + export const CasesModCmd = modActionsCmd({ trigger: ["cases", "modlogs"], permission: "can_view", @@ -25,36 +28,55 @@ export const CasesModCmd = modActionsCmd({ ], async run({ pluginData, message: msg, args }) { - const modId = args.mod ? args.mod.id : msg.author.id; - const recentCases = await pluginData.state.cases.with("notes").getRecentByModId(modId, 5); - recentCases.sort(sorter("case_number", "ASC")); + const modId = args.mod || msg.author.id; + const mod = await resolveUser(pluginData.client, modId); + const modName = mod instanceof User ? `${mod.username}#${mod.discriminator}` : modId; - const mod = pluginData.client.users.get(modId); - const modName = mod ? `${mod.username}#${mod.discriminator}` : modId; + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const totalCases = await casesPlugin.getTotalCasesByMod(modId); - if (recentCases.length === 0) { + if (totalCases === 0) { sendErrorMessage(pluginData, msg.channel, `No cases by **${modName}**`); - } else { - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const lines = await asyncMap(recentCases, c => casesPlugin.getCaseSummary(c, true, msg.author.id)); - const prefix = getGuildPrefix(pluginData); - const embed: EmbedOptions = { - author: { - name: `Most recent 5 cases by ${modName}`, - icon_url: mod ? mod.avatarURL || mod.defaultAvatarURL : undefined, - }, - fields: [ - ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), - { - name: emptyEmbedValue, - value: trimLines(` - Use \`${prefix}case \` to see more information about an individual case - Use \`${prefix}cases \` to see a specific user's cases - `), - }, - ], - }; - msg.channel.createMessage({ embed }); + return; } + + const totalPages = Math.max(Math.ceil(totalCases / casesPerPage), 1); + const prefix = getGuildPrefix(pluginData); + + createPaginatedMessage( + pluginData.client, + msg.channel, + totalPages, + async page => { + const cases = await casesPlugin.getRecentCasesByMod(modId, casesPerPage, (page - 1) * casesPerPage); + const lines = await asyncMap(cases, c => casesPlugin.getCaseSummary(c, true, msg.author.id)); + + const firstCaseNum = (page - 1) * casesPerPage + 1; + const lastCaseNum = page * casesPerPage; + const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`; + + const embed: EmbedOptions = { + author: { + name: title, + icon_url: mod instanceof User ? mod.avatarURL || mod.defaultAvatarURL : undefined, + }, + fields: [ + ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), + { + name: emptyEmbedValue, + value: trimLines(` + Use \`${prefix}case \` to see more information about an individual case + Use \`${prefix}cases \` to see a specific user's cases + `), + }, + ], + }; + + return { embed }; + }, + { + limitToUserId: msg.author.id, + }, + ); }, });