diff --git a/src/opcodes/LazyRequest.ts b/src/opcodes/LazyRequest.ts
index ba7278f0..1d52ff3c 100644
--- a/src/opcodes/LazyRequest.ts
+++ b/src/opcodes/LazyRequest.ts
@@ -1,5 +1,13 @@
// @ts-nocheck WIP
-import { db, getPermission, MemberModel, MongooseCache, PublicUserProjection, RoleModel } from "@fosscord/server-util";
+import {
+ db,
+ getPermission,
+ MemberModel,
+ MongooseCache,
+ PublicUserProjection,
+ RoleModel,
+ toObject,
+} from "@fosscord/server-util";
import { LazyRequest } from "../schema/LazyRequest";
import { OPCODES, Payload } from "../util/Constants";
import { Send } from "../util/Send";
@@ -9,7 +17,6 @@ import { check } from "./instanceOf";
// TODO: config: if want to list all members (even those who are offline) sorted by role, or just those who are online
export async function onLazyRequest(this: WebSocket, { d }: Payload) {
- return; // WIP
// TODO: check data
check.call(this, LazyRequest, d);
const { guild_id, typing, channels, activities } = d as LazyRequest;
@@ -17,37 +24,63 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
const permissions = await getPermission(this.user_id, guild_id);
// MongoDB query to retrieve all hoisted roles and join them with the members and users collection
- const roles = await db
- .collection("roles")
- .aggregate([
- { $match: { guild_id, hoist: true } },
- { $sort: { position: 1 } },
- {
- $lookup: {
- from: "members",
- let: { id: "$id" },
- pipeline: [
- { $match: { $expr: { $in: ["$$id", "$roles"] } } },
- { $limit: 1 },
- {
- $lookup: {
- from: "users",
- let: { user_id: "$id" },
- pipeline: [
- { $match: { $expr: { $eq: ["$id", "$$user_id"] } } },
- { $project: PublicUserProjection },
- ],
- as: "user",
+ const roles = toObject(
+ await db
+ .collection("roles")
+ .aggregate([
+ {
+ $match: {
+ guild_id,
+ // hoist: true // TODO: also match @everyone role
+ },
+ },
+ { $sort: { position: 1 } },
+ {
+ $lookup: {
+ from: "members",
+ let: { id: "$id" },
+ pipeline: [
+ { $match: { $expr: { $in: ["$$id", "$roles"] } } },
+ { $limit: 1 },
+ {
+ $lookup: {
+ from: "users",
+ let: { user_id: "$id" },
+ pipeline: [
+ { $match: { $expr: { $eq: ["$id", "$$user_id"] } } },
+ { $project: PublicUserProjection },
+ ],
+ as: "user",
+ },
},
- },
- ],
- as: "members",
+ {
+ $unwind: "$user",
+ },
+ ],
+ as: "members",
+ },
},
+ ])
+ .toArray()
+ );
+
+ const groups = roles.map((x) => ({ id: x.id === guild_id ? "online" : x.id, count: x.members.length }));
+ const member_count = roles.reduce((a, b) => b.members.length + a, 0);
+ const items = [];
+
+ for (const role of roles) {
+ items.push({
+ group: {
+ count: role.members.length,
+ id: role.id,
},
- ])
- .toArray();
+ });
+ for (const member of role.members) {
+ items.push({ member });
+ }
+ }
- Send(this, {
+ return Send(this, {
op: OPCODES.Dispatch,
s: this.sequence++,
t: "GUILD_MEMBER_LIST_UPDATE",
@@ -56,14 +89,14 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
{
range: [0, 99],
op: "SYNC",
- items: [{ group: { id: "online", count: 0 } }],
+ items: items,
},
],
- online_count: 1,
- member_count: 1,
+ online_count: member_count, // TODO count online count
+ member_count,
id: "everyone",
guild_id,
- groups: [{ id: "online", count: 1 }],
+ groups,
},
});
}
|