Files
DiscordClone/convex/members.ts
2026-02-16 13:08:39 -06:00

87 lines
2.2 KiB
TypeScript

import { query } from "./_generated/server";
import { v } from "convex/values";
import { getPublicStorageUrl } from "./storageUrl";
export const getChannelMembers = query({
args: {
channelId: v.id("channels"),
},
returns: v.any(),
handler: async (ctx, args) => {
const channelKeyDocs = await ctx.db
.query("channelKeys")
.withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
.collect();
const seenUsers = new Set<string>();
const members = [];
for (const doc of channelKeyDocs) {
const odId = doc.userId.toString();
if (seenUsers.has(odId)) continue;
seenUsers.add(odId);
const user = await ctx.db.get(doc.userId);
if (!user) continue;
const userRoleDocs = await ctx.db
.query("userRoles")
.withIndex("by_user", (q) => q.eq("userId", doc.userId))
.collect();
const roles = [];
for (const ur of userRoleDocs) {
const role = await ctx.db.get(ur.roleId);
if (role) {
roles.push({
id: role._id,
name: role.name,
color: role.color,
position: role.position,
isHoist: role.isHoist,
});
}
}
let avatarUrl: string | null = null;
if (user.avatarStorageId) {
avatarUrl = await getPublicStorageUrl(ctx, user.avatarStorageId);
}
members.push({
id: user._id,
username: user.username,
status: user.status || "offline",
roles: roles.sort((a, b) => b.position - a.position),
avatarUrl,
aboutMe: user.aboutMe,
customStatus: user.customStatus,
});
}
return members;
},
});
export const listAll = query({
args: {},
returns: v.any(),
handler: async (ctx) => {
const users = await ctx.db.query("userProfiles").collect();
const results = [];
for (const user of users) {
let avatarUrl: string | null = null;
if (user.avatarStorageId) {
avatarUrl = await getPublicStorageUrl(ctx, user.avatarStorageId);
}
results.push({
id: user._id,
username: user.username,
status: user.status || "offline",
avatarUrl,
});
}
return results;
},
});