refactor(twilight): better embed

This commit is contained in:
AlphaNecron 2021-10-09 12:52:36 +07:00
parent d4d69bf6ae
commit 2560ddcdfa
14 changed files with 140 additions and 76 deletions

View File

@ -1,6 +1,6 @@
{
"name": "void",
"version": "0.4.1",
"version": "0.5.0",
"private": true,
"engines": {
"node": ">=14"

View File

@ -10,8 +10,9 @@ import mimetypes from '../src/lib/mimetypes';
import validate from '../src/lib/validateConfig';
import readConfig from '../src/lib/configReader';
import start from '../twilight/twilight';
import { name, version } from '../package.json';
info('SERVER', 'Starting Void server');
info('SERVER', `Starting ${name}@${version}`);
const dev = process.env.NODE_ENV === 'development';

View File

@ -14,7 +14,7 @@ export default function URLs() {
const [busy, setBusy] = useState(false);
const toast = useToast();
const schema = yup.object({
destination: yup.string().matches(/((?:(?:http?|ftp)[s]*:\/\/)?[a-z0-9-%\/\&=?\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?)/gi).min(3).required(),
destination: yup.string().matches(/((?:(?:http?|ftp)[s]*:\/\/)?[a-z0-9-%\/\&=?\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?)/i).min(3).required(),
vanity: yup.string(),
urlPassword: yup.string()
});

View File

@ -204,7 +204,7 @@ export const getServerSideProps: GetServerSideProps = async context => {
const ext = file.fileName.split('.').pop();
const type = file.mimetype.split('/').shift();
const src = `${config.uploader.raw_route}/${file.fileName}`;
const url = `http${config.core.secure ? 's' : ''}://${context.req.headers.host}/${config.uploader.raw_route}`;
const url = `http${config.core.secure ? 's' : ''}://${context.req.headers.host}${config.uploader.raw_route}`;
const isCode = Object.keys(languages).some(name => languages[name] === ext);
const replace = size => {
const time = new Date(file.uploadedAt);

View File

@ -1,5 +1,7 @@
import { Message, MessageEmbed } from 'discord.js';
import prisma from '../../src/lib/prisma';
import { pagify } from '../utils/utils';
import config from '../../src/lib/config';
const files = {
command: 'files',
@ -7,49 +9,27 @@ const files = {
syntax: '{PREFIX}files',
scopes: ['dm', 'text'],
execute: async (msg: Message) => {
const all = await prisma.file.findMany({
const all = (await prisma.file.findMany({
select: {
id: true,
fileName: true,
origFileName: true,
mimetype: true,
uploadedAt: true,
userId: true
slug: true
}
});
const pages: MessageEmbed[] = [];
for (let i = 0; i < all.length; i += 4) {
const files = all.slice(i, i + 4);
const embed = new MessageEmbed()
.setTitle('Files')
.setColor('#B794F4')
.setFooter(`Page ${i / 4 + 1}/${Math.ceil(all.length / 4)} | Total: ${all.length}`);
files.forEach(file =>
embed.addField(file.fileName,
`ID: ${file.id}
Original file name: ${file.origFileName}
Mimetype: ${file.mimetype}
Uploaded at: ${new Date(file.uploadedAt).toLocaleString()}`)
);
pages.push(embed);
}
// https://stackoverflow.com/a/60693028
msg.channel.send(pages[0]).then(message => {
if (pages.length <= 1) return;
message.react('➡️');
const collector = message.createReactionCollector(
(reaction, user) => ['⬅️', '➡️'].includes(reaction.emoji.name) && user.id === msg.author.id,
{ time: 60000 }
);
let i = 0;
collector.on('collect', async reaction => {
await message.reactions.removeAll();
reaction.emoji.name === '⬅️' ? i -= 1 : i += 1;
await message.edit(pages[i]);
if (i !== 0) await message.react('⬅️');
if (i + 1 < pages.length) await message.react('➡️');
});
});
}) as any[]).map(file => ({
name: file.fileName,
value:
`
ID: ${file.id}
Original file name: ${file.origFileName}
Mimetype: ${file.mimetype}
Uploaded at: ${new Date(file.uploadedAt).toLocaleString()}
[View](http${config.core.secure ? 's' : ''}://${config.bot.hostname}/${file.slug})
`
}));
pagify('Files', all, msg)();
}
};

View File

@ -1,6 +1,7 @@
import { Message, MessageEmbed } from 'discord.js';
import config from '../../src/lib/config';
import { commands } from '../twilight';
import { defaultEmbed } from '../utils/utils';
const help = {
command: 'help',
@ -8,7 +9,7 @@ const help = {
syntax: '{PREFIX}help',
scopes: ['dm', 'text'],
execute: async (msg: Message) => {
const embed = new MessageEmbed().setTimestamp().setTitle('Help').setColor('#B794F4');
const embed = defaultEmbed().setTitle('Help');
commands.forEach(command =>
embed.addField(command.syntax.replace(/{PREFIX}/g, config.bot.prefix),
command.description));

View File

@ -13,7 +13,7 @@ const shorten = {
execute: async (msg: Message, args: string[]) => {
const [dest, vanity] = args;
if (!dest) return msg.channel.send('Please specify a URL to shorten');
if (!dest.includes('.')) return msg.channel.send('Please specify a valid URL.');
if (!dest.match(/((?:(?:http?|ftp)[s]*:\/\/)?[a-z0-9-%\/\&=?\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?)/i)) return msg.channel.send('Please specify a valid URL.');
if (vanity) {
const existing = await prisma.url.findFirst({
where: {

View File

@ -3,6 +3,7 @@ import { join } from 'path';
import config from '../../src/lib/config';
import prisma from '../../src/lib/prisma';
import { bytesToHr, sizeOfDir } from '../../src/lib/utils';
import { defaultEmbed } from '../utils/utils';
const stats = {
command: 'stats',
@ -20,14 +21,14 @@ const stats = {
views: true
}
});
await msg.channel.send(new MessageEmbed().addFields(
await msg.channel.send(defaultEmbed().setTitle('Stats').addFields(
{ name: 'Size', value: bytesToHr(size) },
{ name: 'Average size', value: bytesToHr(isNaN(size / fcount) ? 0 : size / fcount) },
{ name: 'File count', value: fcount },
{ name: 'URL count', value: ucount },
{ name: 'User count', value: userCount },
{ name: 'View count', value: viewCount[0]?._sum?.views ?? 0 }
).setAuthor('Server stats').setTimestamp().setColor('#B794F4'));
));
}
};

35
twilight/commands/urls.ts Normal file
View File

@ -0,0 +1,35 @@
import { Message, MessageEmbed } from 'discord.js';
import prisma from '../../src/lib/prisma';
import { pagify } from '../utils/utils';
import config from '../../src/lib/config';
const urls = {
command: 'urls',
description: 'View urls',
syntax: '{PREFIX}urls',
scopes: ['dm', 'text'],
execute: async (msg: Message) => {
const all = (await prisma.url.findMany({
select: {
id: true,
short: true,
destination: true,
createdAt: true,
password: true
}
}) as any[]).map(url => ({
name: url.short,
value:
`
ID: ${url.id}
Destination: ${url.destination}
Created at: ${new Date(url.createdAt).toLocaleString()}
Has password: ${url.password ? 'yes' : 'no'}
[Go](http${config.core.secure ? 's' : ''}://${config.bot.hostname}${config.shortener.route}/${url.short})
`
}));
pagify('URLs', all, msg)();
}
};
export default urls;

View File

@ -2,6 +2,7 @@ import { Message, MessageEmbed } from 'discord.js';
import { info } from '../../src/lib/logger';
import prisma from '../../src/lib/prisma';
import { generateToken, hashPassword } from '../../src/lib/utils';
import { defaultEmbed } from '../utils/utils';
const user = {
command: 'user',
@ -32,10 +33,7 @@ const user = {
password: hashed,
}
});
const embed = new MessageEmbed()
.setTitle('Created a new user')
.setColor('#B794F4')
.setFooter(`By: ${msg.author.username}#${msg.author.discriminator}`)
const embed = defaultEmbed()
.addFields(
{ name: 'id', value: newUser.id },
{ name: 'Username', value: newUser.username }
@ -56,14 +54,13 @@ const user = {
});
}
catch (err) { return msg.channel.send(`Failed to delete user with id: ${id}\nError: ${err.meta?.cause}`); }
const embed = new MessageEmbed()
.setTitle('Deleted user')
.setColor('#B794F4')
.setFooter(`By: ${msg.author.username}#${msg.author.discriminator}`)
.addField('Username', userToDelete.username, true);
global.logger.log(embed);
msg.channel.send(embed);
info('USER',`${msg.author.tag} created a user: ${userToDelete.username}`);
global.logger.log(`User deleted: ${userToDelete.username} (${userToDelete.id})`);
msg.channel.send(defaultEmbed()
.setTitle('User deleted')
.setFooter(`By: ${msg.author.tag}`)
.setFooter(`By: ${msg.author.tag}`)
.addField('Username', userToDelete.username, true));
info('USER',`${msg.author.tag} deleted a user: ${userToDelete.username} (${userToDelete.id})`);
}
}
}

View File

@ -1,28 +1,29 @@
import { Message, MessageEmbed } from 'discord.js';
import prisma from '../../src/lib/prisma';
import { pagify } from '../utils/utils';
import config from '../../src/lib/config';
const users = {
command: 'users',
description: 'View user stats',
description: 'View users',
syntax: '{PREFIX}users',
scopes: ['dm', 'text'],
execute: async (msg: Message) => {
const all = await prisma.user.findMany({
const all = (await prisma.user.findMany({
select: {
username: true,
id: true,
username: true,
isAdmin: true
}
});
const embed = new MessageEmbed()
.setTimestamp()
.setTitle('Users')
.setColor('#B794F4')
.setFooter(`Total: ${all.length}`);
all.forEach(user => {
embed.addField(`${user.username}`, `ID: ${user.id}\nAdmin: ${user.isAdmin ? 'yes' : 'no'}`);
});
await msg.channel.send(embed);
}) as any[]).map(user => ({
name: user.username,
value:
`
ID: ${user.id}
Admin: ${user.isAdmin ? 'yes' : 'no'}
`
}));
pagify('Users', all, msg)();
}
};

View File

@ -7,10 +7,13 @@ let config;
const client = new Discord.Client();
export let avatarUrl = '';
export const commands = [];
client.once('ready', () => {
info('BOT', 'Twilight is ready');
avatarUrl = client.user.displayAvatarURL();
global.logger = new Logger(client);
global.logger.log('Twilight is ready');
readdir(`${__dirname}/commands`, (err, files) => {

View File

@ -1,6 +1,8 @@
import { Client, MessageEmbed, TextChannel } from 'discord.js';
import config from '../../src/lib/config';
import { name, version } from '../../package.json';
import { avatarUrl } from '../twilight';
import { defaultEmbed } from '../utils/utils';
export class Logger {
channel: TextChannel;
@ -12,13 +14,16 @@ export class Logger {
this.channel = client.channels.cache.find(c => c.type === 'text' && c.id === config.bot.log_channel) as TextChannel;
}
log(msg: MessageEmbed | string) {
logFile(file: any, user: any) {
}
logUrl(url: any, user: any) {
}
log(msg: string) {
if (!this.channel) return;
this.channel.send(typeof msg === 'string' ? new MessageEmbed()
.setTitle(msg)
.setColor('#B794F4')
.setTimestamp()
.setFooter(`${name}@${version}`, this.client.user.displayAvatarURL())
.setThumbnail(this.client.user.displayAvatarURL()) : msg);
this.channel.send(defaultEmbed().setTitle(msg))
}
}

40
twilight/utils/utils.ts Normal file
View File

@ -0,0 +1,40 @@
import { Message, MessageEmbed } from 'discord.js';
import { name, version } from '../../package.json';
import config from '../../src/lib/config';
import { avatarUrl } from '../twilight';
export function pagify(title: string, items: any[], msg: Message): Function {
const pages: MessageEmbed[] = [];
for (let i = 0; i < items.length; i += 6) {
const sliced = items.slice(i, i + 6);
const embed = defaultEmbed()
.setTitle(title)
.setFooter(`${name}@${version} | Page ${i / 6 + 1}/${Math.ceil(items.length / 6)} | Total: ${items.length}`, `http${config.core.secure ? 's' : ''}://${config.bot.hostname}/logo.png`);
sliced.forEach(item =>
embed.addField(item.name, item.value)
);
pages.push(embed);
}
// https://stackoverflow.com/a/60693028
return () => {
msg.channel.send(pages[0]).then(message => {
if (pages.length <= 1) return;
message.react('➡️');
const collector = message.createReactionCollector(
(reaction, user) => ['⬅️', '➡️'].includes(reaction.emoji.name) && user.id === msg.author.id,
{ time: 60000 }
);
let i = 0;
collector.on('collect', async reaction => {
await message.reactions.removeAll();
reaction.emoji.name === '⬅️' ? i -= 1 : i += 1;
await message.edit(pages[i]);
if (i !== 0) await message.react('⬅️');
if (i + 1 < pages.length) await message.react('➡️');
});
});
};
}
export const defaultEmbed = () => new MessageEmbed().setColor('#B794F4')
.setAuthor('Twilight', avatarUrl).setTimestamp().setFooter(`${name}@${version}`, `http${config.core.secure ? 's' : ''}://${config.bot.hostname}/logo.png`);