mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-07-07 02:57:20 +00:00
feat: native timestamps
This commit is contained in:
parent
eb5fda8d19
commit
6006504459
7 changed files with 305 additions and 243 deletions
|
@ -2,10 +2,23 @@ import humanizeDuration from "humanize-duration";
|
||||||
import { getMemberLevel } from "knub/helpers";
|
import { getMemberLevel } from "knub/helpers";
|
||||||
import { commandTypeHelpers as ct } from "../../../commandTypes.js";
|
import { commandTypeHelpers as ct } from "../../../commandTypes.js";
|
||||||
import { CaseTypes } from "../../../data/CaseTypes.js";
|
import { CaseTypes } from "../../../data/CaseTypes.js";
|
||||||
import { clearExpiringTempban, registerExpiringTempban } from "../../../data/loops/expiringTempbansLoop.js";
|
import {
|
||||||
import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils.js";
|
clearExpiringTempban,
|
||||||
|
registerExpiringTempban,
|
||||||
|
} from "../../../data/loops/expiringTempbansLoop.js";
|
||||||
|
import {
|
||||||
|
canActOn,
|
||||||
|
hasPermission,
|
||||||
|
sendErrorMessage,
|
||||||
|
sendSuccessMessage,
|
||||||
|
} from "../../../pluginUtils.js";
|
||||||
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin.js";
|
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin.js";
|
||||||
import { renderUsername, resolveMember, resolveUser } from "../../../utils.js";
|
import {
|
||||||
|
renderUsername,
|
||||||
|
resolveMember,
|
||||||
|
resolveUser,
|
||||||
|
toRelativeNativeTimestamp,
|
||||||
|
} from "../../../utils.js";
|
||||||
import { banLock } from "../../../utils/lockNameHelpers.js";
|
import { banLock } from "../../../utils/lockNameHelpers.js";
|
||||||
import { waitForButtonConfirm } from "../../../utils/waitForInteraction.js";
|
import { waitForButtonConfirm } from "../../../utils/waitForInteraction.js";
|
||||||
import { LogsPlugin } from "../../Logs/LogsPlugin.js";
|
import { LogsPlugin } from "../../Logs/LogsPlugin.js";
|
||||||
|
@ -51,13 +64,28 @@ export const BanCmd = modActionsCmd({
|
||||||
}
|
}
|
||||||
const time = args["time"] ? args["time"] : null;
|
const time = args["time"] ? args["time"] : null;
|
||||||
|
|
||||||
const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]);
|
const reason = formatReasonWithAttachments(args.reason, [
|
||||||
const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id);
|
...msg.attachments.values(),
|
||||||
|
]);
|
||||||
|
const memberToBan = await resolveMember(
|
||||||
|
pluginData.client,
|
||||||
|
pluginData.guild,
|
||||||
|
user.id,
|
||||||
|
);
|
||||||
// The moderator who did the action is the message author or, if used, the specified -mod
|
// The moderator who did the action is the message author or, if used, the specified -mod
|
||||||
let mod = msg.member;
|
let mod = msg.member;
|
||||||
if (args.mod) {
|
if (args.mod) {
|
||||||
if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) {
|
if (
|
||||||
sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod");
|
!(await hasPermission(pluginData, "can_act_as_other", {
|
||||||
|
message: msg,
|
||||||
|
channelId: msg.channel.id,
|
||||||
|
}))
|
||||||
|
) {
|
||||||
|
sendErrorMessage(
|
||||||
|
pluginData,
|
||||||
|
msg.channel,
|
||||||
|
"You don't have permission to use -mod",
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,13 +95,18 @@ export const BanCmd = modActionsCmd({
|
||||||
// acquire a lock because of the needed user-inputs below (if banned/not on server)
|
// acquire a lock because of the needed user-inputs below (if banned/not on server)
|
||||||
const lock = await pluginData.locks.acquire(banLock(user));
|
const lock = await pluginData.locks.acquire(banLock(user));
|
||||||
let forceban = false;
|
let forceban = false;
|
||||||
const existingTempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id);
|
const existingTempban =
|
||||||
|
await pluginData.state.tempbans.findExistingTempbanForUserId(user.id);
|
||||||
if (!memberToBan) {
|
if (!memberToBan) {
|
||||||
const banned = await isBanned(pluginData, user.id);
|
const banned = await isBanned(pluginData, user.id);
|
||||||
if (banned) {
|
if (banned) {
|
||||||
// Abort if trying to ban user indefinitely if they are already banned indefinitely
|
// Abort if trying to ban user indefinitely if they are already banned indefinitely
|
||||||
if (!existingTempban && !time) {
|
if (!existingTempban && !time) {
|
||||||
sendErrorMessage(pluginData, msg.channel, `User is already banned indefinitely.`);
|
sendErrorMessage(
|
||||||
|
pluginData,
|
||||||
|
msg.channel,
|
||||||
|
`User is already banned indefinitely.`,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,18 +117,29 @@ export const BanCmd = modActionsCmd({
|
||||||
{ confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id },
|
{ confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id },
|
||||||
);
|
);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator");
|
sendErrorMessage(
|
||||||
|
pluginData,
|
||||||
|
msg.channel,
|
||||||
|
"User already banned, update cancelled by moderator",
|
||||||
|
);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Update or add new tempban / remove old tempban
|
// Update or add new tempban / remove old tempban
|
||||||
if (time && time > 0) {
|
if (time && time > 0) {
|
||||||
if (existingTempban) {
|
if (existingTempban) {
|
||||||
await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id);
|
await pluginData.state.tempbans.updateExpiryTime(
|
||||||
|
user.id,
|
||||||
|
time,
|
||||||
|
mod.id,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
await pluginData.state.tempbans.addTempban(user.id, time, mod.id);
|
await pluginData.state.tempbans.addTempban(user.id, time, mod.id);
|
||||||
}
|
}
|
||||||
const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!;
|
const tempban =
|
||||||
|
(await pluginData.state.tempbans.findExistingTempbanForUserId(
|
||||||
|
user.id,
|
||||||
|
))!;
|
||||||
registerExpiringTempban(tempban);
|
registerExpiringTempban(tempban);
|
||||||
} else if (existingTempban) {
|
} else if (existingTempban) {
|
||||||
clearExpiringTempban(existingTempban);
|
clearExpiringTempban(existingTempban);
|
||||||
|
@ -109,7 +153,9 @@ export const BanCmd = modActionsCmd({
|
||||||
type: CaseTypes.Ban,
|
type: CaseTypes.Ban,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
reason,
|
reason,
|
||||||
noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`],
|
noteDetails: [
|
||||||
|
`Ban updated to ${time ? `expire ${toRelativeNativeTimestamp(time)}` : "indefinite"}`,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (time) {
|
if (time) {
|
||||||
pluginData.getPlugin(LogsPlugin).logMemberTimedBan({
|
pluginData.getPlugin(LogsPlugin).logMemberTimedBan({
|
||||||
|
@ -131,7 +177,7 @@ export const BanCmd = modActionsCmd({
|
||||||
sendSuccessMessage(
|
sendSuccessMessage(
|
||||||
pluginData,
|
pluginData,
|
||||||
msg.channel,
|
msg.channel,
|
||||||
`Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`,
|
`Ban updated to ${time ? `expire ${toRelativeNativeTimestamp(time)}` : "indefinite"}`,
|
||||||
);
|
);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
return;
|
return;
|
||||||
|
@ -144,7 +190,11 @@ export const BanCmd = modActionsCmd({
|
||||||
{ confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id },
|
{ confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id },
|
||||||
);
|
);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
sendErrorMessage(pluginData, msg.channel, "User not on server, ban cancelled by moderator");
|
sendErrorMessage(
|
||||||
|
pluginData,
|
||||||
|
msg.channel,
|
||||||
|
"User not on server, ban cancelled by moderator",
|
||||||
|
);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,7 +226,8 @@ export const BanCmd = modActionsCmd({
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteMessageDays =
|
const deleteMessageDays =
|
||||||
args["delete-days"] ?? (await pluginData.config.getForMessage(msg)).ban_delete_message_days;
|
args["delete-days"] ??
|
||||||
|
(await pluginData.config.getForMessage(msg)).ban_delete_message_days;
|
||||||
const banResult = await banUserId(
|
const banResult = await banUserId(
|
||||||
pluginData,
|
pluginData,
|
||||||
user.id,
|
user.id,
|
||||||
|
@ -194,7 +245,11 @@ export const BanCmd = modActionsCmd({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (banResult.status === "failed") {
|
if (banResult.status === "failed") {
|
||||||
sendErrorMessage(pluginData, msg.channel, `Failed to ban member: ${banResult.error}`);
|
sendErrorMessage(
|
||||||
|
pluginData,
|
||||||
|
msg.channel,
|
||||||
|
`Failed to ban member: ${banResult.error}`,
|
||||||
|
);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +263,8 @@ export const BanCmd = modActionsCmd({
|
||||||
let response = "";
|
let response = "";
|
||||||
if (!forceban) {
|
if (!forceban) {
|
||||||
response = `Banned **${renderUsername(user)}** ${forTime}(Case #${banResult.case.case_number})`;
|
response = `Banned **${renderUsername(user)}** ${forTime}(Case #${banResult.case.case_number})`;
|
||||||
if (banResult.notifyResult.text) response += ` (${banResult.notifyResult.text})`;
|
if (banResult.notifyResult.text)
|
||||||
|
response += ` (${banResult.notifyResult.text})`;
|
||||||
} else {
|
} else {
|
||||||
response = `Member forcebanned ${forTime}(Case #${banResult.case.case_number})`;
|
response = `Member forcebanned ${forTime}(Case #${banResult.case.case_number})`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
notifyUser,
|
notifyUser,
|
||||||
resolveMember,
|
resolveMember,
|
||||||
resolveUser,
|
resolveUser,
|
||||||
|
toRelativeNativeTimestamp,
|
||||||
ucfirst,
|
ucfirst,
|
||||||
} from "../../../utils.js";
|
} from "../../../utils.js";
|
||||||
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js";
|
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js";
|
||||||
|
@ -172,7 +173,7 @@ export async function banUserId(
|
||||||
user,
|
user,
|
||||||
caseNumber: createdCase.case_number,
|
caseNumber: createdCase.case_number,
|
||||||
reason: reason ?? "",
|
reason: reason ?? "",
|
||||||
banTime: humanizeDuration(banTime),
|
banTime: toRelativeNativeTimestamp(banTime),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
pluginData.getPlugin(LogsPlugin).logMemberBan({
|
pluginData.getPlugin(LogsPlugin).logMemberBan({
|
||||||
|
|
|
@ -10,7 +10,7 @@ import moment from "moment-timezone";
|
||||||
import { commandTypeHelpers as ct } from "../../../commandTypes.js";
|
import { commandTypeHelpers as ct } from "../../../commandTypes.js";
|
||||||
import { humanizeDurationShort } from "../../../humanizeDurationShort.js";
|
import { humanizeDurationShort } from "../../../humanizeDurationShort.js";
|
||||||
import { getBaseUrl } from "../../../pluginUtils.js";
|
import { getBaseUrl } from "../../../pluginUtils.js";
|
||||||
import { DBDateFormat, MINUTES, renderUsername, resolveMember } from "../../../utils.js";
|
import { DBDateFormat, MINUTES, renderUsername, resolveMember, toRelativeNativeTimestamp } from "../../../utils.js";
|
||||||
import { IMuteWithDetails, mutesCmd } from "../types.js";
|
import { IMuteWithDetails, mutesCmd } from "../types.js";
|
||||||
|
|
||||||
export const MutesCmd = mutesCmd({
|
export const MutesCmd = mutesCmd({
|
||||||
|
@ -131,15 +131,15 @@ export const MutesCmd = mutesCmd({
|
||||||
|
|
||||||
if (mute.expires_at) {
|
if (mute.expires_at) {
|
||||||
const timeUntilExpiry = moment.utc().diff(moment.utc(mute.expires_at, DBDateFormat));
|
const timeUntilExpiry = moment.utc().diff(moment.utc(mute.expires_at, DBDateFormat));
|
||||||
const humanizedTime = humanizeDurationShort(timeUntilExpiry, { largest: 2, round: true });
|
const humanizedTime = toRelativeNativeTimestamp(timeUntilExpiry, 0);
|
||||||
line += ` ⏰ Expires in ${humanizedTime}`;
|
line += ` ⏰ Expires ${humanizedTime}`;
|
||||||
} else {
|
} else {
|
||||||
line += ` ⏰ Indefinite`;
|
line += ` ⏰ Indefinite`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeFromMute = moment.utc(mute.created_at, DBDateFormat).diff(moment.utc());
|
const timeFromMute = moment.utc(mute.created_at, DBDateFormat);
|
||||||
const humanizedTimeFromMute = humanizeDurationShort(timeFromMute, { largest: 2, round: true });
|
const humanizedTimeFromMute = toRelativeNativeTimestamp(timeFromMute);
|
||||||
line += ` 🕒 Muted ${humanizedTimeFromMute} ago`;
|
line += ` 🕒 Muted ${humanizedTimeFromMute}`;
|
||||||
|
|
||||||
if (mute.banned) {
|
if (mute.banned) {
|
||||||
line += ` 🔨 Banned`;
|
line += ` 🔨 Banned`;
|
||||||
|
@ -207,12 +207,17 @@ export const MutesCmd = mutesCmd({
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(buttons);
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(buttons);
|
||||||
await listMessage.edit({ components: [row] });
|
await listMessage.edit({ components: [row] });
|
||||||
|
|
||||||
const collector = listMessage.createMessageComponentCollector({ time: stopCollectionDebounce });
|
const collector = listMessage.createMessageComponentCollector({
|
||||||
|
time: stopCollectionDebounce,
|
||||||
|
});
|
||||||
|
|
||||||
collector.on("collect", async (interaction: MessageComponentInteraction) => {
|
collector.on("collect", async (interaction: MessageComponentInteraction) => {
|
||||||
if (msg.author.id !== interaction.user.id) {
|
if (msg.author.id !== interaction.user.id) {
|
||||||
interaction
|
interaction
|
||||||
.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true })
|
.reply({
|
||||||
|
content: `You are not permitted to use these buttons.`,
|
||||||
|
ephemeral: true,
|
||||||
|
})
|
||||||
// tslint:disable-next-line no-console
|
// tslint:disable-next-line no-console
|
||||||
.catch((err) => console.trace(err.message));
|
.catch((err) => console.trace(err.message));
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,7 +233,10 @@ export const MutesCmd = mutesCmd({
|
||||||
|
|
||||||
stopCollectionFn = async () => {
|
stopCollectionFn = async () => {
|
||||||
collector.stop();
|
collector.stop();
|
||||||
await listMessage.edit({ content: listMessage.content, components: [] });
|
await listMessage.edit({
|
||||||
|
content: listMessage.content,
|
||||||
|
components: [],
|
||||||
|
});
|
||||||
};
|
};
|
||||||
bumpCollectionTimeout();
|
bumpCollectionTimeout();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import humanizeDuration from "humanize-duration";
|
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import { commandTypeHelpers as ct } from "../../../commandTypes.js";
|
import { commandTypeHelpers as ct } from "../../../commandTypes.js";
|
||||||
import { registerUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop.js";
|
import { registerUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop.js";
|
||||||
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils.js";
|
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils.js";
|
||||||
import { convertDelayStringToMS, messageLink } from "../../../utils.js";
|
import { convertDelayStringToMS, toNativeTimestamp, toRelativeNativeTimestamp, messageLink } from "../../../utils.js";
|
||||||
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js";
|
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js";
|
||||||
import { remindersCmd } from "../types.js";
|
import { remindersCmd } from "../types.js";
|
||||||
|
|
||||||
|
@ -61,16 +60,9 @@ export const RemindCmd = remindersCmd({
|
||||||
|
|
||||||
registerUpcomingReminder(reminder);
|
registerUpcomingReminder(reminder);
|
||||||
|
|
||||||
const msUntilReminder = reminderTime.diff(now);
|
const timeUntilReminder = toRelativeNativeTimestamp(reminderTime, 0);
|
||||||
const timeUntilReminder = humanizeDuration(msUntilReminder, { largest: 2, round: true });
|
const prettyReminderTime = toNativeTimestamp(reminderTime);
|
||||||
const prettyReminderTime = (await timeAndDate.inMemberTz(msg.author.id, reminderTime)).format(
|
|
||||||
pluginData.getPlugin(TimeAndDatePlugin).getDateFormat("pretty_datetime"),
|
|
||||||
);
|
|
||||||
|
|
||||||
sendSuccessMessage(
|
sendSuccessMessage(pluginData, msg.channel, `I will remind you ${timeUntilReminder} at ${prettyReminderTime}`);
|
||||||
pluginData,
|
|
||||||
msg.channel,
|
|
||||||
`I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import humanizeDuration from "humanize-duration";
|
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import { sendErrorMessage } from "../../../pluginUtils.js";
|
import { sendErrorMessage } from "../../../pluginUtils.js";
|
||||||
import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils.js";
|
import {
|
||||||
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js";
|
createChunkedMessage,
|
||||||
|
sorter,
|
||||||
|
toNativeTimestamp,
|
||||||
|
toRelativeNativeTimestamp,
|
||||||
|
} from "../../../utils.js";
|
||||||
import { remindersCmd } from "../types.js";
|
import { remindersCmd } from "../types.js";
|
||||||
|
|
||||||
export const RemindersCmd = remindersCmd({
|
export const RemindersCmd = remindersCmd({
|
||||||
|
@ -10,26 +13,23 @@ export const RemindersCmd = remindersCmd({
|
||||||
permission: "can_use",
|
permission: "can_use",
|
||||||
|
|
||||||
async run({ message: msg, pluginData }) {
|
async run({ message: msg, pluginData }) {
|
||||||
const reminders = await pluginData.state.reminders.getRemindersByUserId(msg.author.id);
|
const reminders = await pluginData.state.reminders.getRemindersByUserId(
|
||||||
|
msg.author.id,
|
||||||
|
);
|
||||||
if (reminders.length === 0) {
|
if (reminders.length === 0) {
|
||||||
sendErrorMessage(pluginData, msg.channel, "No reminders");
|
sendErrorMessage(pluginData, msg.channel, "No reminders");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin);
|
|
||||||
|
|
||||||
reminders.sort(sorter("remind_at"));
|
reminders.sort(sorter("remind_at"));
|
||||||
const longestNum = (reminders.length + 1).toString().length;
|
const longestNum = (reminders.length + 1).toString().length;
|
||||||
const lines = Array.from(reminders.entries()).map(([i, reminder]) => {
|
const lines = Array.from(reminders.entries()).map(([i, reminder]) => {
|
||||||
const num = i + 1;
|
const num = i + 1;
|
||||||
const paddedNum = num.toString().padStart(longestNum, " ");
|
const paddedNum = num.toString().padStart(longestNum, " ");
|
||||||
const target = moment.utc(reminder.remind_at, "YYYY-MM-DD HH:mm:ss");
|
const target = moment.utc(reminder.remind_at);
|
||||||
const diff = target.diff(moment.utc());
|
const relative = toRelativeNativeTimestamp(target, 0);
|
||||||
const result = humanizeDuration(diff, { largest: 2, round: true });
|
const prettyRemindAt = toNativeTimestamp(target);
|
||||||
const prettyRemindAt = timeAndDate
|
return `\`${paddedNum}.\` ${prettyRemindAt} (${relative}) ${reminder.body}`;
|
||||||
.inGuildTz(moment.utc(reminder.remind_at, DBDateFormat))
|
|
||||||
.format(timeAndDate.getDateFormat("pretty_datetime"));
|
|
||||||
return `\`${paddedNum}.\` \`${prettyRemindAt} (${result})\` ${reminder.body}`;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
createChunkedMessage(msg.channel, lines.join("\n"));
|
createChunkedMessage(msg.channel, lines.join("\n"));
|
||||||
|
|
|
@ -5,7 +5,7 @@ import shuffle from "lodash/shuffle.js";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import { rootDir } from "../../../paths.js";
|
import { rootDir } from "../../../paths.js";
|
||||||
import { getCurrentUptime } from "../../../uptime.js";
|
import { getCurrentUptime } from "../../../uptime.js";
|
||||||
import { resolveMember, sorter } from "../../../utils.js";
|
import { resolveMember, sorter, toRelativeNativeTimestamp } from "../../../utils.js";
|
||||||
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js";
|
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js";
|
||||||
import { utilityCmd } from "../types.js";
|
import { utilityCmd } from "../types.js";
|
||||||
|
|
||||||
|
@ -31,23 +31,18 @@ export const AboutCmd = utilityCmd({
|
||||||
let version;
|
let version;
|
||||||
|
|
||||||
if (lastCommit) {
|
if (lastCommit) {
|
||||||
lastUpdate = timeAndDate
|
lastUpdate = toRelativeNativeTimestamp(moment.utc(lastCommit.committer.data, "X"), 0);
|
||||||
.inGuildTz(moment.utc(lastCommit.committer.date, "X"))
|
|
||||||
.format(pluginData.getPlugin(TimeAndDatePlugin).getDateFormat("pretty_datetime"));
|
|
||||||
version = lastCommit.shortHash;
|
version = lastCommit.shortHash;
|
||||||
} else {
|
} else {
|
||||||
lastUpdate = "?";
|
lastUpdate = "?";
|
||||||
version = "?";
|
version = "?";
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastReload = humanizeDuration(Date.now() - pluginData.state.lastReload, {
|
const lastReload = toRelativeNativeTimestamp(pluginData.state.lastReload, 0);
|
||||||
largest: 2,
|
|
||||||
round: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const basicInfoRows = [
|
const basicInfoRows = [
|
||||||
["Uptime", prettyUptime],
|
["Uptime", prettyUptime],
|
||||||
["Last config reload", `${lastReload} ago`],
|
["Last config reload", lastReload],
|
||||||
["Last bot update", lastUpdate],
|
["Last bot update", lastUpdate],
|
||||||
["Version", version],
|
["Version", version],
|
||||||
["API latency", `${pluginData.client.ws.ping}ms`],
|
["API latency", `${pluginData.client.ws.ping}ms`],
|
||||||
|
@ -101,7 +96,9 @@ export const AboutCmd = utilityCmd({
|
||||||
|
|
||||||
// Use the bot avatar as the embed image
|
// Use the bot avatar as the embed image
|
||||||
if (pluginData.client.user!.displayAvatarURL()) {
|
if (pluginData.client.user!.displayAvatarURL()) {
|
||||||
aboutEmbed.thumbnail = { url: pluginData.client.user!.displayAvatarURL()! };
|
aboutEmbed.thumbnail = {
|
||||||
|
url: pluginData.client.user!.displayAvatarURL()!,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.channel.send({ embeds: [aboutEmbed] });
|
msg.channel.send({ embeds: [aboutEmbed] });
|
||||||
|
|
|
@ -446,6 +446,14 @@ export function convertMSToDelayString(ms: number): string {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toNativeTimestamp(time, flag = "f") {
|
||||||
|
return `<t:${Math.round(time / 1000)}:${flag}>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toRelativeNativeTimestamp(ms, offset = Date.now()) {
|
||||||
|
return `<t:${Math.round((offset + ms) / 1000)}:R>`;
|
||||||
|
}
|
||||||
|
|
||||||
export function successMessage(str: string, emoji = "<:zep_check:906897402101891093>") {
|
export function successMessage(str: string, emoji = "<:zep_check:906897402101891093>") {
|
||||||
return emoji ? `${emoji} ${str}` : str;
|
return emoji ? `${emoji} ${str}` : str;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue