blob: 8fb6b407374497207373c2c79c86f400c2da41f4 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
pineafan73a7c4a2022-07-24 10:38:04 +01002import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
pineafane23c4ec2022-07-27 21:56:27 +01003import { SelectMenuOption, SlashCommandBuilder } from "@discordjs/builders";
pineafan4f164f32022-02-26 22:07:12 +00004import { WrappedCheck } from "jshaiku";
pineafan73a7c4a2022-07-24 10:38:04 +01005import EmojiEmbed from "../utils/generateEmojiEmbed.js";
pineafane23c4ec2022-07-27 21:56:27 +01006import getEmojiByName from "../utils/getEmojiByName.js";
7import createPageIndicator from "../utils/createPageIndicator.js";
8import client from "../utils/client.js";
9import confirmationMessage from "../utils/confirmationMessage.js";
pineafan4f164f32022-02-26 22:07:12 +000010
11const command = new SlashCommandBuilder()
12 .setName("privacy")
pineafan63fc5e22022-08-04 22:04:10 +010013 .setDescription("Information and options for you and your server's settings");
pineafan4f164f32022-02-26 22:07:12 +000014
pineafane23c4ec2022-07-27 21:56:27 +010015class Embed {
16 embed: Discord.MessageEmbed;
17 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010018 description = "";
19 pageId = 0;
pineafane23c4ec2022-07-27 21:56:27 +010020 components?: MessageActionRow[] = [];
21 setEmbed(embed: Discord.MessageEmbed) { this.embed = embed; return this; }
22 setTitle(title: string) { this.title = title; return this; }
23 setDescription(description: string) { this.description = description; return this; }
24 setPageId(pageId: number) { this.pageId = pageId; return this; }
25 setComponents(components: MessageActionRow[]) { this.components = components; return this; }
26}
27
pineafanbd02b4a2022-08-05 22:01:38 +010028const callback = async (interaction: CommandInteraction): Promise<void> => {
pineafan63fc5e22022-08-04 22:04:10 +010029 const pages = [
pineafane23c4ec2022-07-27 21:56:27 +010030 new Embed()
31 .setEmbed(new EmojiEmbed()
32 .setTitle("Nucleus Privacy")
33 .setDescription(
34 "Nucleus is a bot that naturally needs to store data about servers.\n" +
35 "We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
36 "If you are a server administrator, you can view the options page in the dropdown under this message.\n\n" +
37 "Any questions about Nucleus, how it works and data stored can be asked in [our server](https://discord.gg/bPaNnxe)."
38 )
39 .setEmoji("NUCLEUS.LOGO")
40 .setStatus("Danger")
41 ).setTitle("Welcome").setDescription("General privacy information").setPageId(0),
42 new Embed()
43 .setEmbed(new EmojiEmbed()
44 .setTitle("Scanners")
45 .setDescription(
46 "Nucleus uses [unscan](https://unscan.co) to scan links, images and files for malware and other threats.\n" +
47 "This service's [privacy policy](https://unscan.co/policies) is public, and they \"do not store or sell your data.\""
48 )
49 .setEmoji("NUCLEUS.LOGO")
50 .setStatus("Danger")
51 ).setTitle("Scanners").setDescription("About Unscan").setPageId(1),
52 new Embed()
53 .setEmbed(new EmojiEmbed()
54 .setTitle("Link scanning and Transcripts")
55 .setDescription(
56 "**Facebook** - Facebook trackers include data such as your date of birth, and guess your age if not entered, your preferences, who you interact with and more.\n" +
57 "**AMP** - AMP is a technology that allows websites to be served by Google. This means Google can store and track data, and are pushing this to as many pages as possible.\n\n" +
58 "Transcripts allow you to store all messages sent in a channel. This could be an issue in some cases, as they are hosted on [Pastebin](https://pastebin.com), so a leaked link could show all messages sent in the channel.\n"
59 )
60 .setEmoji("NUCLEUS.LOGO")
61 .setStatus("Danger")
62 ).setTitle("Link scanning and Transcripts").setDescription("Regarding Facebook and AMP filter types, and ticket transcripts").setPageId(2)
63 ].concat((interaction.member as Discord.GuildMember).permissions.has("ADMINISTRATOR") ? [new Embed()
64 .setEmbed(new EmojiEmbed()
65 .setTitle("Options")
66 .setDescription(
67 "Below are buttons for controlling this servers privacy settings"
68 )
69 .setEmoji("NUCLEUS.LOGO")
70 .setStatus("Danger")
71 ).setTitle("Options").setDescription("Options").setPageId(3).setComponents([new MessageActionRow().addComponents([
72 new MessageButton().setLabel("Clear all data").setCustomId("clear-all-data").setStyle("DANGER")
73 ])])
74 ] : []);
pineafanbd02b4a2022-08-05 22:01:38 +010075 const m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true});
pineafane23c4ec2022-07-27 21:56:27 +010076 let page = 0;
77
78 let selectPaneOpen = false;
79 let nextFooter = null;
80
81 while (true) {
pineafan63fc5e22022-08-04 22:04:10 +010082 let selectPane = [];
pineafane23c4ec2022-07-27 21:56:27 +010083
84 if (selectPaneOpen) {
pineafan63fc5e22022-08-04 22:04:10 +010085 const options = [];
pineafane23c4ec2022-07-27 21:56:27 +010086 pages.forEach(embed => {
87 options.push(new SelectMenuOption({
88 label: embed.title,
89 value: embed.pageId.toString(),
pineafan63fc5e22022-08-04 22:04:10 +010090 description: embed.description || ""
91 }));
92 });
pineafane23c4ec2022-07-27 21:56:27 +010093 selectPane = [new MessageActionRow().addComponents([
94 new Discord.MessageSelectMenu()
95 .addOptions(options)
96 .setCustomId("page")
97 .setMaxValues(1)
98 .setPlaceholder("Choose a page...")
pineafan63fc5e22022-08-04 22:04:10 +010099 ])];
pineafane23c4ec2022-07-27 21:56:27 +0100100 }
pineafan63fc5e22022-08-04 22:04:10 +0100101 const components = selectPane.concat([new MessageActionRow().addComponents([
pineafane23c4ec2022-07-27 21:56:27 +0100102 new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(page === 0),
103 new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(false),
104 new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(page === pages.length - 1)
pineafan63fc5e22022-08-04 22:04:10 +0100105 ])]);
106 const em = new Discord.MessageEmbed(pages[page].embed);
pineafane23c4ec2022-07-27 21:56:27 +0100107 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
pineafan63fc5e22022-08-04 22:04:10 +0100108 em.setFooter({text: nextFooter ?? ""});
pineafane23c4ec2022-07-27 21:56:27 +0100109 await interaction.editReply({
110 embeds: [em],
111 components: components.concat(pages[page].components)
112 });
pineafan63fc5e22022-08-04 22:04:10 +0100113 let i;
pineafane23c4ec2022-07-27 21:56:27 +0100114 try {
115 i = await m.awaitMessageComponent({time: 300000});
pineafan63fc5e22022-08-04 22:04:10 +0100116 } catch(e) { break; }
117 nextFooter = null;
118 i.deferUpdate();
pineafane23c4ec2022-07-27 21:56:27 +0100119 if (i.component.customId === "left") {
120 if (page > 0) page--;
121 selectPaneOpen = false;
122 } else if (i.component.customId === "right") {
123 if (page < pages.length - 1) page++;
124 selectPaneOpen = false;
125 } else if (i.component.customId === "select") {
126 selectPaneOpen = !selectPaneOpen;
127 } else if (i.component.customId === "page") {
128 page = parseInt(i.values[0]);
129 selectPaneOpen = false;
130 } else if (i.component.customId === "clear-all-data") {
pineafan63fc5e22022-08-04 22:04:10 +0100131 const confirmation = await new confirmationMessage(interaction)
pineafane23c4ec2022-07-27 21:56:27 +0100132 .setEmoji("CONTROL.BLOCKCROSS")
133 .setTitle("Clear All Data")
134 .setDescription(
pineafan63fc5e22022-08-04 22:04:10 +0100135 "Are you sure you want to delete all data on this server? This includes your settings and all punishment histories.\n\n" +
pineafane23c4ec2022-07-27 21:56:27 +0100136 "**This cannot be undone.**"
137 )
138 .setColor("Danger")
pineafan63fc5e22022-08-04 22:04:10 +0100139 .send(true);
pineafane23c4ec2022-07-27 21:56:27 +0100140 if (confirmation.cancelled) { break; }
141 if (confirmation.success) {
142 client.database.guilds.delete(interaction.guild.id);
143 client.database.history.delete(interaction.guild.id);
144 nextFooter = "All data cleared";
145 continue;
146 } else {
147 nextFooter = "No changes were made";
148 continue;
149 }
150 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100151 const em = new Discord.MessageEmbed(pages[page].embed);
152 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
pineafane23c4ec2022-07-27 21:56:27 +0100153 em.setFooter({text: "Message closed"});
154 interaction.editReply({embeds: [em], components: []});
pineafan63fc5e22022-08-04 22:04:10 +0100155 return;
pineafane23c4ec2022-07-27 21:56:27 +0100156 }
pineafan73a7c4a2022-07-24 10:38:04 +0100157 }
pineafan63fc5e22022-08-04 22:04:10 +0100158 const em = new Discord.MessageEmbed(pages[page].embed);
159 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
pineafane23c4ec2022-07-27 21:56:27 +0100160 em.setFooter({text: "Message timed out"});
161 await interaction.editReply({
162 embeds: [em],
163 components: []
164 });
pineafan63fc5e22022-08-04 22:04:10 +0100165};
pineafan4f164f32022-02-26 22:07:12 +0000166
pineafanbd02b4a2022-08-05 22:01:38 +0100167const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
pineafan4f164f32022-02-26 22:07:12 +0000168 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100169};
pineafan4f164f32022-02-26 22:07:12 +0000170
171export { command };
172export { callback };
173export { check };