3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-15 05:41:51 +00:00

some more patches thanks to ruby

Signed-off-by: GitHub <noreply@github.com>
This commit is contained in:
Tiago R 2023-11-26 14:53:54 +00:00
parent ba4a2b45b8
commit 10bb0b67bc
18 changed files with 69 additions and 52 deletions

View file

@ -1,6 +1,6 @@
import { User, escapeBold, type Snowflake } from "discord.js"; import { User, escapeBold, type Snowflake } from "discord.js";
import * as t from "io-ts"; import * as t from "io-ts";
import { tNullable } from "../../../utils"; import { renderUsername, tNullable } from "../../../utils";
import { automodTrigger } from "../helpers"; import { automodTrigger } from "../helpers";
interface ThreadArchiveResult { interface ThreadArchiveResult {
@ -48,7 +48,7 @@ export const ThreadArchiveTrigger = automodTrigger<ThreadArchiveResult>()({
const parentName = matchResult.extra.matchedThreadParentName; const parentName = matchResult.extra.matchedThreadParentName;
const base = `Thread **#${threadName}** (\`${threadId}\`) has been archived in the **#${parentName}** (\`${parentId}\`) channel`; const base = `Thread **#${threadName}** (\`${threadId}\`) has been archived in the **#${parentName}** (\`${parentId}\`) channel`;
if (threadOwner) { if (threadOwner) {
return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; return `${base} by **${escapeBold(renderUsername(threadOwner.tag))}** (\`${threadOwner.id}\`)`;
} }
return base; return base;
}, },

View file

@ -1,5 +1,6 @@
import { User, escapeBold, type Snowflake } from "discord.js"; import { User, escapeBold, type Snowflake } from "discord.js";
import * as t from "io-ts"; import * as t from "io-ts";
import { renderUsername } from "../../../utils.js";
import { automodTrigger } from "../helpers"; import { automodTrigger } from "../helpers";
interface ThreadCreateResult { interface ThreadCreateResult {
@ -40,7 +41,7 @@ export const ThreadCreateTrigger = automodTrigger<ThreadCreateResult>()({
const parentName = matchResult.extra.matchedThreadParentName; const parentName = matchResult.extra.matchedThreadParentName;
const base = `Thread **#${threadName}** (\`${threadId}\`) has been created in the **#${parentName}** (\`${parentId}\`) channel`; const base = `Thread **#${threadName}** (\`${threadId}\`) has been created in the **#${parentName}** (\`${parentId}\`) channel`;
if (threadOwner) { if (threadOwner) {
return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; return `${base} by **${escapeBold(renderUsername(threadOwner.tag))}** (\`${threadOwner.id}\`)`;
} }
return base; return base;
}, },

View file

@ -1,5 +1,6 @@
import { User, escapeBold, type Snowflake } from "discord.js"; import { User, escapeBold, type Snowflake } from "discord.js";
import * as t from "io-ts"; import * as t from "io-ts";
import { renderUsername } from "../../../utils.js";
import { automodTrigger } from "../helpers"; import { automodTrigger } from "../helpers";
interface ThreadDeleteResult { interface ThreadDeleteResult {
@ -40,7 +41,7 @@ export const ThreadDeleteTrigger = automodTrigger<ThreadDeleteResult>()({
const parentName = matchResult.extra.matchedThreadParentName; const parentName = matchResult.extra.matchedThreadParentName;
if (threadOwner) { if (threadOwner) {
return `Thread **#${threadName ?? "Unknown"}** (\`${threadId}\`) created by **${escapeBold( return `Thread **#${threadName ?? "Unknown"}** (\`${threadId}\`) created by **${escapeBold(
threadOwner.tag, renderUsername(threadOwner.tag),
)}** (\`${threadOwner.id}\`) in the **#${parentName}** (\`${parentId}\`) channel has been deleted`; )}** (\`${threadOwner.id}\`) in the **#${parentName}** (\`${parentId}\`) channel has been deleted`;
} }
return `Thread **#${ return `Thread **#${

View file

@ -1,6 +1,6 @@
import { User, escapeBold, type Snowflake } from "discord.js"; import { User, escapeBold, type Snowflake } from "discord.js";
import * as t from "io-ts"; import * as t from "io-ts";
import { tNullable } from "../../../utils"; import { renderUsername, tNullable } from "../../../utils";
import { automodTrigger } from "../helpers"; import { automodTrigger } from "../helpers";
interface ThreadUnarchiveResult { interface ThreadUnarchiveResult {
@ -48,7 +48,7 @@ export const ThreadUnarchiveTrigger = automodTrigger<ThreadUnarchiveResult>()({
const parentName = matchResult.extra.matchedThreadParentName; const parentName = matchResult.extra.matchedThreadParentName;
const base = `Thread **#${threadName}** (\`${threadId}\`) has been unarchived in the **#${parentName}** (\`${parentId}\`) channel`; const base = `Thread **#${threadName}** (\`${threadId}\`) has been unarchived in the **#${parentName}** (\`${parentId}\`) channel`;
if (threadOwner) { if (threadOwner) {
return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; return `${base} by **${escapeBold(renderUsername(threadOwner.tag))}** (\`${threadOwner.id}\`)`;
} }
return base; return base;
}, },

View file

@ -1,7 +1,7 @@
import escapeStringRegexp from "escape-string-regexp"; import escapeStringRegexp from "escape-string-regexp";
import { commandTypeHelpers as ct } from "../../../commandTypes"; import { commandTypeHelpers as ct } from "../../../commandTypes";
import { isStaffPreFilter } from "../../../pluginUtils"; import { isStaffPreFilter } from "../../../pluginUtils";
import { createChunkedMessage, getUser, sorter } from "../../../utils"; import { createChunkedMessage, getUser, renderUsername, sorter } from "../../../utils";
import { botControlCmd } from "../types"; import { botControlCmd } from "../types";
export const ServersCmd = botControlCmd({ export const ServersCmd = botControlCmd({
@ -48,7 +48,9 @@ export const ServersCmd = botControlCmd({
const lines = filteredGuilds.map((g) => { const lines = filteredGuilds.map((g) => {
const paddedId = g.id.padEnd(longestId, " "); const paddedId = g.id.padEnd(longestId, " ");
const owner = getUser(pluginData.client, g.ownerId); const owner = getUser(pluginData.client, g.ownerId);
return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.tag}** \`${owner.id}\`)`; return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${renderUsername(owner.tag)}** \`${
owner.id
}\`)`;
}); });
createChunkedMessage(msg.channel, lines.join("\n")); createChunkedMessage(msg.channel, lines.join("\n"));
} else { } else {

View file

@ -1,23 +1,23 @@
import type { Snowflake } from "discord.js"; import type { Snowflake } from "discord.js";
import { GuildPluginData } from "knub"; import { GuildPluginData } from "knub";
import { logger } from "../../../logger"; import { logger } from "../../../logger";
import { renderUserUsername, resolveUser } from "../../../utils"; import { renderUsername, resolveUser } from "../../../utils";
import { CaseArgs, CasesPluginType } from "../types"; import { CaseArgs, CasesPluginType } from "../types";
import { createCaseNote } from "./createCaseNote"; import { createCaseNote } from "./createCaseNote";
import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; import { postCaseToCaseLogChannel } from "./postToCaseLogChannel";
export async function createCase(pluginData: GuildPluginData<CasesPluginType>, args: CaseArgs) { export async function createCase(pluginData: GuildPluginData<CasesPluginType>, args: CaseArgs) {
const user = await resolveUser(pluginData.client, args.userId); const user = await resolveUser(pluginData.client, args.userId);
const userName = renderUserUsername(user); const userName = renderUsername(user.username, user.discriminator);
const mod = await resolveUser(pluginData.client, args.modId); const mod = await resolveUser(pluginData.client, args.modId);
const modName = mod.tag; const modName = renderUsername(mod.username, mod.discriminator);
let ppName: string | null = null; let ppName: string | null = null;
let ppId: Snowflake | null = null; let ppId: Snowflake | null = null;
if (args.ppId) { if (args.ppId) {
const pp = await resolveUser(pluginData.client, args.ppId); const pp = await resolveUser(pluginData.client, args.ppId);
ppName = pp.tag; ppName = renderUsername(pp.username, pp.discriminator);
ppId = pp.id; ppId = pp.id;
} }

View file

@ -1,6 +1,6 @@
import { GuildPluginData } from "knub"; import { GuildPluginData } from "knub";
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
import { UnknownUser, resolveUser } from "../../../utils"; import { UnknownUser, renderUsername, resolveUser } from "../../../utils";
import { CaseNoteArgs, CasesPluginType } from "../types"; import { CaseNoteArgs, CasesPluginType } from "../types";
import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; import { postCaseToCaseLogChannel } from "./postToCaseLogChannel";
import { resolveCaseId } from "./resolveCaseId"; import { resolveCaseId } from "./resolveCaseId";
@ -16,7 +16,7 @@ export async function createCaseNote(pluginData: GuildPluginData<CasesPluginType
throw new RecoverablePluginError(ERRORS.INVALID_USER); throw new RecoverablePluginError(ERRORS.INVALID_USER);
} }
const modName = mod.tag; const modName = renderUsername(mod);
let body = args.body; let body = args.body;

View file

@ -48,7 +48,7 @@ export async function sendMessage(
...content, ...content,
...(pluginData.client.user && { ...(pluginData.client.user && {
username: pluginData.client.user.username, username: pluginData.client.user.username,
avatarURL: pluginData.client.user.avatarURL() || pluginData.client.user.defaultAvatarURL, avatarURL: pluginData.client.user.displayAvatarURL(),
}), }),
}) })
.then((apiMessage) => ({ .then((apiMessage) => ({

View file

@ -1,7 +1,7 @@
import { APIEmbed, User } from "discord.js"; import { APIEmbed, GuildMember, User } from "discord.js";
import { commandTypeHelpers as ct } from "../../../commandTypes"; import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils"; import { sendErrorMessage } from "../../../pluginUtils";
import { emptyEmbedValue, resolveUser, trimLines } from "../../../utils"; import { emptyEmbedValue, renderUsername, resolveMember, resolveUser, trimLines } from "../../../utils";
import { asyncMap } from "../../../utils/async"; import { asyncMap } from "../../../utils/async";
import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; import { createPaginatedMessage } from "../../../utils/createPaginatedMessage";
import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields";
@ -28,8 +28,10 @@ export const CasesModCmd = modActionsCmd({
async run({ pluginData, message: msg, args }) { async run({ pluginData, message: msg, args }) {
const modId = args.mod || msg.author.id; const modId = args.mod || msg.author.id;
const mod = await resolveUser(pluginData.client, modId); const mod =
const modName = mod instanceof User ? mod.tag : modId; (await resolveMember(pluginData.client, pluginData.guild, modId)) ||
(await resolveUser(pluginData.client, modId));
const modName = mod instanceof User ? renderUsername(mod) : modId;
const casesPlugin = pluginData.getPlugin(CasesPlugin); const casesPlugin = pluginData.getPlugin(CasesPlugin);
const totalCases = await casesPlugin.getTotalCasesByMod(modId); const totalCases = await casesPlugin.getTotalCasesByMod(modId);
@ -57,7 +59,7 @@ export const CasesModCmd = modActionsCmd({
const embed = { const embed = {
author: { author: {
name: title, name: title,
icon_url: mod instanceof User ? mod.displayAvatarURL() : undefined, icon_url: mod instanceof User || mod instanceof GuildMember ? mod.displayAvatarURL() : undefined,
}, },
fields: [ fields: [
...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")),

View file

@ -1,9 +1,17 @@
import { APIEmbed, User } from "discord.js"; import { APIEmbed } from "discord.js";
import { commandTypeHelpers as ct } from "../../../commandTypes"; import { commandTypeHelpers as ct } from "../../../commandTypes";
import { CaseTypes } from "../../../data/CaseTypes"; import { CaseTypes } from "../../../data/CaseTypes";
import { sendErrorMessage } from "../../../pluginUtils"; import { sendErrorMessage } from "../../../pluginUtils";
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
import { UnknownUser, chunkArray, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import {
UnknownUser,
chunkArray,
emptyEmbedValue,
renderUsername,
resolveMember,
resolveUser,
trimLines,
} from "../../../utils";
import { asyncMap } from "../../../utils/async"; import { asyncMap } from "../../../utils/async";
import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields";
import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { getGuildPrefix } from "../../../utils/getGuildPrefix";
@ -35,8 +43,10 @@ export const CasesUserCmd = modActionsCmd({
], ],
async run({ pluginData, message: msg, args }) { async run({ pluginData, message: msg, args }) {
const user = await resolveUser(pluginData.client, args.user); const user =
if (!user.id) { (await resolveMember(pluginData.client, pluginData.guild, args.user)) ||
(await resolveUser(pluginData.client, args.user));
if (!user.id || user instanceof UnknownUser) {
sendErrorMessage(pluginData, msg.channel, `User not found`); sendErrorMessage(pluginData, msg.channel, `User not found`);
return; return;
} }
@ -62,7 +72,7 @@ export const CasesUserCmd = modActionsCmd({
const hiddenCases = cases.filter((c) => c.is_hidden); const hiddenCases = cases.filter((c) => c.is_hidden);
const userName = const userName =
user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUserUsername(user); user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUsername(user);
if (cases.length === 0) { if (cases.length === 0) {
msg.channel.send(`No cases found for **${userName}**`); msg.channel.send(`No cases found for **${userName}**`);
@ -123,7 +133,7 @@ export const CasesUserCmd = modActionsCmd({
lineChunks.length === 1 lineChunks.length === 1
? `Cases for ${userName} (${lines.length} total)` ? `Cases for ${userName} (${lines.length} total)`
: `Cases ${chunkStart}${chunkEnd} of ${lines.length} for ${userName}`, : `Cases ${chunkStart}${chunkEnd} of ${lines.length} for ${userName}`,
icon_url: user instanceof User ? user.displayAvatarURL() : undefined, icon_url: user.displayAvatarURL(),
}, },
fields: [ fields: [
...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")),

View file

@ -4,7 +4,7 @@ import { GuildPluginData } from "knub";
import moment from "moment-timezone"; import moment from "moment-timezone";
import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage } from "../../../utils"; import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage, renderUsername } from "../../../utils";
import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { PostPluginType } from "../types"; import { PostPluginType } from "../types";
@ -122,7 +122,7 @@ export async function actualPostCmd(
const post = await pluginData.state.scheduledPosts.create({ const post = await pluginData.state.scheduledPosts.create({
author_id: msg.author.id, author_id: msg.author.id,
author_name: msg.author.tag, author_name: renderUsername(msg.author),
channel_id: targetChannel.id, channel_id: targetChannel.id,
content, content,
attachments: [...msg.attachments.values()], attachments: [...msg.attachments.values()],

View file

@ -1,6 +1,6 @@
import { GuildChannel, Message } from "discord.js"; import { GuildChannel, Message } from "discord.js";
import path from "path"; import path from "path";
import { EMPTY_CHAR, EmbedWith } from "../../../utils"; import { EMPTY_CHAR, EmbedWith, renderUsername } from "../../../utils";
const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"];
const audioAttachmentExtensions = ["wav", "mp3", "m4a"]; const audioAttachmentExtensions = ["wav", "mp3", "m4a"];
@ -18,7 +18,7 @@ export function createStarboardEmbedFromMessage(
text: `#${(msg.channel as GuildChannel).name}`, text: `#${(msg.channel as GuildChannel).name}`,
}, },
author: { author: {
name: msg.author.tag, name: renderUsername(msg.author),
}, },
fields: [], fields: [],
timestamp: msg.createdAt.toISOString(), timestamp: msg.createdAt.toISOString(),
@ -28,7 +28,7 @@ export function createStarboardEmbedFromMessage(
embed.color = color; embed.color = color;
} }
embed.author.icon_url = msg.author.displayAvatarURL(); embed.author.icon_url = (msg.member || msg.author).displayAvatarURL();
// The second condition here checks for messages with only an image link that is then embedded. // The second condition here checks for messages with only an image link that is then embedded.
// The message content in that case is hidden by the Discord client, so we hide it here too. // The message content in that case is hidden by the Discord client, so we hide it here too.

View file

@ -100,8 +100,8 @@ export const AboutCmd = utilityCmd({
} }
// Use the bot avatar as the embed image // Use the bot avatar as the embed image
if (pluginData.client.user!.avatarURL()) { if (pluginData.client.user!.displayAvatarURL()) {
aboutEmbed.thumbnail = { url: pluginData.client.user!.avatarURL()! }; aboutEmbed.thumbnail = { url: pluginData.client.user!.displayAvatarURL()! };
} }
msg.channel.send({ embeds: [aboutEmbed] }); msg.channel.send({ embeds: [aboutEmbed] });

View file

@ -1,7 +1,7 @@
import { APIEmbed, ImageFormat } from "discord.js"; import { APIEmbed, ImageFormat } from "discord.js";
import { commandTypeHelpers as ct } from "../../../commandTypes"; import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils"; import { sendErrorMessage } from "../../../pluginUtils";
import { UnknownUser, renderUserUsername } from "../../../utils"; import { UnknownUser, renderUsername } from "../../../utils";
import { utilityCmd } from "../types"; import { utilityCmd } from "../types";
export const AvatarCmd = utilityCmd({ export const AvatarCmd = utilityCmd({
@ -10,17 +10,17 @@ export const AvatarCmd = utilityCmd({
permission: "can_avatar", permission: "can_avatar",
signature: { signature: {
user: ct.resolvedUserLoose({ required: false }), user: ct.resolvedMember({ required: false }) || ct.resolvedUserLoose({ required: false }),
}, },
async run({ message: msg, args, pluginData }) { async run({ message: msg, args, pluginData }) {
const user = args.user || msg.author; const user = args.user || msg.member || msg.author;
if (!(user instanceof UnknownUser)) { if (!(user instanceof UnknownUser)) {
const embed: APIEmbed = { const embed: APIEmbed = {
image: { image: {
url: user.displayAvatarURL({ extension: ImageFormat.PNG, size: 2048 }), url: user.displayAvatarURL({ extension: ImageFormat.PNG, size: 2048 }),
}, },
title: `Avatar of ${renderUserUsername(user)}:`, title: `Avatar of ${renderUsername(user)}:`,
}; };
msg.channel.send({ embeds: [embed] }); msg.channel.send({ embeds: [embed] });
} else { } else {

View file

@ -13,7 +13,6 @@ import {
trimLines, trimLines,
UnknownUser, UnknownUser,
} from "../../../utils"; } from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { UtilityPluginType } from "../types"; import { UtilityPluginType } from "../types";
const MAX_ROLES_TO_DISPLAY = 15; const MAX_ROLES_TO_DISPLAY = 15;
@ -40,13 +39,11 @@ export async function getUserInfoEmbed(
fields: [], fields: [],
}; };
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
embed.author = { embed.author = {
name: `${user.bot ? "Bot" : "User"}: ${renderUsername(user)}`, name: `${user.bot ? "Bot" : "User"}: ${renderUsername(user)}`,
}; };
const avatarURL = user.displayAvatarURL(); const avatarURL = (member || user).displayAvatarURL();
embed.author.icon_url = avatarURL; embed.author.icon_url = avatarURL;
if (compact) { if (compact) {

View file

@ -14,7 +14,7 @@ import { ArgsFromSignatureOrArray, GuildPluginData } from "knub";
import moment from "moment-timezone"; import moment from "moment-timezone";
import { RegExpRunner, allowTimeout } from "../../RegExpRunner"; import { RegExpRunner, allowTimeout } from "../../RegExpRunner";
import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; import { getBaseUrl, sendErrorMessage } from "../../pluginUtils";
import { MINUTES, multiSorter, renderUserUsername, sorter, trimLines } from "../../utils"; import { MINUTES, multiSorter, renderUsername, sorter, trimLines } from "../../utils";
import { asyncFilter } from "../../utils/async"; import { asyncFilter } from "../../utils/async";
import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions";
import { InvalidRegexError, inputPatternToRegExp } from "../../validatorUtils"; import { InvalidRegexError, inputPatternToRegExp } from "../../validatorUtils";
@ -381,7 +381,7 @@ async function performMemberSearch(
return true; return true;
} }
const fullUsername = renderUserUsername(member.user); const fullUsername = renderUsername(member.user);
if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true;
return false; return false;
@ -448,7 +448,7 @@ async function performBanSearch(
const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex); const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex);
matchingBans = await asyncFilter(matchingBans, async (user) => { matchingBans = await asyncFilter(matchingBans, async (user) => {
const fullUsername = renderUserUsername(user); const fullUsername = renderUsername(user);
if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true;
return false; return false;
}); });
@ -492,10 +492,10 @@ function formatSearchResultList(members: Array<GuildMember | User>): string {
const paddedId = member.id.padEnd(longestId, " "); const paddedId = member.id.padEnd(longestId, " ");
let line; let line;
if (member instanceof GuildMember) { if (member instanceof GuildMember) {
line = `${paddedId} ${renderUserUsername(member.user)}`; line = `${paddedId} ${renderUsername(member.user)}`;
if (member.nickname) line += ` (${member.nickname})`; if (member.nickname) line += ` (${member.nickname})`;
} else { } else {
line = `${paddedId} ${member.tag}`; line = `${paddedId} ${renderUsername(member)}`;
} }
return line; return line;
}); });

View file

@ -1603,9 +1603,12 @@ export function isTruthy<T>(value: T): value is Exclude<T, false | null | undefi
export const DBDateFormat = "YYYY-MM-DD HH:mm:ss"; export const DBDateFormat = "YYYY-MM-DD HH:mm:ss";
export function renderUsername(username: User): string; // TODO: Fix overloads
export function renderUsername(username: string, discriminator?: string): string; //export function renderUsername(username: GuildMember): string;
export function renderUsername(username: string | User, discriminator?: string): string { //export function renderUsername(username: User): string;
//export function renderUsername(username: string, discriminator?: string): string;
export function renderUsername(username: string | User | GuildMember, discriminator?: string): string {
if (username instanceof GuildMember) return username.user.tag;
if (username instanceof User) return username.tag; if (username instanceof User) return username.tag;
if (discriminator === "0" || discriminator === "0000") { if (discriminator === "0" || discriminator === "0000") {
return username; return username;

View file

@ -52,7 +52,7 @@ export class TemplateSafeUser extends TemplateSafeValueContainer {
globalName?: string; globalName?: string;
mention: string; mention: string;
tag: string; tag: string;
avatarURL?: string; avatarURL: string;
bot?: boolean; bot?: boolean;
createdAt?: number; createdAt?: number;
renderedUsername: string; renderedUsername: string;
@ -92,7 +92,7 @@ export class TemplateSafeMember extends TemplateSafeUser {
nick: string; nick: string;
roles: TemplateSafeRole[]; roles: TemplateSafeRole[];
joinedAt?: number; joinedAt?: number;
// guildAvatarURL: string, Once DJS supports per-server avatars guildAvatarURL: string;
guildName: string; guildName: string;
constructor(data: InputProps<TemplateSafeMember>) { constructor(data: InputProps<TemplateSafeMember>) {
@ -261,7 +261,7 @@ export function userToTemplateSafeUser(user: User | UnknownUser): TemplateSafeUs
globalName: user.globalName, globalName: user.globalName,
mention: `<@${user.id}>`, mention: `<@${user.id}>`,
tag: user.tag, tag: user.tag,
avatarURL: user.displayAvatarURL?.(), avatarURL: user.displayAvatarURL(),
bot: user.bot, bot: user.bot,
createdAt: user.createdTimestamp, createdAt: user.createdTimestamp,
renderedUsername: renderUserUsername(user), renderedUsername: renderUserUsername(user),
@ -287,6 +287,7 @@ export function memberToTemplateSafeMember(member: GuildMember | PartialGuildMem
nick: member.nickname ?? "*None*", nick: member.nickname ?? "*None*",
roles: [...member.roles.cache.mapValues((r) => roleToTemplateSafeRole(r)).values()], roles: [...member.roles.cache.mapValues((r) => roleToTemplateSafeRole(r)).values()],
joinedAt: member.joinedTimestamp ?? undefined, joinedAt: member.joinedTimestamp ?? undefined,
guildAvatarURL: member.displayAvatarURL(),
guildName: member.guild.name, guildName: member.guild.name,
}); });
} }