diff --git a/assets/openapi.json b/assets/openapi.json index aa965def4..769daa671 100644 Binary files a/assets/openapi.json and b/assets/openapi.json differ diff --git a/assets/schemas.json b/assets/schemas.json index e28447eb8..0ec5ee02c 100644 Binary files a/assets/schemas.json and b/assets/schemas.json differ diff --git a/src/gateway/opcodes/PresenceUpdate.ts b/src/gateway/opcodes/PresenceUpdate.ts index ca52af2a2..f4d9ffcfd 100644 --- a/src/gateway/opcodes/PresenceUpdate.ts +++ b/src/gateway/opcodes/PresenceUpdate.ts @@ -17,7 +17,7 @@ */ import { WebSocket, Payload } from "@spacebar/gateway"; -import { emitEvent, PresenceUpdateEvent, Session, User } from "@spacebar/util"; +import { emitEvent, PresenceUpdateEvent, PrivateStatus, PublicStatus, PublicStatusOrder, Session, User } from "@spacebar/util"; import { check } from "./instanceOf"; import { ActivitySchema } from "@spacebar/schemas"; @@ -26,7 +26,12 @@ export async function onPresenceUpdate(this: WebSocket, { d }: Payload) { check.call(this, ActivitySchema, d); const presence = d as ActivitySchema; - await Session.update({ session_id: this.session_id }, { status: presence.status, activities: presence.activities }); + if (d.status === "unknown") { + const sessions = await Session.find({ where: { user_id: this.user_id } }); + d.status = sessions.sort((a, b) => PublicStatusOrder[a.getPublicStatus()] - PublicStatusOrder[b.getPublicStatus()])[0].getPublicStatus(); + } + + await Session.update({ session_id: this.session_id }, { status: presence.status as PrivateStatus, activities: presence.activities }); const session = await Session.findOneOrFail({ select: { client_status: true }, diff --git a/src/schemas/uncategorised/ActivitySchema.ts b/src/schemas/uncategorised/ActivitySchema.ts index 572c28c09..f0dfaf892 100644 --- a/src/schemas/uncategorised/ActivitySchema.ts +++ b/src/schemas/uncategorised/ActivitySchema.ts @@ -17,7 +17,7 @@ */ // TODO: remove entity imports -import { Activity, Status } from "@spacebar/util"; +import { Activity, ClientStatus, Status } from "@spacebar/util"; export const ActivitySchema = { $afk: Boolean, @@ -78,4 +78,5 @@ export interface ActivitySchema { status: Status; activities?: Activity[]; since?: number; // unix time (in milliseconds) of when the client went idle, or null if the client is not idle + client_status?: ClientStatus; } diff --git a/src/util/entities/Session.ts b/src/util/entities/Session.ts index 058961f67..1cb77ebef 100644 --- a/src/util/entities/Session.ts +++ b/src/util/entities/Session.ts @@ -20,7 +20,7 @@ import crypto from "node:crypto"; import { User } from "./User"; import { BaseClassWithoutId } from "./BaseClass"; import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn, RelationId } from "typeorm"; -import { Activity, ClientStatus, GatewaySession, GatewaySessionClientInfo, Status } from "../interfaces"; +import { Activity, ClientStatus, GatewaySession, GatewaySessionClientInfo, PrivateStatus } from "../interfaces"; import { randomUpperString } from "@spacebar/api"; import { DateBuilder, IpDataClient, TimeSpan } from "../util"; @@ -57,7 +57,7 @@ export class Session extends BaseClassWithoutId { client_status: ClientStatus; @Column({ nullable: false, type: String }) - status: Status; + status: PrivateStatus; @Column({ default: false }) is_admin_session: boolean; diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts index 96d04a556..087f0a598 100644 --- a/src/util/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts @@ -35,6 +35,7 @@ import { GuildOrUnavailable, Snowflake, ThreadMember, + PrivateStatus, } from "@spacebar/util"; import { JsonValue } from "@protobuf-ts/runtime"; import { @@ -603,7 +604,7 @@ export interface GatewaySession { activities: Activity[]; hidden_activities: Activity[]; client_info: GatewaySessionClientInfo; - status: Status; + status: PrivateStatus; active?: boolean; // How is this even defined? } diff --git a/src/util/interfaces/Status.ts b/src/util/interfaces/Status.ts index 8edd379c1..93e1b74f6 100644 --- a/src/util/interfaces/Status.ts +++ b/src/util/interfaces/Status.ts @@ -16,6 +16,20 @@ along with this program. If not, see . */ +export enum PublicStatusOrder { + online = 0, + idle = 1, + dnd = 2, + offline = 3, +} + +console.log(PublicStatusOrder); + +export type PublicStatus = keyof typeof PublicStatusOrder; +export type PrivateStatus = PublicStatus | "invisible"; +export type SetPrivateStatus = PrivateStatus | "unknown"; + +// @deprecated Use PublicStatus, PrivateStatus or SetPrivateStatus instead export type Status = | "idle" | "dnd"