From 9e7f3bdfdece3baff4208b029ae9beab48b55732 Mon Sep 17 00:00:00 2001 From: Rory& Date: Tue, 19 May 2026 16:26:24 +0200 Subject: [PATCH] Rework status enum schema --- assets/openapi.json | Bin 971256 -> 971867 bytes assets/schemas.json | Bin 438781 -> 439311 bytes src/gateway/opcodes/PresenceUpdate.ts | 9 +++++++-- src/schemas/uncategorised/ActivitySchema.ts | 3 ++- src/util/entities/Session.ts | 4 ++-- src/util/interfaces/Event.ts | 3 ++- src/util/interfaces/Status.ts | 14 ++++++++++++++ 7 files changed, 27 insertions(+), 6 deletions(-) diff --git a/assets/openapi.json b/assets/openapi.json index aa965def46d36edb1c561baab6d42db438b77946..769daa671b2ebb6ef93ffca9a9391c5870e9ae61 100644 GIT binary patch delta 390 zcmYMt&nv@W90%~8XW!@hd^g*^D8FXrn>cXTG}`DJZAm#OD};!K9achq6{#s@H>PRt zql1fb*~xQoQOb>xB$U}7Aaiq)N0h^>K7HQrKA+Dc^ZD4!o_LYHw^T!~Rv0=el|~qM z%!Bg)X~^u5KHOXr4n3~;k>4a59__YLtmo*&_MuN4`bgppTfJ&ITF(?KQd1OyOg)g|2ql`O(-C{CZqx3O`W zzM6N5o&hD5=aHrOT686bNiS;`+{Ydi?Qb=R+iT)NHmQ2BTOhS~i8415!<6BvK-~B$ zka}cuqy~#0ydoWP)WT`1Wl1x@BvqIJe!(rl_D(^%d9g}PK@=89bNYP9fz&V`)mP`2 zXBHNt({r)qknH`Zud`|dMZ4CK>6d?vQqqF=F0TI^!+wq!$;%NgX_8g4NhOk9a)`?j Hr+?!cRcwhO delta 245 zcmcb;!urQz>kX^*ra#!u>@nTnl98>sT7P@BKBMZp=@0DrM5h<5W0u-(Ajj0q1ma6g zPcUZGovhH!)}E=z1jNkSGZk5Q^(P19OKyK1#4_RjWKUg_?c0o4ud{3~4Pc33YM*Pt z3dC&N=UT8IVP`h8w3xn8fl+Vzh3RZs(>I7Pn@w|K<=p<;fjv?jC}}o*V-2&}^aU>L zq0_%dvhzdKLxq5vDmY{(JA|@K4|vCEIsHH&qx5tKHfGJ~-y+!sKuRYs+^o>98O097 Y96-zo#9Tnk4a7V^%)4DPiqEJD0A-X@sQ>@~ diff --git a/assets/schemas.json b/assets/schemas.json index e28447eb8416da2d7687f646461f5e74dd3d727b..0ec5ee02c5e8b633c14d9c879482c933c06179a1 100644 GIT binary patch delta 343 zcmezSSgQYp)P_pc$rr>0roV4wW}V)X!QwZ4f+=Ho^99xI7gQPDS5N;ii&b#?IW88? z=?;RdmeVg>U{snukDrlax=J3C*kl7<@$Cf{8Fw+l)p1PUpw7rX-N2raXZm`5M&aoS zt615lUyx&zo?dW+k$1YB7n4$Z!ez$o3747D?rsmwWl><7+#e&g{r(1Kn;q-{MVV!Z zC8?A1R8+RxXR?U02tq}IOA<>;i@od82CMn>1=?&{(;tMeaZW$2&87-s2~IySnKgRy1b_9( z35Qvy7wE7lLxdfS*<81u)?g`9;nU_bvQ78yWagaSdy?6Ix`8DVNApaz?K9OFAFg6e%1qD9 zo4)V?v-~tg7LM)TFET!7WC00IZ>(n(nO?xiC^z{)8C!et6~^twSC|s+PA-UNo4)%2 zi|}^dEzCAMrhnjMVc8y%!(z&^{nAEeMW*)lLYD3Ag{;|onawOMrazQqRGZ$ghgEU< zh2Kmp+a2`Twh99!%%)E?V=JDX?aamxR>qjinm0XR2dmiRf-i!T1ulwAb~vd7m!4e6 MDY3oCg>7y=0J#-U@c;k- 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"