Hyperlinks in ticket descriptions

This commit is contained in:
Tarrgon
2025-06-04 07:15:52 -04:00
parent 4aa3b8e0ca
commit 6fc76fd25d
4 changed files with 110 additions and 18 deletions
+94 -3
View File
@@ -2,9 +2,72 @@ import { createClient } from '@redis/client';
import { Database } from './Database';
import { config } from '../config';
import { APIEmbedField, Client, EmbedAuthorOptions, EmbedBuilder, SendableChannels, TextBasedChannel } from 'discord.js';
import { humanizeCapitalization } from '../utils/string-utils';
import { blipIDRegex, commentIDRegex, forumTopicIDRegex, humanizeCapitalization, poolIDRegex, postIDRegex, shouldAlert, recordIDRegex, searchLinkRegex, setIDRegex, takedownIDRegex, ticketIDRegex, userIDRegex, wikiLinkRegex } from '../utils';
import { BanUpdate, Ticket, TicketPhrase, TicketUpdate } from '../types';
import { shouldAlert } from '../utils/ticket-utils';
// TODO: Condense this and the message event handler regex array.
const linkReplacers = [
{
regex: blipIDRegex,
replacement: '/blips/{match}',
encodeURI: false
},
{
regex: commentIDRegex,
replacement: '/comments/{match}',
encodeURI: false
},
{
regex: forumTopicIDRegex,
replacement: '/forum_topics/{match}',
encodeURI: false
},
{
regex: poolIDRegex,
replacement: '/pools/{match}',
encodeURI: false
},
{
regex: postIDRegex,
replacement: '/posts/{match}',
encodeURI: false
},
{
regex: recordIDRegex,
replacement: '/user_feedbacks/{match}',
encodeURI: false
},
{
regex: searchLinkRegex,
replacement: '/posts?tags={match}',
encodeURI: true
},
{
regex: setIDRegex,
replacement: '/post_sets/{match}',
encodeURI: false
},
{
regex: takedownIDRegex,
replacement: '/takedowns/{match}',
encodeURI: false
},
{
regex: ticketIDRegex,
replacement: '/tickets/{match}',
encodeURI: false
},
{
regex: userIDRegex,
replacement: '/users/{match}',
encodeURI: false
},
{
regex: wikiLinkRegex,
replacement: '/wiki_pages/{match}',
encodeURI: true
}
];
const MAX_DESCRIPTION_LENGTH = 500;
@@ -119,8 +182,36 @@ function getURL(ticket: Ticket): string {
return `${config.E621_BASE_URL}/tickets/${ticket.id}`;
}
function getLinks(input: string, limit: number = Number.MAX_SAFE_INTEGER): string {
const length = input.length;
const replacedIndexes: { start: number, end: number }[] = [];
for (const replacer of linkReplacers) {
input = input.replaceAll(replacer.regex, (match, group1) => {
const replaced = `[${match}](${config.E621_BASE_URL}${(replacer.replacement).replace('{match}', replacer.encodeURI ? encodeURIComponent(group1) : group1)})`;
const start = input.indexOf(match);
replacedIndexes.push({ start, end: start + replaced.length });
return replaced;
});
}
if (length > limit) {
for (const replacedIndex of replacedIndexes) {
if (replacedIndex.start < limit && replacedIndex.end >= limit) {
return input.substring(0, replacedIndex.end) + '...';
}
}
return input.substring(0, limit) + '...';
}
return input;
}
function getDescription(ticket: Ticket): string {
return ticket.reason.length <= MAX_DESCRIPTION_LENGTH ? ticket.reason : ticket.reason.substring(0, MAX_DESCRIPTION_LENGTH);
return ticket.reason.length <= MAX_DESCRIPTION_LENGTH ? getLinks(ticket.reason) : getLinks(ticket.reason, MAX_DESCRIPTION_LENGTH);
}
function getAuthor(ticket: Ticket): EmbedAuthorOptions {