From 34369e692b634ea8a923b0916f886c427993df97 Mon Sep 17 00:00:00 2001 From: pineafan Date: Wed, 18 May 2022 16:52:37 +0100 Subject: [PATCH] added page indicators --- package-lock.json | 73 ++++++++++++++++++++++++++++++++ package.json | 4 +- src/automations/guide.ts | 23 +++++++--- src/automations/unscan.ts | 4 +- src/automations/verify.ts | 28 +++++++----- src/commands/user/about.ts | 7 ++- src/events/commandError.ts | 21 +++++++++ src/utils/createPageIndicator.ts | 22 ++++++++++ yarn.lock | 31 +++++++++++++- 9 files changed, 191 insertions(+), 22 deletions(-) create mode 100644 src/events/commandError.ts create mode 100644 src/utils/createPageIndicator.ts diff --git a/package-lock.json b/package-lock.json index 61e0f8f..0615b7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,8 @@ "humanize-duration": "^3.27.1", "jshaiku": "file:../haiku", "json-diff": "^0.7.1", + "node-tesseract": "^0.2.7", + "structured-clone": "^0.2.2", "tesseract.js": "^2.1.5", "typescript": "^4.5.5", "unscan": "^1.1.2" @@ -904,6 +906,39 @@ } } }, + "node_modules/node-tesseract": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/node-tesseract/-/node-tesseract-0.2.7.tgz", + "integrity": "sha1-yPAvuDUaQnByc1d4wFGYI/JgG4Q=", + "dependencies": { + "glob": "^5.0.10", + "node-uuid": "^1.4.1" + } + }, + "node_modules/node-tesseract/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "deprecated": "Use uuid module instead", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -1116,6 +1151,11 @@ "node": ">= 0.8" } }, + "node_modules/structured-clone": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/structured-clone/-/structured-clone-0.2.2.tgz", + "integrity": "sha1-rJK2vjGVimQ9sw8TNavGobAt/cI=" + }, "node_modules/tesseract.js": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-2.1.5.tgz", @@ -2004,6 +2044,34 @@ "whatwg-url": "^5.0.0" } }, + "node-tesseract": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/node-tesseract/-/node-tesseract-0.2.7.tgz", + "integrity": "sha1-yPAvuDUaQnByc1d4wFGYI/JgG4Q=", + "requires": { + "glob": "^5.0.10", + "node-uuid": "^1.4.1" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, "object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -2161,6 +2229,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "structured-clone": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/structured-clone/-/structured-clone-0.2.2.tgz", + "integrity": "sha1-rJK2vjGVimQ9sw8TNavGobAt/cI=" + }, "tesseract.js": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-2.1.5.tgz", diff --git a/package.json b/package.json index dd55984..7287aef 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "humanize-duration": "^3.27.1", "jshaiku": "file:../haiku", "json-diff": "^0.7.1", + "node-tesseract": "^0.2.7", + "structured-clone": "^0.2.2", "tesseract.js": "^2.1.5", "typescript": "^4.5.5", "unscan": "^1.1.2" @@ -35,6 +37,6 @@ "url": "https://github.com/ClicksMinutePer/Nucleus/issues" }, "homepage": "https://github.com/ClicksMinutePer/Nucleus#readme", - "private": true, + "private": false, "type": "module" } diff --git a/src/automations/guide.ts b/src/automations/guide.ts index e3cfa25..19a3337 100644 --- a/src/automations/guide.ts +++ b/src/automations/guide.ts @@ -1,6 +1,7 @@ import Discord, { MessageActionRow, MessageButton } from "discord.js"; import generateEmojiEmbed from "../utils/generateEmojiEmbed.js"; import getEmojiByName from "../utils/getEmojiByName.js"; +import createPageIndicator from "../utils/createPageIndicator.js"; export default async (guild, interaction?) => { let c = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel; @@ -39,7 +40,7 @@ export default async (guild, interaction?) => { `**${getEmojiByName("PUNISH.KICK.RED")} Kick:** The user is removed from the server.\n` + `**${getEmojiByName("PUNISH.SOFTBAN")} Softban:** Kicks the user, deleting their messages from every channel.\n` + `**${getEmojiByName("PUNISH.BAN.RED")} Ban:** The user is removed from the server, and they are unable to rejoin.\n` + - `**${getEmojiByName("PUNISH.BAN.GREEN")} Unban:** The user is able to rejoin the server.\n` + `**${getEmojiByName("PUNISH.BAN.GREEN")} Unban:** The user is able to rejoin the server.` ) .setEmoji("NUCLEUS.LOGO") .setStatus("Danger"), @@ -99,8 +100,10 @@ export default async (guild, interaction?) => { while (true) { if (interaction) { + let em = new Discord.MessageEmbed(pages[page]) + em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)); await interaction.editReply({ - embeds: [pages[page].setFooter({text: `Page ${page + 1}/${pages.length}`})], + embeds: [em], components: [new MessageActionRow().addComponents([ new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(page === 0), new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(page === pages.length - 1), @@ -130,7 +133,13 @@ export default async (guild, interaction?) => { if (page < pages.length - 1) page++; } else if (i.component.customId == "close") { if (interaction) { - interaction.delete(); + let em = new Discord.MessageEmbed(pages[page]) + em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message closed"); + interaction.editReply({embeds: [em], components: [new MessageActionRow().addComponents([ + new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true), + new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true), + new MessageButton().setCustomId("close").setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setStyle("DANGER").setDisabled(true) + ])], fetchReply: true}); } else { m.delete(); } @@ -141,8 +150,10 @@ export default async (guild, interaction?) => { } } if (interaction) { + let em = new Discord.MessageEmbed(pages[page]) + em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out"); await interaction.editReply({ - embeds: [pages[page].setFooter({text: `Page ${page + 1}/${pages.length} | Message timed out`})], + embeds: [em], components: [new MessageActionRow().addComponents([ new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true), new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true), @@ -150,8 +161,10 @@ export default async (guild, interaction?) => { ])] }); } else { + let em = new Discord.MessageEmbed(pages[page]) + em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out"); await m.edit({ - embeds: [pages[page].setFooter({text: `Page ${page + 1}/${pages.length} | Message timed out`})], + embeds: [em], components: [new MessageActionRow().addComponents([ new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true), new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true), diff --git a/src/automations/unscan.ts b/src/automations/unscan.ts index b5c5ffb..d3a2a18 100644 --- a/src/automations/unscan.ts +++ b/src/automations/unscan.ts @@ -1,5 +1,5 @@ import * as scan from '../utils/scanners.js' -import Tesseract from 'tesseract.js'; +import process from 'tesseract.js' export async function LinkCheck(message): Promise { let links = message.content.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi) ?? [] @@ -70,4 +70,4 @@ export function TestString(string, soft, strict): string { export async function TestImage(element): Promise { return ""; -} \ No newline at end of file +} diff --git a/src/automations/verify.ts b/src/automations/verify.ts index a60ed07..3d4e658 100644 --- a/src/automations/verify.ts +++ b/src/automations/verify.ts @@ -3,12 +3,18 @@ import generateEmojiEmbed from "../utils/generateEmojiEmbed.js"; import readConfig from "../utils/readConfig.js"; import fetch from "node-fetch"; import { TestString, NSFWCheck } from "../automations/unscan.js"; +import createPageIndicator from "../utils/createPageIndicator.js"; + +function step(i) { + return "\n\n" + createPageIndicator(5, i); +} export default async function(interaction) { // @ts-ignore let verify = interaction.client.verify await interaction.reply({embeds: [new generateEmojiEmbed() .setTitle("Loading") + .setDescription(step(-1)) .setStatus("Danger") .setEmoji("NUCLEUS.LOADING") ], ephemeral: true, fetchReply: true}); @@ -16,23 +22,23 @@ export default async function(interaction) { if ((interaction.member as GuildMember).roles.cache.has(config.verify.role)) { return await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`You already have the <@&${config.verify.role}> role`) + .setDescription(`You already have the <@&${config.verify.role}> role` + step(0)) .setStatus("Danger") .setEmoji("CONTROL.BLOCKCROSS") ]}); } await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Checking our servers are up`) + .setDescription(`Checking our servers are up` + step(0)) .setStatus("Warning") .setEmoji("NUCLEUS.LOADING") ]}); try { - let status = await fetch(`https://clicks.codes`).then(res => res.status); + let status = await fetch(`https://clicks.codes/`).then(res => res.status); if (status != 200) { return await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Our servers appear to be down, please try again later`) + .setDescription(`Our servers appear to be down, please try again later` + step(0)) .setStatus("Danger") .setEmoji("CONTROL.BLOCKCROSS") ]}); @@ -40,7 +46,7 @@ export default async function(interaction) { } catch { return await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Our servers appear to be down, please try again later`) + .setDescription(`Our servers appear to be down, please try again later` + step(0)) .setStatus("Danger") .setEmoji("CONTROL.BLOCKCROSS") ], components: [new Discord.MessageActionRow().addComponents([ @@ -57,14 +63,14 @@ export default async function(interaction) { if (config.filters.images.NSFW) { await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Checking your avatar is safe for work`) + .setDescription(`Checking your avatar is safe for work` + step(1)) .setStatus("Warning") .setEmoji("NUCLEUS.LOADING") ]}); if (await NSFWCheck((interaction.member as GuildMember).user.avatarURL({format: "png"}))) { return await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake`) + .setDescription(`Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(1)) .setStatus("Danger") .setEmoji("CONTROL.BLOCKCROSS") ]}); @@ -73,14 +79,14 @@ export default async function(interaction) { if (config.filters.wordFilter) { await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Checking your name is allowed`) + .setDescription(`Checking your name is allowed` + step(2)) .setStatus("Warning") .setEmoji("NUCLEUS.LOADING") ]}); if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) != "none") { return await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake`) + .setDescription(`Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(2)) .setStatus("Danger") .setEmoji("CONTROL.BLOCKCROSS") ]}); @@ -88,7 +94,7 @@ export default async function(interaction) { } await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`One moment...`) + .setDescription(`One moment...` + step(3)) .setStatus("Warning") .setEmoji("NUCLEUS.LOADING") ]}); @@ -120,7 +126,7 @@ export default async function(interaction) { } await interaction.editReply({embeds: [new generateEmojiEmbed() .setTitle("Verify") - .setDescription(`Looking good!\nClick the button below to get verified`) + .setDescription(`Looking good!\nClick the button below to get verified` + step(4)) .setStatus("Success") .setEmoji("MEMBER.JOIN") ], components: [new Discord.MessageActionRow().addComponents([new Discord.MessageButton() diff --git a/src/commands/user/about.ts b/src/commands/user/about.ts index b6e2aee..788054e 100644 --- a/src/commands/user/about.ts +++ b/src/commands/user/about.ts @@ -4,6 +4,7 @@ import { WrappedCheck } from "jshaiku"; import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js"; import getEmojiByName from "../../utils/getEmojiByName.js"; import generateKeyValueList from "../../utils/generateKeyValueList.js"; +import createPageIndicator from "../../utils/createPageIndicator.js"; const command = (builder: SlashCommandSubcommandBuilder) => builder @@ -120,7 +121,7 @@ const callback = async (interaction: CommandInteraction) => { "id": `\`${member.id}\``, "roles": `${member.roles.cache.size - 1}`, }) + "\n" + - (s.length > 0 ? s : "*None*") + (s.length > 0 ? s : "*None*") + "\n" ) .setThumbnail(await member.user.displayAvatarURL({dynamic: true})), new generateEmojiEmbed() @@ -139,8 +140,10 @@ const callback = async (interaction: CommandInteraction) => { m = await interaction.reply({embeds: [new generateEmojiEmbed().setTitle("Loading").setEmoji("NUCLEUS.LOADING").setStatus("Danger")], fetchReply: true, ephemeral: true}); let page = 0 while (true) { + let em = new Discord.MessageEmbed(embeds[page]) + em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page)); await interaction.editReply({ - embeds: [embeds[page].setFooter({text: `Page ${page + 1} of ${embeds.length}`})], + embeds: [em], components: [new MessageActionRow().addComponents([ new MessageButton() .setEmoji(getEmojiByName("CONTROL.LEFT", "id")) diff --git a/src/events/commandError.ts b/src/events/commandError.ts new file mode 100644 index 0000000..ba47426 --- /dev/null +++ b/src/events/commandError.ts @@ -0,0 +1,21 @@ +import generateEmojiEmbed from "../utils/generateEmojiEmbed.js"; + +export const event = 'commandError' + +export async function callback(client, interaction, error) { + if (interaction.replied || interaction.deferred) { + await interaction.followUp({embeds: [new generateEmojiEmbed() + .setTitle("Something went wrong") + .setDescription(error.message ?? error.toString()) + .setStatus("Danger") + .setEmoji("CONTROL.BLOCKCROSS") + ], ephemeral: true}) + } else { + await interaction.reply({embeds: [new generateEmojiEmbed() + .setTitle("Something went wrong") + .setDescription(error.message ?? error.toString()) + .setStatus("Danger") + .setEmoji("CONTROL.BLOCKCROSS") + ], ephemeral: true}) + } +} diff --git a/src/utils/createPageIndicator.ts b/src/utils/createPageIndicator.ts new file mode 100644 index 0000000..8e18e30 --- /dev/null +++ b/src/utils/createPageIndicator.ts @@ -0,0 +1,22 @@ +import getEmojiByName from "./getEmojiByName.js"; + +function pageIndicator(amount: number, selected: number, showDetails?: boolean | true) { + let out = ""; + + if (amount == 1) { + out += getEmojiByName("TRACKS.SINGLE." + (selected == 0 ? "ACTIVE" : "INACTIVE")); + } else { + for (let i = 0; i < amount; i++) { + out += getEmojiByName("TRACKS.HORIZONTAL." + + (i == 0 ? "LEFT" : (i == amount - 1 ? "RIGHT" : "MIDDLE")) + "." + + (i == selected ? "ACTIVE" : "INACTIVE") + ); + } + } + if (showDetails) { + out += " Page " + selected + " of " + amount; + } + return out; +} + +export default pageIndicator; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 715459c..4ae6519 100644 --- a/yarn.lock +++ b/yarn.lock @@ -423,6 +423,17 @@ "has" "^1.0.3" "has-symbols" "^1.0.1" +"glob@^5.0.10": + "integrity" "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=" + "resolved" "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz" + "version" "5.0.15" + dependencies: + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "2 || 3" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + "glob@^7.1.6": "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" @@ -609,7 +620,7 @@ "resolved" "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" "version" "1.6.0" -"minimatch@^3.0.4": +"minimatch@^3.0.4", "minimatch@2 || 3": "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" "version" "3.1.2" @@ -643,6 +654,19 @@ dependencies: "whatwg-url" "^5.0.0" +"node-tesseract@^0.2.7": + "integrity" "sha1-yPAvuDUaQnByc1d4wFGYI/JgG4Q=" + "resolved" "https://registry.npmjs.org/node-tesseract/-/node-tesseract-0.2.7.tgz" + "version" "0.2.7" + dependencies: + "glob" "^5.0.10" + "node-uuid" "^1.4.1" + +"node-uuid@^1.4.1": + "integrity" "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + "resolved" "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz" + "version" "1.4.8" + "object-inspect@^1.9.0": "integrity" "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" "resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz" @@ -785,6 +809,11 @@ "resolved" "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" "version" "2.0.1" +"structured-clone@^0.2.2": + "integrity" "sha1-rJK2vjGVimQ9sw8TNavGobAt/cI=" + "resolved" "https://registry.npmjs.org/structured-clone/-/structured-clone-0.2.2.tgz" + "version" "0.2.2" + "tesseract.js-core@^2.2.0": "integrity" "sha512-a8L+OJTbUipBsEDsJhDPlnLB0TY1MkTZqw5dqUwmiDSjUzwvU7HWLg/2+WDRulKUi4LE+7PnHlaBlW0k+V0U0w==" "resolved" "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-2.2.0.tgz"