Skip to content

Commit

Permalink
Always ping Mod in Convene Mods, fix Track for new message types (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
vcarl authored Oct 21, 2024
1 parent 1f44e06 commit 7f1faed
Show file tree
Hide file tree
Showing 14 changed files with 10,935 additions and 9,784 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
- run: npm ci

- name: Run vitest
run: npm run test -- --coverage
run: npm run test

build:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ k8s-context
*.sqlite3
/cypress/screenshots
/cypress/videos
tsconfig.tsbuildinfo
28 changes: 6 additions & 22 deletions app/commands/convene.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
ApplicationCommandType,
ChannelType,
ContextMenuCommandBuilder,
PermissionFlagsBits,
Expand All @@ -8,6 +7,7 @@ import type {
MessageContextMenuCommandInteraction,
TextChannel,
} from "discord.js";
import { ApplicationCommandType } from "discord-api-types/v10";

import { reacord } from "~/discord/client.server";
import { quoteAndEscape } from "~/helpers/discord";
Expand All @@ -16,7 +16,7 @@ import { resolutions } from "~/helpers/modResponse";

import { fetchSettings, SETTINGS } from "~/models/guilds.server";
import { applyRestriction, ban, kick, timeout } from "~/models/discord.server";
import { Confirmation, ModResponse } from "~/commands/reacord/ModResponse";
import { ModResponse } from "~/commands/reacord/ModResponse";

export const command = new ContextMenuCommandBuilder()
.setName("Convene mods")
Expand Down Expand Up @@ -157,15 +157,6 @@ This isn't a formal warning, but your message concerned the moderators enough th
);
return;

case resolutions.okay:
reportUser({
reason: ReportReasons.mod,
message,
staff,
extra: "✅ Determined to be okay",
});
return;

case resolutions.track:
reportUser({
reason: ReportReasons.track,
Expand All @@ -190,15 +181,8 @@ This isn't a formal warning, but your message concerned the moderators enough th
);

// reply
const ackInstance = reacord.ephemeralReply(
interaction,
<Confirmation
modRoleId={moderator}
thread={thread}
onNotify={() => {
ackInstance.render("Mods notified");
ackInstance.deactivate();
}}
/>,
);
await interaction.reply({
content: `Discussion thread created <#${thread.id}>`,
ephemeral: true,
});
};
7 changes: 2 additions & 5 deletions app/commands/demo.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type { CommandInteraction } from "discord.js";
import {
ApplicationCommandType,
ContextMenuCommandBuilder,
SlashCommandBuilder,
} from "discord.js";
import { ContextMenuCommandBuilder, SlashCommandBuilder } from "discord.js";
import { ApplicationCommandType } from "discord-api-types/v10";

export const command = new SlashCommandBuilder()
.setName("demo")
Expand Down
43 changes: 7 additions & 36 deletions app/commands/reacord/ModResponse.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { AnyThreadChannel } from "discord.js";
import type { UserInfo } from "reacord";
import { Button } from "reacord";

import type { Resolution } from "~/helpers/modResponse";
import { humanReadableResolutions } from "~/helpers/modResponse";
import { resolutions, useVotes } from "~/helpers/modResponse";
import {
humanReadableResolutions,
resolutions,
useVotes,
} from "~/helpers/modResponse";

const VOTES_TO_APPROVE = 3;

Expand Down Expand Up @@ -55,18 +57,13 @@ export const ModResponse = ({

return (
<>
{`After ${votesRequired} or more votes, the leading resolution will be automatically enforced.`}
{`After ${votesRequired} or more votes, the leading resolution will be automatically enforced. <@&${modRoleId}> please respond.`}
{/* TODO: show vote in progress, reveal votes and unvoted mods */}
{renderButton(
votes,
resolutions.okay,
humanReadableResolutions[resolutions.okay],
"success",
)}
{renderButton(
votes,
resolutions.track,
humanReadableResolutions[resolutions.track],
"success",
)}
{renderButton(
votes,
Expand Down Expand Up @@ -103,29 +100,3 @@ export const ModResponse = ({
</>
);
};

export const Confirmation = ({
thread,
modRoleId,
onNotify,
}: {
thread: AnyThreadChannel;
modRoleId: string;
onNotify: () => void;
}) => {
return (
<>
Discussion thread created
<Button
label="Notify mods"
style="success"
onClick={async (event) => {
await thread.send(
`<@${event.user.id}> indicated this is urgent. <@&${modRoleId}> please respond`,
);
await onNotify();
}}
/>
</>
);
};
4 changes: 2 additions & 2 deletions app/commands/report.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { MessageContextMenuCommandInteraction } from "discord.js";
import { PermissionFlagsBits } from "discord.js";
import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js";
import { PermissionFlagsBits, ContextMenuCommandBuilder } from "discord.js";
import { ApplicationCommandType } from "discord-api-types/v10";
import { ReportReasons, reportUser } from "~/helpers/modLog";

export const command = new ContextMenuCommandBuilder()
Expand Down
3 changes: 1 addition & 2 deletions app/commands/setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ChatInputCommandInteraction } from "discord.js";
import { PermissionFlagsBits } from "discord.js";
import { SlashCommandBuilder } from "discord.js";
import { PermissionFlagsBits, SlashCommandBuilder } from "discord.js";

import { SETTINGS, setSettings, registerGuild } from "~/models/guilds.server";

Expand Down
4 changes: 2 additions & 2 deletions app/commands/track.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { MessageContextMenuCommandInteraction } from "discord.js";
import { PermissionFlagsBits } from "discord.js";
import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js";
import { PermissionFlagsBits, ContextMenuCommandBuilder } from "discord.js";
import { ApplicationCommandType } from "discord-api-types/v10";
import { Button } from "reacord";
import { reacord } from "~/discord/client.server";

Expand Down
7 changes: 7 additions & 0 deletions app/helpers/discord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
MessageContextMenuCommandInteraction,
UserContextMenuCommandInteraction,
ChatInputCommandInteraction,
Poll,
} from "discord.js";
import {
ApplicationCommandType,
Expand Down Expand Up @@ -103,6 +104,12 @@ export const quoteAndEscape = (content: string) => {
return escapeDisruptiveContent(quoteMessageContent(content));
};

export const quoteAndEscapePoll = (poll: Poll) => {
return `Poll:
> ${poll.question.text}
${poll.answers.map((a) => `> - ${a.text}`).join("\n")}`;
};

//
// Types and type helpers for command configs
//
Expand Down
7 changes: 2 additions & 5 deletions app/helpers/discordCommands.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { calculateChangedCommands, compareCommands } from "./discordCommands";

import {
ApplicationCommandType,
ContextMenuCommandBuilder,
SlashCommandBuilder,
} from "discord.js";
import { ContextMenuCommandBuilder, SlashCommandBuilder } from "discord.js";
import { ApplicationCommandType } from "discord-api-types/v10";

const l = {
slashCommand: new SlashCommandBuilder()
Expand Down
20 changes: 15 additions & 5 deletions app/helpers/modLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
constructDiscordLink,
describeAttachments,
quoteAndEscape,
quoteAndEscapePoll,
} from "~/helpers/discord";
import { simplifyString, truncateMessage } from "~/helpers/string";
import { format, formatDistanceToNowStrict } from "date-fns";
Expand Down Expand Up @@ -156,10 +157,17 @@ const constructLog = async ({
logs: Report[];
previousWarnings: Map<string, { logMessage: Message; logs: Report[] }>;
}): Promise<MessageCreateOptions> => {
const lastReport = logs.at(-1)!;
const { moderator } = await fetchSettings(lastReport.message.guild!, [
const lastReport = logs.at(-1);
if (!lastReport || !lastReport.message.guild) {
throw new Error("Something went wrong when trying to retrieve last report");
}
const { moderator } = await fetchSettings(lastReport.message.guild, [
SETTINGS.moderator,
]);
let { message } = lastReport;
if (lastReport.message.reference) {
message = await message.fetchReference();
}

if (!moderator) {
throw new Error("No role configured to be used as moderator");
Expand All @@ -172,9 +180,11 @@ const constructLog = async ({
} channels ${formatDistanceToNowStrict(lastReport.message.createdAt)} ago`;
const extra = origExtra ? `${origExtra}\n` : "";

const reportedMessage = quoteAndEscape(lastReport.message.content).trim();
const attachments = describeAttachments(lastReport.message.attachments);
let warnings = [];
const reportedMessage = message.poll
? quoteAndEscapePoll(message.poll)
: quoteAndEscape(message.content).trim();
const attachments = describeAttachments(message.attachments);
const warnings = [];
for (const { logMessage } of previousWarnings.values()) {
warnings.push(
`[${format(logMessage.createdAt, "PP kk:mmX")}](${constructDiscordLink(
Expand Down
4 changes: 1 addition & 3 deletions app/helpers/modResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { uniq } from "lodash";
import { useCallback, useMemo, useState } from "react";

export const resolutions = {
okay: "okay",
track: "track",
nudge: "informalWarning",
warning: "formalWarning",
Expand All @@ -12,7 +11,6 @@ export const resolutions = {
ban: "ban",
} as const;
export const humanReadableResolutions = {
[resolutions.okay]: "Okay",
[resolutions.track]: "Track",
[resolutions.nudge]: "Informal Warning",
[resolutions.warning]: "Formal Warning",
Expand All @@ -21,7 +19,7 @@ export const humanReadableResolutions = {
[resolutions.kick]: "Kick",
[resolutions.ban]: "Ban",
} as const;
export type Resolution = (typeof resolutions)[keyof typeof resolutions];
export type Resolution = typeof resolutions[keyof typeof resolutions];

export const useVotes = () => {
const [votes, setVotes] = useState({} as Record<Resolution, string[]>);
Expand Down
Loading

0 comments on commit 7f1faed

Please sign in to comment.