diff --git a/components/inspector/UserActions.tsx b/components/inspector/UserActions.tsx
index a3778b9..7dde812 100644
--- a/components/inspector/UserActions.tsx
+++ b/components/inspector/UserActions.tsx
@@ -26,10 +26,16 @@ import {
suspendUser,
unsuspendUser,
updateBotDiscoverability,
+ updateUserBadges,
} from "@/lib/actions";
import { useRef, useState } from "react";
import { useToast } from "../ui/use-toast";
import { Bot, User } from "revolt-api";
+import { Card, CardHeader } from "../ui/card";
+import { cn } from "@/lib/utils";
+import { decodeTime } from "ulid";
+
+const badges = [1, 2, 4, 8, 16, 32, 128, 0, 256, 512, 1024];
export function UserActions({ user, bot }: { user: User; bot?: Bot }) {
const alertMessage = useRef("");
@@ -41,224 +47,271 @@ export function UserActions({ user, bot }: { user: User; bot?: Bot }) {
const userInaccessible = userDraft.flags === 4 || userDraft.flags === 2;
return (
-
- {bot ? (
- botDraft!.discoverable ? (
-
- ) : (
-
- )
- ) : (
-
- Account
-
- )}
+ <>
+
+
+ {badges.map((badge) => {
+ const sysBadge =
+ (badge === 0 && user._id === "01EX2NCWQ0CHS3QJF0FEQS1GR4") ||
+ (badge === 256 && decodeTime(user._id) < 1629638578431);
+ return (
+ // eslint-disable-next-line
+
{
+ if (sysBadge) return;
-
-
-
-
-
-
-
- Are you sure you want to{" "}
- {userDraft.flags === 1 ? "unsuspend" : "suspend"} this user?
-
-
-
- Cancel
-
- userDraft.flags === 1
- ? unsuspendUser(user._id)
- .then(() => {
- setUserDraft((user) => ({ ...user, flags: 0 }));
- toast({ title: "Unsuspended user" });
- })
- .catch((err) =>
- toast({
- title: "Failed to unsuspend user!",
- description: String(err),
- variant: "destructive",
- })
- )
- : suspendUser(user._id)
- .then(() => {
- setUserDraft((user) => ({ ...user, flags: 1 }));
- toast({ title: "Suspended user" });
- })
- .catch((err) =>
- toast({
- title: "Failed to suspend user!",
- description: String(err),
- variant: "destructive",
- })
- )
- }
- >
- Suspend
-
-
-
-
-
-
-
-
-
-
-
-
- Are you sure you want to ban this user?
-
-
- This action is irreversible!
-
-
-
- Cancel
-
- banUser(user._id)
- .then(() => {
- setUserDraft((user) => ({ ...user, flags: 4 }));
- toast({ title: "Banned user" });
- })
- .catch((err) =>
+ try {
+ const badges =
+ (decodeTime(user._id) < 1629638578431 ? 256 : 0) |
+ ((userDraft.badges ?? 0) ^ badge);
+ await updateUserBadges(user._id, badges);
+ setUserDraft((user) => ({ ...user!, badges }));
toast({
- title: "Failed to ban user!",
+ title: "Updated user badges",
+ });
+ } catch (err) {
+ toast({
+ title: "Failed to update user badges",
description: String(err),
variant: "destructive",
- })
- )
- }
- >
- Ban
-
-
-
-
-
-
-
-
-
-
-
-
- {
- throw "Cancel immediate propagation.";
+ });
+ }
}}
- disabled={userInaccessible}
- >
- Send Alert
-
-
-
-
- Send Alert
-
-
- This will send a message from the Platform Moderation
- account.
-
-
- (alertMessage.current = e.currentTarget.value)
- }
- />
-
-
-
- Cancel
- {
- if (!alertMessage.current) return;
- alertMessage.current = "";
+ />
+ );
+ })}
+
+
- sendAlert(user._id, alertMessage.current)
- .then(() => toast({ title: "Sent Alert" }))
- .catch((err) =>
- toast({
- title: "Failed to send alert!",
- description: String(err),
- variant: "destructive",
+
+ {bot ? (
+ botDraft!.discoverable ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ Account
+
+ )}
+
+
+
+
+
+
+
+
+ Are you sure you want to{" "}
+ {userDraft.flags === 1 ? "unsuspend" : "suspend"} this user?
+
+
+
+ Cancel
+
+ userDraft.flags === 1
+ ? unsuspendUser(user._id)
+ .then(() => {
+ setUserDraft((user) => ({ ...user, flags: 0 }));
+ toast({ title: "Unsuspended user" });
})
- );
- }}
- >
- Send
-
-
-
-
+ .catch((err) =>
+ toast({
+ title: "Failed to unsuspend user!",
+ description: String(err),
+ variant: "destructive",
+ })
+ )
+ : suspendUser(user._id)
+ .then(() => {
+ setUserDraft((user) => ({ ...user, flags: 1 }));
+ toast({ title: "Suspended user" });
+ })
+ .catch((err) =>
+ toast({
+ title: "Failed to suspend user!",
+ description: String(err),
+ variant: "destructive",
+ })
+ )
+ }
+ >
+ Suspend
+
+
+
+
- {/*
+
+
+
+
+
+
+
+ Are you sure you want to ban this user?
+
+
+ This action is irreversible!
+
+
+
+ Cancel
+
+ banUser(user._id)
+ .then(() => {
+ setUserDraft((user) => ({ ...user, flags: 4 }));
+ toast({ title: "Banned user" });
+ })
+ .catch((err) =>
+ toast({
+ title: "Failed to ban user!",
+ description: String(err),
+ variant: "destructive",
+ })
+ )
+ }
+ >
+ Ban
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ throw "Cancel immediate propagation.";
+ }}
+ disabled={userInaccessible}
+ >
+ Send Alert
+
+
+
+
+ Send Alert
+
+
+ This will send a message from the Platform Moderation
+ account.
+
+
+ (alertMessage.current = e.currentTarget.value)
+ }
+ />
+
+
+
+ Cancel
+ {
+ if (!alertMessage.current) return;
+ alertMessage.current = "";
+
+ sendAlert(user._id, alertMessage.current)
+ .then(() => toast({ title: "Sent Alert" }))
+ .catch((err) =>
+ toast({
+ title: "Failed to send alert!",
+ description: String(err),
+ variant: "destructive",
+ })
+ );
+ }}
+ >
+ Send
+
+
+
+
+
+ {/*
Clear ({counts.pending}) Friend Requests
Clear All ({counts.all}) Relations
*/}
-
-
-
+
+
+
+ >
);
}
diff --git a/lib/actions.ts b/lib/actions.ts
index ab2f44a..ebf97ae 100644
--- a/lib/actions.ts
+++ b/lib/actions.ts
@@ -84,7 +84,6 @@ export async function suspendUser(userId: string) {
);
const memberships = await fetchMembershipsByUser(userId);
-
for (const topic of memberships.map((x) => x._id.server)) {
await publishMessage(topic, {
type: "UserUpdate",
@@ -92,6 +91,32 @@ export async function suspendUser(userId: string) {
data: {
flags: 1,
},
+ clear: [],
+ });
+ }
+}
+
+export async function updateUserBadges(userId: string, badges: number) {
+ await mongo().db("revolt").collection("users").updateOne(
+ {
+ _id: userId,
+ },
+ {
+ $set: {
+ badges,
+ },
+ }
+ );
+
+ const memberships = await fetchMembershipsByUser(userId);
+ for (const topic of [userId, ...memberships.map((x) => x._id.server)]) {
+ await publishMessage(topic, {
+ type: "UserUpdate",
+ id: userId,
+ data: {
+ badges,
+ },
+ clear: [],
});
}
}
diff --git a/public/badges/0.svg b/public/badges/0.svg
new file mode 100644
index 0000000..87365aa
--- /dev/null
+++ b/public/badges/0.svg
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/public/badges/1.svg b/public/badges/1.svg
new file mode 100644
index 0000000..4d468eb
--- /dev/null
+++ b/public/badges/1.svg
@@ -0,0 +1,40 @@
+
+
diff --git a/public/badges/1024.svg b/public/badges/1024.svg
new file mode 100644
index 0000000..24f4bd9
--- /dev/null
+++ b/public/badges/1024.svg
@@ -0,0 +1,3018 @@
+
+
+
diff --git a/public/badges/128.svg b/public/badges/128.svg
new file mode 100644
index 0000000..431e64f
--- /dev/null
+++ b/public/badges/128.svg
@@ -0,0 +1,38 @@
+
+
+
diff --git a/public/badges/16.svg b/public/badges/16.svg
new file mode 100644
index 0000000..f8832c3
--- /dev/null
+++ b/public/badges/16.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/public/badges/2.svg b/public/badges/2.svg
new file mode 100644
index 0000000..1e8df12
--- /dev/null
+++ b/public/badges/2.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/badges/2048.svg b/public/badges/2048.svg
new file mode 100644
index 0000000..9f8406a
--- /dev/null
+++ b/public/badges/2048.svg
@@ -0,0 +1,245 @@
+
+
+
diff --git a/public/badges/256.svg b/public/badges/256.svg
new file mode 100644
index 0000000..0da734e
--- /dev/null
+++ b/public/badges/256.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/badges/32.svg b/public/badges/32.svg
new file mode 100644
index 0000000..40bfa6e
--- /dev/null
+++ b/public/badges/32.svg
@@ -0,0 +1,154 @@
+
+
diff --git a/public/badges/4.svg b/public/badges/4.svg
new file mode 100644
index 0000000..dbb2502
--- /dev/null
+++ b/public/badges/4.svg
@@ -0,0 +1,153 @@
+
+
diff --git a/public/badges/512.svg b/public/badges/512.svg
new file mode 100644
index 0000000..c6f490a
--- /dev/null
+++ b/public/badges/512.svg
@@ -0,0 +1,7 @@
+
diff --git a/public/badges/8.svg b/public/badges/8.svg
new file mode 100644
index 0000000..b31345b
--- /dev/null
+++ b/public/badges/8.svg
@@ -0,0 +1 @@
+
\ No newline at end of file