summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gateway/opcodes/LazyRequest.ts80
-rw-r--r--src/util/schemas/LazyRequestSchema.ts4
2 files changed, 63 insertions, 21 deletions
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[],
 };