diff --git a/src/gateway/opcodes/PresenceUpdate.ts b/src/gateway/opcodes/PresenceUpdate.ts
index ca52af2a..f4d9ffcf 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 572c28c0..f0dfaf89 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 058961f6..1cb77ebe 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 96d04a55..087f0a59 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 8edd379c..93e1b74f 100644
--- a/src/util/interfaces/Status.ts
+++ b/src/util/interfaces/Status.ts
@@ -16,6 +16,20 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+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"
|