added messageEdit highlighting
diff --git a/package.json b/package.json
index 3591ee0..968af14 100644
--- a/package.json
+++ b/package.json
@@ -5,13 +5,12 @@
"@tensorflow/tfjs": "^3.18.0",
"@tensorflow/tfjs-node": "^3.18.0",
"@total-typescript/ts-reset": "^0.3.7",
- "@types/gm": "^1.25.0",
- "@types/node": "^18.14.6",
"@ungap/structured-clone": "^1.0.1",
"agenda": "^4.3.0",
"body-parser": "^1.20.0",
"canvas": "^2.11.0",
"clamscan": "^2.1.2",
+ "diff": "^5.1.0",
"discord.js": "^14.8.0",
"eslint": "^8.21.0",
"express": "^4.18.1",
@@ -83,6 +82,9 @@
"prettier-eslint": "^15.0.1",
"tsc-suppress": "^1.0.7",
"typescript": "^5.0.0",
- "yarn-audit-fix": "^9.3.9"
+ "yarn-audit-fix": "^9.3.9",
+ "@types/diff": "^5.0.3",
+ "@types/gm": "^1.25.0",
+ "@types/node": "^18.14.6"
}
}
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index 270da00..bc85353 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -1,6 +1,7 @@
import type { NucleusClient } from "../utils/client.js";
import type { Message, MessageReference } from "discord.js";
import type Discord from "discord.js";
+import * as diff from "diff";
export const event = "messageUpdate";
@@ -10,10 +11,9 @@
if (!newMessage.guild) return;
const { log, isLogging, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } =
client.logger;
-
const replyTo: MessageReference | null = newMessage.reference;
- let newContent = newMessage.cleanContent.replaceAll("`", "‘");
- let oldContent = oldMessage.cleanContent.replaceAll("`", "‘");
+ const newContent = newMessage.cleanContent.replaceAll("`", "‘");
+ const oldContent = oldMessage.cleanContent.replaceAll("`", "‘");
let attachmentJump = "";
const config = (await client.database.guilds.read(newMessage.guild.id)).logging.attachments.saved[
newMessage.channel.id + newMessage.id
@@ -62,46 +62,69 @@
if (!newMessage.editedTimestamp) {
return;
}
- if (newContent.length > 256) newContent = newContent.substring(0, 253) + "...";
- if (oldContent.length > 256) oldContent = oldContent.substring(0, 253) + "...";
- const data = {
- meta: {
- type: "messageUpdate",
- displayName: "Message Edited",
- calculateType: "messageUpdate",
- color: NucleusColors.yellow,
- emoji: "MESSAGE.EDIT",
- timestamp: newMessage.editedTimestamp
- },
- separate: {
- start:
- (oldContent
- ? `**Before:**\n\`\`\`\n${oldContent}\n\`\`\`\n`
- : "**Before:** *Message had no content*\n") +
- (newContent ? `**After:**\n\`\`\`\n${newContent}\n\`\`\`` : "**After:** *Message had no content*"),
- end: `[[Jump to message]](${newMessage.url})`
- },
- list: {
- messageId: entry(newMessage.id, `\`${newMessage.id}\``),
- sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
- sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel as Discord.GuildBasedChannel)),
- sent: entry(newMessage.createdTimestamp, renderDelta(newMessage.createdTimestamp)),
- edited: entry(newMessage.editedTimestamp, renderDelta(newMessage.editedTimestamp)),
- mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
- attachments: entry(
- renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size),
- renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size) + attachmentJump
- ),
- repliedTo: entry(
- replyTo ? replyTo.messageId! : null,
- replyTo
- ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${replyTo.messageId})`
- : "None"
- )
- },
- hidden: {
- guild: newMessage.guild.id
- }
- };
- await log(data);
+ const differences = diff.diffChars(oldContent, newContent);
+ console.log(differences);
+ let contentEdit = "";
+ if (differences.map((d) => (d.added || d.removed ? 1 : 0)).filter((f) => f === 1).length > 0) {
+ const green = "\x1B[36m";
+ const red = "\x1B[41m";
+ const skipped = "\x1B[40;33m";
+ const reset = "\x1B[0m";
+ const bold = "\x1B[1m";
+ const cutoff = 20;
+ differences.forEach((part) => {
+ if (!part.added && !part.removed && part.value.length > cutoff) {
+ contentEdit +=
+ reset +
+ part.value.slice(0, cutoff / 2) +
+ skipped +
+ `(${part.value.length - cutoff} more)` +
+ reset +
+ part.value.slice(-(cutoff / 2));
+ } else {
+ if (part.added || part.removed) {
+ part.value = part.value.replaceAll(" ", "▁");
+ }
+ contentEdit += (part.added ? green : part.removed ? red : reset) + part.value;
+ }
+ });
+ contentEdit = contentEdit.slice(0, 2000);
+ contentEdit += `\n\n${bold}Key:${reset} ${green}Added${reset} | ${red}Removed${reset} | ${skipped}Skipped${reset}`;
+ const data = {
+ meta: {
+ type: "messageUpdate",
+ displayName: "Message Edited",
+ calculateType: "messageUpdate",
+ color: NucleusColors.yellow,
+ emoji: "MESSAGE.EDIT",
+ timestamp: newMessage.editedTimestamp
+ },
+ separate: {
+ start: `\`\`\`ansi\n${contentEdit}\`\`\``,
+ end: `[[Jump to message]](${newMessage.url})`
+ },
+ list: {
+ messageId: entry(newMessage.id, `\`${newMessage.id}\``),
+ sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
+ sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel as Discord.GuildBasedChannel)),
+ sent: entry(newMessage.createdTimestamp, renderDelta(newMessage.createdTimestamp)),
+ edited: entry(newMessage.editedTimestamp, renderDelta(newMessage.editedTimestamp)),
+ mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
+ attachments: entry(
+ renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size),
+ renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size) + attachmentJump
+ ),
+ repliedTo: entry(
+ replyTo ? replyTo.messageId! : null,
+ replyTo
+ ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${replyTo.messageId})`
+ : "None"
+ )
+ },
+ hidden: {
+ guild: newMessage.guild.id
+ }
+ };
+ await log(data);
+ }
}
diff --git a/src/utils/commandRegistration/register.ts b/src/utils/commandRegistration/register.ts
index 5889d54..47f96ae 100644
--- a/src/utils/commandRegistration/register.ts
+++ b/src/utils/commandRegistration/register.ts
@@ -80,7 +80,13 @@
i++;
try {
console.log(`${last}─ ${colors.yellow}Loading event ${file.name}${colors.none}`);
- const event = await import(`../../../${config.eventsFolder}/${file.name}`);
+
+ let event;
+ try {
+ event = await import(`../../../${config.eventsFolder}/${file.name}`);
+ } catch (e) {
+ console.error(colors.red + e + colors.none);
+ }
client.on(event.event, event.callback.bind(null, client));
@@ -98,7 +104,7 @@
);
}
}
- console.log(`Loaded ${files.length - errors} events (${errors} failed)`);
+ console.log(`${errors ? colors.red : ""}Loaded ${files.length - errors} events (${errors} failed)${colors.none}`);
}
async function registerContextMenus() {
@@ -179,7 +185,11 @@
}
}
- console.log(`Loaded ${messageFiles.length + userFiles.length - errors} context menus (${errors} failed)`);
+ console.log(
+ `${errors ? colors.red : ""}Loaded ${
+ messageFiles.length + userFiles.length - errors
+ } context menus (${errors} failed) ${colors.none}`
+ );
return commands;
}
diff --git a/yarn.lock b/yarn.lock
index cedcc5c..14cfaef 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1258,6 +1258,11 @@
"@types/node" "*"
axios "^0.24.0"
+"@types/diff@^5.0.3":
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/@types/diff/-/diff-5.0.3.tgz#1f89e49ff83b5d200d78964fb896c68498ce1828"
+ integrity sha512-amrLbRqTU9bXMCc6uX0sWpxsQzRIo9z6MJPkH1pkez/qOxuqSZVuryJAWoBRq94CeG8JxY+VK4Le9HtjQR5T9A==
+
"@types/eslint@^8.4.2":
version "8.21.1"
resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.1.tgz"
@@ -2190,6 +2195,11 @@
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz"
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
+diff@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
+ integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
+
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"