diff --git a/src/gateway/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts
index 93524058..c21a6d52 100644
--- a/src/gateway/opcodes/LazyRequest.ts
+++ b/src/gateway/opcodes/LazyRequest.ts
@@ -24,6 +24,8 @@ import {
Role,
Session,
LazyRequestSchema,
+ User,
+ Presence,
} from "@fosscord/util";
import {
WebSocket,
@@ -38,6 +40,26 @@ import { check } from "./instanceOf";
// TODO: config: to list all members (even those who are offline) sorted by role, or just those who are online
// TODO: rewrite typeorm
+const getMostRelevantSession = (sessions: Session[]) => {
+ const statusMap = {
+ online: 0,
+ idle: 1,
+ dnd: 2,
+ invisible: 3,
+ offline: 4,
+ };
+ // sort sessions by relevance
+ sessions = sessions.sort((a, b) => {
+ return (
+ statusMap[a.status] -
+ statusMap[b.status] +
+ (a.activities.length - b.activities.length) * 2
+ );
+ });
+
+ return sessions.first();
+};
+
async function getMembers(guild_id: string, range: [number, number]) {
if (!Array.isArray(range) || range.length !== 2) {
throw new Error("range is not a valid array");
@@ -111,24 +133,13 @@ async function getMembers(guild_id: string, range: [number, number]) {
.filter((x: Role) => x.id !== guild_id)
.map((x: Role) => x.id);
- const statusMap = {
- online: 0,
- idle: 1,
- dnd: 2,
- invisible: 3,
- offline: 4,
- };
- // sort sessions by relevance
- const sessions = member.user.sessions.sort((a, b) => {
- return (
- statusMap[a.status] -
- statusMap[b.status] +
- (a.activities.length - b.activities.length) * 2
- );
- });
- const session: Session | undefined = sessions.first();
-
- if (session?.status == "offline") {
+ const session: Session | undefined = getMostRelevantSession(
+ member.user.sessions,
+ );
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ if (session?.status == "unknown") {
session.status = member?.user?.settings?.status || "online";
}
@@ -190,7 +201,38 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
// TODO: check data
check.call(this, LazyRequestSchema, d);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { guild_id, typing, channels, activities } = d as LazyRequestSchema;
+ const { guild_id, typing, channels, activities, members } =
+ d as LazyRequestSchema;
+
+ if (members) {
+ // Client has requested a PRESENCE_UPDATE for specific member
+
+ await Promise.all([
+ members.map(async (x) => {
+ const sessions = await Session.find({ where: { user_id: x } });
+ const session = getMostRelevantSession(sessions);
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ if (session.status == "unknown") session.status = "online";
+ const user = (await User.getPublicUser(x)).toPublicUser(); // why is this needed?
+
+ return Send(this, {
+ op: OPCODES.Dispatch,
+ s: this.sequence++,
+ t: "PRESENCE_UPDATE",
+ d: {
+ user: user,
+ activities: session?.activities || [],
+ client_status: session?.client_info,
+ status: session?.status || "offline",
+ } as Presence,
+ });
+ }),
+ ]);
+
+ if (!channels) return;
+ }
+
if (!channels) throw new Error("Must provide channel ranges");
const channel_id = Object.keys(channels || {}).first();
diff --git a/src/util/schemas/LazyRequestSchema.ts b/src/util/schemas/LazyRequestSchema.ts
index 7cf3fd36..9d25eb37 100644
--- a/src/util/schemas/LazyRequestSchema.ts
+++ b/src/util/schemas/LazyRequestSchema.ts
@@ -22,7 +22,7 @@ export interface LazyRequestSchema {
activities?: boolean;
threads?: boolean;
typing?: true;
- members?: unknown[];
+ members?: string[];
thread_member_lists?: unknown[];
}
@@ -32,6 +32,6 @@ export const LazyRequestSchema = {
$channels: Object,
$typing: Boolean,
$threads: Boolean,
- $members: [] as unknown[],
+ $members: [] as string[],
$thread_member_lists: [] as unknown[],
};
|