feat: Add initial Discord clone application with Convex backend services and Electron React frontend components.
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
import { query, mutation } from "./_generated/server";
|
||||
import { v } from "convex/values";
|
||||
import { GenericMutationCtx } from "convex/server";
|
||||
import { DataModel, Id } from "./_generated/dataModel";
|
||||
|
||||
type TableWithChannelIndex =
|
||||
| "channelKeys"
|
||||
| "dmParticipants"
|
||||
| "typingIndicators"
|
||||
| "voiceStates";
|
||||
|
||||
async function deleteByChannel(
|
||||
ctx: GenericMutationCtx<DataModel>,
|
||||
table: TableWithChannelIndex,
|
||||
channelId: Id<"channels">
|
||||
) {
|
||||
const docs = await (ctx.db.query(table) as any)
|
||||
.withIndex("by_channel", (q: any) => q.eq("channelId", channelId))
|
||||
.collect();
|
||||
for (const doc of docs) {
|
||||
await ctx.db.delete(doc._id);
|
||||
}
|
||||
}
|
||||
|
||||
// List all non-DM channels
|
||||
export const list = query({
|
||||
@@ -49,7 +70,6 @@ export const create = mutation({
|
||||
throw new Error("Channel name required");
|
||||
}
|
||||
|
||||
// Check for duplicate name
|
||||
const existing = await ctx.db
|
||||
.query("channels")
|
||||
.withIndex("by_name", (q) => q.eq("name", args.name))
|
||||
@@ -105,13 +125,12 @@ export const remove = mutation({
|
||||
throw new Error("Channel not found");
|
||||
}
|
||||
|
||||
// Delete messages
|
||||
// Delete reactions for all messages in this channel
|
||||
const messages = await ctx.db
|
||||
.query("messages")
|
||||
.withIndex("by_channel", (q) => q.eq("channelId", args.id))
|
||||
.collect();
|
||||
for (const msg of messages) {
|
||||
// Delete reactions for this message
|
||||
const reactions = await ctx.db
|
||||
.query("messageReactions")
|
||||
.withIndex("by_message", (q) => q.eq("messageId", msg._id))
|
||||
@@ -122,43 +141,11 @@ export const remove = mutation({
|
||||
await ctx.db.delete(msg._id);
|
||||
}
|
||||
|
||||
// Delete channel keys
|
||||
const keys = await ctx.db
|
||||
.query("channelKeys")
|
||||
.withIndex("by_channel", (q) => q.eq("channelId", args.id))
|
||||
.collect();
|
||||
for (const key of keys) {
|
||||
await ctx.db.delete(key._id);
|
||||
}
|
||||
await deleteByChannel(ctx, "channelKeys", args.id);
|
||||
await deleteByChannel(ctx, "dmParticipants", args.id);
|
||||
await deleteByChannel(ctx, "typingIndicators", args.id);
|
||||
await deleteByChannel(ctx, "voiceStates", args.id);
|
||||
|
||||
// Delete DM participants
|
||||
const dmParts = await ctx.db
|
||||
.query("dmParticipants")
|
||||
.withIndex("by_channel", (q) => q.eq("channelId", args.id))
|
||||
.collect();
|
||||
for (const dp of dmParts) {
|
||||
await ctx.db.delete(dp._id);
|
||||
}
|
||||
|
||||
// Delete typing indicators
|
||||
const typing = await ctx.db
|
||||
.query("typingIndicators")
|
||||
.withIndex("by_channel", (q) => q.eq("channelId", args.id))
|
||||
.collect();
|
||||
for (const t of typing) {
|
||||
await ctx.db.delete(t._id);
|
||||
}
|
||||
|
||||
// Delete voice states
|
||||
const voiceStates = await ctx.db
|
||||
.query("voiceStates")
|
||||
.withIndex("by_channel", (q) => q.eq("channelId", args.id))
|
||||
.collect();
|
||||
for (const vs of voiceStates) {
|
||||
await ctx.db.delete(vs._id);
|
||||
}
|
||||
|
||||
// Delete channel itself
|
||||
await ctx.db.delete(args.id);
|
||||
|
||||
return { success: true };
|
||||
|
||||
Reference in New Issue
Block a user