Add custom emojis
All checks were successful
Build and Release / build-and-release (push) Successful in 10m4s

This commit is contained in:
Bryan1029384756
2026-02-16 21:33:37 -06:00
parent 2b9fd4e7e0
commit b63c7a71e1
10 changed files with 663 additions and 73 deletions

98
convex/customEmojis.ts Normal file
View File

@@ -0,0 +1,98 @@
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
import { getRolesForUser } from "./roles";
import { getPublicStorageUrl } from "./storageUrl";
export const list = query({
args: {},
returns: v.any(),
handler: async (ctx) => {
const emojis = await ctx.db.query("customEmojis").collect();
const results = await Promise.all(
emojis.map(async (emoji) => {
const src = await getPublicStorageUrl(ctx, emoji.storageId);
const user = await ctx.db.get(emoji.uploadedBy);
return {
_id: emoji._id,
name: emoji.name,
src,
createdAt: emoji.createdAt,
uploadedByUsername: user?.username || "Unknown",
};
})
);
return results.filter((e) => e.src !== null);
},
});
export const upload = mutation({
args: {
userId: v.id("userProfiles"),
name: v.string(),
storageId: v.id("_storage"),
},
returns: v.null(),
handler: async (ctx, args) => {
// Permission check
const roles = await getRolesForUser(ctx, args.userId);
const canManage = roles.some(
(role) => (role.permissions as Record<string, boolean>)?.["manage_channels"]
);
if (!canManage) {
throw new Error("You don't have permission to manage emojis");
}
// Validate name format
const name = args.name.trim();
if (!/^[a-zA-Z0-9_]+$/.test(name)) {
throw new Error("Emoji name can only contain letters, numbers, and underscores");
}
if (name.length < 2 || name.length > 32) {
throw new Error("Emoji name must be between 2 and 32 characters");
}
// Check for duplicate name among custom emojis
const existing = await ctx.db
.query("customEmojis")
.withIndex("by_name", (q) => q.eq("name", name))
.first();
if (existing) {
throw new Error(`A custom emoji named "${name}" already exists`);
}
await ctx.db.insert("customEmojis", {
name,
storageId: args.storageId,
uploadedBy: args.userId,
createdAt: Date.now(),
});
return null;
},
});
export const remove = mutation({
args: {
userId: v.id("userProfiles"),
emojiId: v.id("customEmojis"),
},
returns: v.null(),
handler: async (ctx, args) => {
// Permission check
const roles = await getRolesForUser(ctx, args.userId);
const canManage = roles.some(
(role) => (role.permissions as Record<string, boolean>)?.["manage_channels"]
);
if (!canManage) {
throw new Error("You don't have permission to manage emojis");
}
const emoji = await ctx.db.get(args.emojiId);
if (!emoji) throw new Error("Emoji not found");
await ctx.storage.delete(emoji.storageId);
await ctx.db.delete(args.emojiId);
return null;
},
});