mirror of https://github.com/clickscodes/nucleus
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
10 KiB
230 lines
10 KiB
import { LoadingEmbed } from "../utils/defaults.js";
|
|
import Discord, {
|
|
SlashCommandBuilder,
|
|
CommandInteraction,
|
|
ActionRowBuilder,
|
|
ButtonBuilder,
|
|
ButtonStyle,
|
|
StringSelectMenuOptionBuilder,
|
|
SelectMenuOptionBuilder,
|
|
StringSelectMenuBuilder
|
|
} from "discord.js";
|
|
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
|
|
import getEmojiByName from "../utils/getEmojiByName.js";
|
|
import createPageIndicator from "../utils/createPageIndicator.js";
|
|
import client from "../utils/client.js";
|
|
import confirmationMessage from "../utils/confirmationMessage.js";
|
|
import { Embed } from "../utils/defaults.js";
|
|
|
|
const command = new SlashCommandBuilder()
|
|
.setName("privacy")
|
|
.setDescription("Information and options for you and your server's settings");
|
|
|
|
const callback = async (interaction: CommandInteraction): Promise<void> => {
|
|
const pages = [
|
|
new Embed()
|
|
.setEmbed(
|
|
new EmojiEmbed()
|
|
.setTitle("Nucleus Privacy")
|
|
.setDescription(
|
|
"Nucleus is a bot that naturally needs to store data about servers.\n" +
|
|
"We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
|
|
"Any questions about Nucleus, how it works, and what data is stored can be asked in [our server](https://discord.gg/bPaNnxe)." +
|
|
"\n\n[[Privacy Policy]](https://clicksminuteper.github.io/policies/nucleus) | [[Terms of Service]](https://clicksminuteper.github.io/policies/nucleustos)"
|
|
)
|
|
.setEmoji("NUCLEUS.LOGO")
|
|
.setStatus("Danger")
|
|
)
|
|
.setTitle("Welcome")
|
|
.setDescription("General privacy information")
|
|
.setPageId(0),
|
|
new Embed()
|
|
.setEmbed(
|
|
new EmojiEmbed()
|
|
.setTitle("Scanners")
|
|
.setDescription(
|
|
"Nucleus scans content sent by users for malware and NSFW content\n" +
|
|
"Malware is detected using [ClamAV](https://clamav.net/), and the standard ClamAV database.\n" +
|
|
"NSFW detection is provided by [NsfwJS](https://nsfwjs.com/), with a model provided by [GantMan](https://github.com/GantMan/nsfw_model/releases/tag/1.1.0)\n\n" +
|
|
"All data is processed on our servers and is not processed by a 3rd party."
|
|
)
|
|
.setEmoji("NUCLEUS.LOGO")
|
|
.setStatus("Danger")
|
|
)
|
|
.setTitle("Scanners")
|
|
.setDescription("About Scanners")
|
|
.setPageId(1),
|
|
new Embed()
|
|
.setEmbed(
|
|
new EmojiEmbed()
|
|
.setTitle("Link scanning and Transcripts")
|
|
.setDescription(
|
|
"Transcripts allow you to store all messages sent in a channel. Transcripts are stored in our database along with the rest of the server's settings but is accessible by anyone with the link, so a leaked link could show all messages sent in the channel.\n"
|
|
)
|
|
.setEmoji("NUCLEUS.LOGO")
|
|
.setStatus("Danger")
|
|
)
|
|
.setTitle("Link scanning and Transcripts")
|
|
.setDescription("Information about how links and images are scanned, and transcripts are stored")
|
|
.setPageId(2)
|
|
].concat(
|
|
(interaction.member as Discord.GuildMember).id === interaction.guild!.ownerId
|
|
? [
|
|
new Embed()
|
|
.setEmbed(
|
|
new EmojiEmbed()
|
|
.setTitle("Options")
|
|
.setDescription("Below are buttons for controlling this servers privacy settings")
|
|
.setEmoji("NUCLEUS.LOGO")
|
|
.setStatus("Danger")
|
|
)
|
|
.setTitle("Options")
|
|
.setDescription("Options")
|
|
.setPageId(3)
|
|
.setComponents([
|
|
new ActionRowBuilder<ButtonBuilder>().addComponents([
|
|
new ButtonBuilder()
|
|
.setLabel("Clear all data")
|
|
.setCustomId("clear-all-data")
|
|
.setStyle(ButtonStyle.Danger)
|
|
])
|
|
])
|
|
]
|
|
: []
|
|
);
|
|
const m = await interaction.reply({
|
|
embeds: LoadingEmbed,
|
|
fetchReply: true,
|
|
ephemeral: true
|
|
});
|
|
let page = parseInt(
|
|
client.preloadPage[interaction.channel!.id] ? client.preloadPage[interaction.channel!.id]?.argument! : "0"
|
|
);
|
|
|
|
let selectPaneOpen = false;
|
|
let nextFooter = null;
|
|
|
|
let timedOut = false;
|
|
while (!timedOut) {
|
|
let selectPane: Discord.ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = [];
|
|
|
|
if (selectPaneOpen) {
|
|
const options: SelectMenuOptionBuilder[] = [];
|
|
pages.forEach((embed) => {
|
|
options.push(
|
|
new StringSelectMenuOptionBuilder({
|
|
label: embed.title,
|
|
value: embed.pageId.toString(),
|
|
description: embed.description || ""
|
|
})
|
|
);
|
|
});
|
|
selectPane = [
|
|
new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
|
|
new Discord.StringSelectMenuBuilder()
|
|
.addOptions(options)
|
|
.setCustomId("page")
|
|
.setMaxValues(1)
|
|
.setPlaceholder("Choose a page...")
|
|
])
|
|
];
|
|
}
|
|
const components: ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = selectPane.concat([
|
|
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
new ButtonBuilder()
|
|
.setCustomId("left")
|
|
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
|
|
.setStyle(ButtonStyle.Secondary)
|
|
.setDisabled(page === 0),
|
|
new ButtonBuilder()
|
|
.setCustomId("select")
|
|
.setEmoji(getEmojiByName("CONTROL.MENU", "id"))
|
|
.setStyle(selectPaneOpen ? ButtonStyle.Primary : ButtonStyle.Secondary)
|
|
.setDisabled(false),
|
|
new ButtonBuilder()
|
|
.setCustomId("right")
|
|
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
|
|
.setStyle(ButtonStyle.Secondary)
|
|
.setDisabled(page === pages.length - 1)
|
|
)
|
|
]);
|
|
const em = new Discord.EmbedBuilder(pages[page]!.embed);
|
|
em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
|
|
if (nextFooter) em.setFooter({ text: nextFooter });
|
|
await interaction.editReply({
|
|
embeds: [em],
|
|
components: components.concat(pages[page]?.componentsToSet ?? [])
|
|
});
|
|
let i;
|
|
try {
|
|
i = await m.awaitMessageComponent({
|
|
time: 300000,
|
|
filter: (i) => {
|
|
return (
|
|
i.user.id === interaction.user.id &&
|
|
i.channel!.id === interaction.channel!.id &&
|
|
i.message.id === m.id
|
|
);
|
|
}
|
|
});
|
|
} catch (e) {
|
|
timedOut = true;
|
|
continue;
|
|
}
|
|
nextFooter = null;
|
|
await i.deferUpdate();
|
|
if (i.customId === "left") {
|
|
if (page > 0) page--;
|
|
selectPaneOpen = false;
|
|
} else if (i.customId === "right") {
|
|
if (page < pages.length - 1) page++;
|
|
selectPaneOpen = false;
|
|
} else if (i.customId === "select") {
|
|
selectPaneOpen = !selectPaneOpen;
|
|
} else if (i.customId === "page" && i.isStringSelectMenu()) {
|
|
page = parseInt(i.values[0]!);
|
|
selectPaneOpen = false;
|
|
} else if (i.customId === "clear-all-data") {
|
|
const confirmation = await new confirmationMessage(interaction)
|
|
.setEmoji("CONTROL.BLOCKCROSS")
|
|
.setTitle("Clear All Data")
|
|
.setDescription(
|
|
"Are you sure you want to delete all data on this server? This includes your settings and all punishment histories.\n\n" +
|
|
"**This cannot be undone.**"
|
|
)
|
|
.setColor("Danger")
|
|
.send(true);
|
|
if (confirmation.cancelled) {
|
|
continue;
|
|
}
|
|
if (confirmation.success) {
|
|
await client.database.guilds.delete(interaction.guild!.id);
|
|
await client.database.history.delete(interaction.guild!.id);
|
|
await client.database.notes.delete(interaction.guild!.id);
|
|
await client.database.transcripts.deleteAll(interaction.guild!.id);
|
|
nextFooter = "All data cleared";
|
|
continue;
|
|
} else {
|
|
nextFooter = "No changes were made";
|
|
continue;
|
|
}
|
|
} else {
|
|
const em = new Discord.EmbedBuilder(pages[page]!.embed);
|
|
em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
|
|
em.setFooter({ text: "Message closed" });
|
|
await interaction.editReply({ embeds: [em], components: [] });
|
|
return;
|
|
}
|
|
}
|
|
const em = new Discord.EmbedBuilder(pages[page]!.embed);
|
|
em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
|
|
em.setFooter({ text: "Message timed out" });
|
|
await interaction.editReply({
|
|
embeds: [em],
|
|
components: []
|
|
});
|
|
};
|
|
|
|
export { command };
|
|
export { callback };
|