Commit 7ee0d711 authored by Yashin's avatar Yashin
Browse files

Adding a member channels feature and working on course collections.

parent 83bf0819
......@@ -3,7 +3,7 @@ const {SlashCommandBuilder} = require('@discordjs/builders');
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.create_collection;
const commandLocale = locale.get(loc).slashCommands.add_collection;
return new SlashCommandBuilder()
.setName('add_collection')
.setDescription(commandLocale.description)
......
......@@ -13,6 +13,6 @@ module.exports = (loc) => {
.setRequired(true))
.addChannelOption((option) =>
option.setName('collection_category')
.setDescription(commandLocale.categoryCollectionDescription)
.setDescription(commandLocale.collectionCategoryDescription)
.setRequired(true));
}
\ No newline at end of file
const {SlashCommandBuilder} = require('@discordjs/builders');
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.add_member_channel;
return new SlashCommandBuilder()
.setName('add_member_channel')
.setDescription(commandLocale.description)
.addChannelOption((option) =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true));
}
\ No newline at end of file
const {SlashCommandBuilder} = require('@discordjs/builders');
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.assign_member_role;
return new SlashCommandBuilder()
.setName('assign_member_role')
.setDescription(commandLocale.description)
.addRoleOption((option) =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
.setRequired(true));
}
\ No newline at end of file
......@@ -13,7 +13,8 @@ module.exports = (loc) => {
.setRequired(true)
.addChoice(commandLocale.permissionChoices.roleMenus, 'role_menu')
.addChoice(commandLocale.permissionChoices.locale, 'locale')
.addChoice(commandLocale.permissionChoices.collection, 'collection'))
.addChoice(commandLocale.permissionChoices.collection, 'collection')
.addChoice(commandLocale.permissionChoices.memberManagement, 'memberManagement'))
.addRoleOption(option =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
......
const {SlashCommandBuilder} = require('@discordjs/builders');
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.bulk_add_course_to_collection;
return new SlashCommandBuilder()
.setName('bulk_add_course_to_collection')
.setDescription(commandLocale.description)
.addChannelOption((option) =>
option.setName('collection_category')
.setDescription(commandLocale.collectionCategoryDescription)
.setRequired(true));
}
\ No newline at end of file
const {SlashCommandBuilder} = require('@discordjs/builders');
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.delete_member_channel;
return new SlashCommandBuilder()
.setName('delete_member_channel')
.setDescription(commandLocale.description)
.addChannelOption((option) =>
option.setName('channel')
.setDescription(commandLocale.channelDescription)
.setRequired(true));
}
\ No newline at end of file
const {SlashCommandBuilder} = require('@discordjs/builders');
const locale = require('../util/locale');
module.exports = (loc) => {
const commandLocale = locale.get(loc).slashCommands.revoke_member_role;
return new SlashCommandBuilder()
.setName('revoke_member_role')
.setDescription(commandLocale.description)
.addRoleOption((option) =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
.setRequired(true));
}
\ No newline at end of file
......@@ -13,7 +13,8 @@ module.exports = (loc) => {
.setRequired(true)
.addChoice(commandLocale.permissionChoices.roleMenus, 'role_menu')
.addChoice(commandLocale.permissionChoices.locale, 'locale')
.addChoice(commandLocale.permissionChoices.collection, 'collection'))
.addChoice(commandLocale.permissionChoices.collection, 'collection')
.addChoice(commandLocale.permissionChoices.memberManagement, 'memberManagement'))
.addRoleOption(option =>
option.setName('role')
.setDescription(commandLocale.roleDescription)
......
const ServerConfig = require('../models/ServerConfig');
const CourseCollection = require('../models/CourseCollection');
const locales = require("../util/locale");
const {MessageActionRow, MessageSelectMenu} = require('discord.js');
const checkPerm = require("../util/perm");
async function newCollection(config, guild, name, menuChannelName) {
console.log(4);
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const messageLocale = locales.get(locale).misc.messageTemplates.collectionAllRoleMessage;
let collection = new CourseCollection();
collection.guildID = guild.id;
let category = await guild.channels.create(name, {type: 'GUILD_CATEGORY'});
collection.categoryID = category.id;
let roleChannel = await guild.channels.create(menuChannelName, {parent: category, type: "GUILD_TEXT"});
collection.roleChannelID = roleChannel.id;
const row = new MessageActionRow()
.addComponents(
new MessageSelectMenu()
.setCustomId('seeAllCourses')
.setPlaceholder(messageLocale.dropdown.placeholder)
.addOptions([
{
label: messageLocale.dropdown.enable,
value: 'enable'
},
{
label: messageLocale.dropdown.disable,
value: 'disable'
}
])
);
let selectAllMessage = await roleChannel.send({content: messageLocale.message, components: [row]});
collection.selectAllMessage = selectAllMessage.id.toString();
let seeAllRole = await guild.roles.create({name});
collection.selectAllRole = seeAllRole.id.toString();
collection.roleMessages = [];
collection.courses = [];
await category.permissionOverwrites.create(guild.roles.everyone, {
"VIEW_CHANNEL": false,
"CONNECT": false
})
await Promise.all(config.memberRoles.map(async (roleID) => {
await category.permissionOverwrites.create(roleID, {
"VIEW_CHANNEL": true,
"CONNECT": true
});
}));
config.memberChannels.push(category);
await Promise.all([config, collection].map(async (db) => await db.save()));
return 0;
}
async function delCollection(config, category, guild, deleteChannels) {
const collection = await CourseCollection.findOne({guildID: guild.id.toString(), categoryID: category.id.toString()});
if (collection == null) {
return 1;
}
await Promise.all(collection.courses.map(async (course) => {
await (await guild.roles.fetch(course.roleID)).delete();
}));
await (await guild.roles.fetch(course.selectAllRole)).delete();
config.memberChannels.splice(config.memberChannels.indexOf(collection.categoryID));
await (await guild.channels.fetch(course.roleChannelID)).delete();
if (deleteChannels) {
await Promise.all(category.children.map(async (categoryChannel) => {
await categoryChannel.delete();
}));
await category.delete();
}
return 0;
}
async function createCollection(interaction) {
const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
console.log(3);
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
......@@ -14,10 +87,40 @@ async function createCollection(interaction) {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
//TODO
const name = interaction.options.getString('name');
const roleChannelName = interaction.options.getString('role_channel_name');
await interaction.deferReply({ephemeral: true});
const code = await newCollection(config, interaction.guild, name, roleChannelName);
if (code === 0) {
await interaction.reply({content: functionLocale.collectionAdded, ephemeral: true});
} else {
await interaction.reply({content: functionLocale.collectionNotAdded, ephemeral: true});
}
}
async function deleteCollection(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.courseCollections;
if (!(await checkPerm(interaction.member, 'collection'))) {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
let category = interaction.options.getChannel('collection_category');
let deleteChannels = interaction.options.getBoolean('delete_channels');
await interaction.deferReply({ephemeral: true});
const code = await delCollection(config, category, interaction.guild, deleteChannels)
if (code === 0) {
await interaction.reply({content: functionLocale.collectionDeleted, ephemeral: true});
} else {
await interaction.reply({content: functionLocale.collectionNotDeleted, ephemeral: true});
}
}
async function addCourseToCollection(interaction) {
const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
......@@ -31,7 +134,7 @@ async function deleteCollection(interaction) {
//TODO
}
async function addCourseToCollection(interaction) {
async function bulkAddCourseToCollection(interaction) {
const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
let locale = 'en';
if (config != null) {
......@@ -74,14 +177,17 @@ async function editCollection(interaction) {
}
const slashCommandHandler = async (interaction) => {
if (interaction.commandName === 'create_collection') {
console.log(1);
if (interaction.commandName === 'add_collection') {
console.log(2);
await createCollection(interaction);
} else if (interaction.commandName === 'delete_collection') {
await deleteCollection(interaction);
} else if (interaction.commandName === 'add_course_to_collection') {
await addCourseToCollection(interaction);
} else if (interaction.commandName === 'bulk_add_course_to_collection') {
await bulkAddCourseToCollection(interaction);
} else if (interaction.commandName === 'delete_course_from_collection') {
await deleteCourseFromCollection(interaction);
} else if (interaction.commandName === 'edit_collection') {
......@@ -89,6 +195,10 @@ const slashCommandHandler = async (interaction) => {
}
}
const buttonHandler = async (interaction) => {
}
const selectMenuHandler = async (interaction) => {
if (interaction.customId === 'selectCourse') {
//TODO
......@@ -99,5 +209,6 @@ const selectMenuHandler = async (interaction) => {
module.exports = {
slashCommandHandler,
buttonHandler,
selectMenuHandler
}
\ No newline at end of file
const ServerConfig = require('../models/ServerConfig');
const locales = require('../util/locale');
const {Permissions} = require('discord.js');
const checkPerm = require('../util/perm');
async function assignMemberStatus(interaction) {
console.log(11);
let config = await ServerConfig.findOne({guildID: interaction.guild.id});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.memberManagement;
if (!(await checkPerm(interaction.member, 'memberManagement'))) {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
console.log(12);
const role = interaction.options.getRole('role');
if (config.memberRoles.some((memberRole) => memberRole === role.id.toString())) {
await interaction.reply({content: functionLocale.roleAlreadyMember, ephemeral: true});
return;
}
console.log(13);
config.memberRoles.push(role.id.toString());
await interaction.deferReply({ephemeral: true});
console.log(14);
await Promise.all(config.memberChannels.map(async (channelID) => {
console.log(15);
let channel = await interaction.guild.channels.fetch(channelID);
if (channel.isText()) {
await channel.permissionOverwrites.create(role, {
"VIEW_CHANNEL": true
});
} else {
await channel.permissionOverwrites.create(role, {
"VIEW_CHANNEL": true,
"CONNECT": true
});
}
}));
console.log(16);
await config.save();
console.log(17);
await interaction.editReply({content: functionLocale.roleAdded.replaceAll("$$ROLE$$", role.name), ephemeral: true});
}
async function revokeMemberStatus(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.memberManagement;
if (!(await checkPerm(interaction.member, 'memberManagement'))) {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
const role = interaction.options.getRole('role');
if (!config.memberRoles.some((memberRole) => memberRole === role.id.toString())) {
await interaction.reply({content: functionLocale.roleNotMember, ephemeral: true});
return;
}
config.memberRoles.splice(config.memberRoles.indexOf(role.id.toString()), 1);
await interaction.deferReply({ephemeral: true});
await Promise.all(config.memberChannels.map(async (channelID) => {
let channel = await interaction.guild.channels.fetch(channelID);
await channel.permissionOverwrites.delete(role);
}));
await config.save();
await interaction.editReply({content: functionLocale.roleRevoked.replaceAll("$$ROLE$$", role.name), ephemeral: true});
}
async function addMemberChannel(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.memberManagement;
if (!(await checkPerm(interaction.member, 'memberManagement'))) {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
let channel = await interaction.options.getChannel('channel');
if (config.memberChannels.some((memberChannel) => memberChannel === channel.id.toString())) {
await interaction.reply({content: functionLocale.channelAlreadyMember, ephemeral: true});
return;
}
config.memberChannels.push(channel.id.toString());
await interaction.deferReply({ephemeral: true});
if (channel.isText()) {
await channel.permissionOverwrites.create(interaction.guild.roles.everyone, {
"VIEW_CHANNEL": false
});
} else {
await channel.permissionOverwrites.create(interaction.guild.roles.everyone, {
"VIEW_CHANNEL": false,
"CONNECT": false
});
}
await Promise.all(config.memberRoles.map(async (roleID) => {
let role = await interaction.guild.roles.fetch(roleID);
if (channel.isText()) {
await channel.permissionOverwrites.create(role, {
"VIEW_CHANNEL": true
});
} else {
await channel.permissionOverwrites.create(role, {
"VIEW_CHANNEL": true,
"CONNECT": true
});
}
}));
await config.save();
await interaction.editReply({content: functionLocale.channelAdded.replaceAll("$$CHANNEL$$", channel.name), ephemeral: true});
}
async function deleteMemberChannel(interaction) {
let config = await ServerConfig.findOne({guildID: interaction.guild.id});
let locale = 'en';
if (config != null) {
locale = config.locale;
}
const functionLocale = locales.get(locale).components.memberManagement;
if (!(await checkPerm(interaction.member, 'memberManagement'))) {
await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
return;
}
let channel = interaction.options.getChannel('channel');
if (!config.memberChannels.some((memberChannel) => memberChannel === channel.id.toString())) {
await interaction.reply({content: functionLocale.channelNotMember, ephemeral: true});
return;
}
config.memberChannels.splice(config.memberChannels.indexOf(channel.id.toString()), 1);
await interaction.deferReply({ephemeral: true});
if (channel.isText()) {
await channel.permissionOverwrites.create(interaction.guild.roles.everyone, {
"VIEW_CHANNEL": null
});
} else {
await channel.permissionOverwrites.create(interaction.guild.roles.everyone, {
"VIEW_CHANNEL": null,
"CONNECT": null
});
}
await Promise.all(config.memberRoles.map(async (roleID) => {
await channel.permissionOverwrites.delete(roleID);
}));
await config.save();
await interaction.editReply({content: functionLocale.channelRemoved.replaceAll("$$CHANNEL$$", channel.name), ephemeral: true});
}
async function slashCommandHandler (interaction) {
if (interaction.commandName === 'assign_member_role') {
assignMemberStatus(interaction);
} else if (interaction.commandName === 'revoke_member_role') {
revokeMemberStatus(interaction);
} else if (interaction.commandName === 'add_member_channel') {
addMemberChannel(interaction);
} else if (interaction.commandName === 'delete_member_channel') {
deleteMemberChannel(interaction);
}
}
module.exports = {
slashCommandHandler
}
\ No newline at end of file
......@@ -25,6 +25,14 @@ async function assignPermission(interaction) {
if (!config.permissions.locale.includes(role.id.toString())) {
config.permissions.locale.push(role.id.toString());
}
} else if (perm === 'collection') {
if (!config.permissions.collection.includes(role.id.toString())) {
config.permissions.collection.push(role.id.toString());
}
} else if (perm === 'memberManagement') {
if (!config.permissions.memberManagement.includes(role.id.toString())) {
config.permissions.memberManagement.push(role.id.toString());
}
}
await config.save();
await interaction.reply({
......@@ -62,6 +70,14 @@ async function revokePermission(interaction) {
if (config.permissions.locale.includes(role.id.toString())) {
config.permissions.locale.splice(config.permissions.locale.indexOf(role.id.toString()), 1);
}
} else if (perm === 'collection') {
if (config.permissions.collection.includes(role.id.toString())) {
config.permissions.collection.splice(config.permissions.collection.indexOf(role.id.toString()), 1);
}
} else if (perm === 'memberManagement') {
if (config.permissions.memberManagement.includes(role.id.toString())) {
config.permissions.memberManagement.splice(config.permissions.memberManagement.indexOf(role.id.toString()), 1);
}
}
await config.save();
await interaction.reply({
......
......@@ -9,7 +9,8 @@
"permissionChoices": {
"roleMenus": "Rollenmenüs",
"locale": "Sprache wechseln",
"collection": "Veranstaltungssammlungen"
"collection": "Veranstaltungssammlungen",
"memberManagement": "Memberstatus von Rollen bearbeiten"
},
"roleDescription": "Rolle, der die Berechtigung hinzugefügt werden soll."
},
......@@ -19,7 +20,8 @@
"permissionChoices": {
"roleMenus": "Rollenmenüs",
"locale": "Sprache wechseln",
"collection": "Veranstaltungssammlungen"
"collection": "Veranstaltungssammlungen",
"memberManagement": "Memberstatus von Rollen bearbeiten"
},
"roleDescription": "Rolle, der die Berechtigung entzogen werden soll."
},
......@@ -86,6 +88,10 @@
"courseDescription": "Name der Veranstaltung.",
"collectionCategoryDescription": "Kategorie der Veranstaltungssammlung."
},
"bulk_add_course_to_collection": {
"description": "Mehrere Veranstaltungen einer Sammlung hinzufügen.",
"collectionCategoryDescription": "Kategorie der Veranstaltungssammlungranstaltung"
},
"delete_course_from_collection": {
"description": "Eine Veranstaltung aus der Sammlung entfernen.",
"courseChannelDescription": "Veranstaltung die entfernt werden soll.",
......@@ -95,6 +101,22 @@
"description": "Eine Veranstaltungssammlung bearbeiten.",
"collectionCategoryDescription": "Kategorie der Veranstaltungssammlung.",
"nameDescription": "Neuer Name der Veranstaltungsversammlung."
},
"assign_member_role": {
"description": "Einer Rolle Mitgliedsstatus geben.",
"roleDescription": "Rolle der Mitgliedsstatus gegeben werden soll."
},
"revoke_member_role": {
"description": "Einer Rolle Mitgliedsstatus entziehen.",
"roleDescription": "Rolle der Mitgliedsstatus entzogen werden soll."
},
"add_member_channel": {
"description": "Einen Kanal zu einem Mitgliederkanal machen.",
"channelDescription": "Kanal der zu einem Mitgliederkanal gemacht werden soll."
},
"delete_member_channel": {
"description": "Einen Kanal Mitgliedsstatus entziehen.",
"channelDescription": "Kanal dem der Mitgliedsstatus entzogen werden soll."
}
},
"components": {
......@@ -128,6 +150,24 @@
"roleRemoved": "Deine Rolle wurde entfernt."
},
"internalError": "Interner Fehler. Bitte kontaktier einen Admin."
},
"memberManagement": {
"accessDenied": "You are not authorized to do this.",
"roleAlreadyMember": "This role is already a member role.",
"roleAdded": "Role $$ROLE$$ has been turned into a member role and all member channels are updated.",
"roleNotMember": "This role is not a member role.",
"roleRevoked": "Role $$ROLE$$ has it's member status revoked.",
"channelAlreadyMember": "This channel is already a member channel.",
"channelAdded": "Channel $$CHANNEL$$ has been turned into a member channel.",
"channelNotMember": "This channel is not a member channel.",
"channelRemoved": "Channel $$CHANNEL$$ has it's member status removed."
},
"courseCollections": {
"accessDenied": "You are not authorized to do this.",
"collectionAdded": "The collection has been successfully added.",
"collectionNotAdded": "There was an error adding the collection.",
"collectionDeleted": "The collection has been successfully deleted.",
"collectionNotDeleted": "There was an error deleting the collection."
}
},
"misc": {
......@@ -135,6 +175,14 @@
"roleDropdown": {
"placeholder": "Wähle eine Rolle aus.",
"selectResetText": "Auswahl zurücksetzen."
},
"collectionAllRoleMessage": {
"message": "In this dropdown you can enable seeing all the courses.",
"dropdown": {
"placeholder": "Make a selection.",
"enable": "See all the courses.",
"disable": "See only selected courses."
}
}
}
}
......