Skip to content

Commit 4802f21

Browse files
authored
Smol fixes to things while doing other PRs (#121)
- Fix dashboard loading state so controls are visible - Fix an unhandled case in interaction handling logic - Fix a schema/code types mismatch issue (this is slightly risky but I verified locally that it's tracking correctly with integer dates) - Suppress annoying Kysely upgrade nags on startup - Fix an oversensitive spam trigger that got flagged a few weeks ago - gitignore generated tailwind CSS file so it quits bugging me
1 parent ba05c96 commit 4802f21

File tree

10 files changed

+71
-911
lines changed

10 files changed

+71
-911
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ k8s-context
1212
*.sqlite3
1313
tsconfig.tsbuildinfo
1414
.react-router
15+
tailwind.css

app/db.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface MessageStats {
1919
message_id: string | null;
2020
react_count: Generated<number>;
2121
recipient_id: string | null;
22-
sent_at: string;
22+
sent_at: number;
2323
word_count: number;
2424
}
2525

app/discord/activityTracker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ async function getMessageStats(msg: Message | PartialMessage) {
7676
char_count: content?.length ?? 0,
7777
word_count: content?.split(/\s+/).length ?? 0,
7878
react_count: msg.reactions.cache.size,
79-
sent_at: String(msg.createdTimestamp),
79+
sent_at: msg.createdTimestamp,
8080
};
8181
}
8282

app/discord/automod.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ test("isSpam has a reasonable threshold", () => {
1818
),
1919
).toBe(false);
2020
expect(isSpam("free free free free free")).toBe(false);
21+
expect(isSpam(`https://example.com//w1280$%7Btrend.backdrop_path`)).toBe(
22+
false,
23+
);
2124
});

app/discord/automod.ts

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const spamKeywords = [
1313
"deepfake",
1414
"poki",
1515
"gift",
16-
"\\d\\$",
1716
"18+",
1817
"nudes",
1918
].map((x) => new RegExp(x));

app/discord/deployCommands.server.ts

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export const deployCommands = async (client: Client) => {
6161
}
6262
if (isSlashCommand(config) && interaction.isChatInputCommand()) {
6363
config.handler(interaction);
64+
return;
6465
}
6566
throw new Error("Didn't find a handler for an interaction");
6667
}

app/models/activity.server.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ export async function getTopParticipants(
2020
.selectFrom("message_stats")
2121
.selectAll()
2222
.select(({ fn, val, eb }) => [
23-
fn("date", [eb("sent_at", "/", "1000"), val("unixepoch")]).as("date"),
23+
fn("date", [eb("sent_at", "/", 1000), val("unixepoch")]).as("date"),
2424
])
2525
.where(({ between, and, or, eb }) =>
2626
and([
2727
between(
2828
"sent_at",
29-
new Date(intervalStart).getTime().toString(),
30-
new Date(intervalEnd).getTime().toString(),
29+
new Date(intervalStart).getTime(),
30+
new Date(intervalEnd).getTime(),
3131
),
3232
or([
3333
eb("channel_id", "in", channels),

app/routes/__auth/dashboard.tsx

+57-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { ActionFunction, LoaderFunction } from "react-router";
2-
import { data, useLoaderData } from "react-router";
3-
import type { LabelHTMLAttributes } from "react";
1+
import type { LoaderFunction } from "react-router";
2+
import { data, useLoaderData, useNavigation } from "react-router";
3+
import type { LabelHTMLAttributes, PropsWithChildren } from "react";
44
import { getTopParticipants } from "#~/models/activity.server";
55

66
export const loader = async ({
@@ -18,6 +18,7 @@ export const loader = async ({
1818
}
1919

2020
const REACTIFLUX_GUILD_ID = "102860784329052160";
21+
2122
const output = await getTopParticipants(
2223
REACTIFLUX_GUILD_ID,
2324
start,
@@ -29,43 +30,64 @@ export const loader = async ({
2930
return output;
3031
};
3132

32-
export const action: ActionFunction = async ({ request }) => {
33-
console.log({ request });
34-
};
35-
3633
const Label = (props: LabelHTMLAttributes<Element>) => (
3734
<label {...props} className={`${props.className ?? ""} m-4`}>
3835
{props.children}
3936
</label>
4037
);
4138

42-
const formatter = new Intl.NumberFormat("en-US", {
39+
const percent = new Intl.NumberFormat("en-US", {
4340
style: "percent",
4441
maximumFractionDigits: 0,
45-
});
42+
}).format;
43+
44+
function RangeForm() {
45+
return (
46+
<form method="GET">
47+
<Label>
48+
Start date
49+
<input name="start" type="date" />
50+
</Label>
51+
<Label>
52+
End date
53+
<input name="end" type="date" />
54+
</Label>
55+
<input type="submit" value="Submit" />
56+
</form>
57+
);
58+
}
59+
60+
const DataHeading = ({ children }: PropsWithChildren) => {
61+
return (
62+
<th className="relative origin-bottom-left -rotate-45 max-w-8 text-nowrap">
63+
{children}
64+
</th>
65+
);
66+
};
4667

4768
export default function DashboardPage() {
69+
const nav = useNavigation();
4870
const data = useLoaderData<typeof loader>();
4971

50-
if (!data) {
72+
if (nav.state === "loading") {
5173
return "loading…";
5274
}
5375

76+
if (!data) {
77+
return (
78+
<div>
79+
<div className="flex min-h-full justify-center">
80+
<RangeForm />
81+
</div>
82+
<div></div>
83+
</div>
84+
);
85+
}
86+
5487
return (
5588
<div>
5689
<div className="flex min-h-full justify-center">
57-
<div>test butts</div>
58-
<form method="GET">
59-
<Label>
60-
Start date
61-
<input name="start" type="date" />
62-
</Label>
63-
<Label>
64-
End date
65-
<input name="end" type="date" />
66-
</Label>
67-
<input type="submit" value="Submit" />
68-
</form>
90+
<RangeForm />
6991
</div>
7092
<div>
7193
<textarea
@@ -77,27 +99,27 @@ ${data
7799
)
78100
.join("\n")}`}
79101
></textarea>
80-
<table>
102+
<table className="mt-24">
81103
<thead>
82104
<tr>
83-
<th>Author ID</th>
84-
<th>Percent Zero Days</th>
85-
<th>Word Count</th>
86-
<th>Message Count</th>
87-
<th>Channel Count</th>
88-
<th>Category Count</th>
89-
<th>Reaction Count</th>
90-
<th>Word Score</th>
91-
<th>Message Score</th>
92-
<th>Channel Score</th>
93-
<th>Consistency Score</th>
105+
<DataHeading>Author ID</DataHeading>
106+
<DataHeading>Percent Zero Days</DataHeading>
107+
<DataHeading>Word Count</DataHeading>
108+
<DataHeading>Message Count</DataHeading>
109+
<DataHeading>Channel Count</DataHeading>
110+
<DataHeading>Category Count</DataHeading>
111+
<DataHeading>Reaction Count</DataHeading>
112+
<DataHeading>Word Score</DataHeading>
113+
<DataHeading>Message Score</DataHeading>
114+
<DataHeading>Channel Score</DataHeading>
115+
<DataHeading>Consistency Score</DataHeading>
94116
</tr>
95117
</thead>
96118
<tbody>
97119
{data.map((d) => (
98120
<tr key={d.data.member.author_id}>
99121
<td>{d.data.member.author_id}</td>
100-
<td>{formatter.format(d.metadata.percentZeroDays)}</td>
122+
<td>{percent(d.metadata.percentZeroDays)}</td>
101123
<td>{d.data.member.total_word_count}</td>
102124
<td>{d.data.member.message_count}</td>
103125
<td>{d.data.member.channel_count}</td>

0 commit comments

Comments
 (0)