1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-22 02:12:38 +01:00

rewrite presence store

This commit is contained in:
Puyodead1 2023-12-09 20:31:05 -05:00
parent 876b09b878
commit ce230709e4
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
4 changed files with 99 additions and 64 deletions

View File

@ -2,6 +2,7 @@ import {
APIGuildMember,
APIMessage,
ChannelType,
GatewayActivity,
GatewayChannelCreateDispatchData,
GatewayChannelDeleteDispatchData,
GatewayChannelUpdateDispatchData,
@ -42,10 +43,23 @@ const GATEWAY_VERSION = "9";
const GATEWAY_ENCODING = "json";
const RECONNECT_TIMEOUT = 10000; // start at 10 seconds, doubles each time
interface GatewaySession {
active: boolean;
activities: GatewayActivity[];
client_info: {
client?: string;
os?: string;
version?: number;
};
session_id: string;
status: PresenceUpdateStatus;
}
export default class GatewayConnectionStore {
private readonly logger: Logger = new Logger("GatewayConnectionStore");
@observable private socket: WebSocket | null = null;
@observable private sessionId: string | null = null;
@observable public sessionId: string | null = null;
@observable public session: GatewaySession | undefined;
@observable public readyState: number = WebSocket.CLOSED;
private app: AppStore;
@ -67,6 +81,7 @@ export default class GatewayConnectionStore {
makeObservable(this);
}
/**
* Starts connection to gateway
*/
@ -449,8 +464,9 @@ export default class GatewayConnectionStore {
*/
private onReady = (data: GatewayReadyDispatchData) => {
this.logger.info(`[Ready] took ${Date.now() - this.connectionStartTime!}ms`);
const { session_id, guilds, users, user, private_channels } = data;
const { session_id, guilds, users, user, private_channels, sessions } = data;
this.sessionId = session_id;
this.session = (sessions as GatewaySession[]).find((x) => x.session_id === session_id);
this.app.setUser(user);
@ -665,7 +681,7 @@ export default class GatewayConnectionStore {
};
private onPresenceUpdate = (data: GatewayPresenceUpdateDispatchData) => {
this.app.presences.add(data);
this.app.presences.update(data);
};
private onTypingStart = (data: GatewayTypingStartDispatchData) => {

View File

@ -63,6 +63,12 @@ export default class GuildMemberListStore {
data: [],
});
} else {
// handle presence
this.app.presences.add({
...item.member.presence,
guild_id: this.guild.id,
});
const member = this.guild.members.get(item.member.id);
if (member) {
listData[listData.length - 1].data.push({

View File

@ -1,29 +1,11 @@
import {
GatewayActivity,
GatewayGuildMemberListUpdateMember,
GatewayPresenceClientStatus,
GatewayPresenceUpdate,
PresenceUpdateStatus,
Snowflake,
} from "@spacebarchat/spacebar-api-types/v9";
import { action, makeObservable, observable } from "mobx";
import { OneKeyFrom } from "../utils/interfaces/common";
import type { GatewayPresenceUpdateDispatchData, Snowflake } from "@spacebarchat/spacebar-api-types/v9";
import { ObservableMap, action, computed, makeObservable, observable } from "mobx";
import AppStore from "./AppStore";
import Presence from "./objects/Presence";
export default class PresenceStore {
private readonly app: AppStore;
@observable presences = observable.map<Snowflake, PresenceUpdateStatus>();
@observable presencesForGuilds = observable.map<
Snowflake,
Map<
Snowflake,
Pick<GatewayPresenceUpdate, "activities" | "client_status" | "status"> & {
timestamp: number;
}
>
>();
@observable activities = observable.map<Snowflake, GatewayActivity[]>();
@observable clientStatuses = observable.map<Snowflake, OneKeyFrom<GatewayPresenceClientStatus>>();
@observable presences = observable.map<Snowflake, ObservableMap<Snowflake, Presence>>();
constructor(app: AppStore) {
this.app = app;
@ -32,50 +14,45 @@ export default class PresenceStore {
}
@action
add(presence: GatewayPresenceUpdate | GatewayGuildMemberListUpdateMember["presence"]) {
if (presence.status) {
this.presences.set(presence.user.id, presence.status);
add(data: GatewayPresenceUpdateDispatchData) {
if (!this.presences.has(data.guild_id)) {
this.presences.set(data.guild_id, observable.map<Snowflake, Presence>());
}
if (presence.activities) {
this.activities.set(presence.user.id, presence.activities);
}
if ("client_status" in presence) {
this.clientStatuses.set(
presence.user.id,
presence.client_status as OneKeyFrom<GatewayPresenceClientStatus>,
);
}
if ("guild_id" in presence) {
const guild = this.presencesForGuilds.get(presence.guild_id);
if (guild) {
guild.set(presence.user.id, {
activities: presence.activities,
client_status: presence.client_status,
status: presence.status,
timestamp: Date.now(),
});
}
}
this.presences.get(data.guild_id)?.set(data.user.id, new Presence(this.app, data));
}
// static getStatusColor(status: PresenceUpdateStatus) {
// const theme =
@action
addAll(data: GatewayPresenceUpdateDispatchData[]) {
data.forEach((p) => this.add(p));
}
// switch (status) {
// case 'online':
// return theme.colors.palette.green80;
// case 'idle':
// return theme.colors.palette.yellow80;
// case 'dnd':
// return theme.colors.palette.red80;
// case 'offline':
// case 'invisible':
// return theme.colors.palette.gray80;
// }
// }
@computed
get all() {
return Array.from(this.presences.values());
}
@action
remove(id: Snowflake) {
this.presences.delete(id);
}
@action
update(data: GatewayPresenceUpdateDispatchData) {
this.presences.get(data.guild_id)?.get(data.user.id)?.update(data);
}
get(id: Snowflake) {
return this.presences.get(id);
}
has(id: Snowflake) {
return this.presences.has(id);
}
asList() {
return Array.from(this.presences.values());
}
get size() {
return this.presences.size;

View File

@ -0,0 +1,36 @@
import type {
APIUser,
GatewayActivity,
GatewayPresenceClientStatus,
GatewayPresenceUpdateDispatchData,
PresenceUpdateStatus,
Snowflake,
} from "@spacebarchat/spacebar-api-types/v9";
import { action, observable } from "mobx";
import AppStore from "../AppStore";
import User from "./User";
export default class Presence {
private readonly app: AppStore;
@observable public readonly user: User;
@observable public readonly guildId?: Snowflake;
@observable public readonly status: PresenceUpdateStatus | undefined;
@observable public readonly activities: GatewayActivity[] | undefined;
@observable public readonly clientStatus: GatewayPresenceClientStatus | undefined;
constructor(app: AppStore, data: GatewayPresenceUpdateDispatchData) {
this.app = app;
this.user = this.app.users.get(data.user.id) ?? new User(data.user as APIUser); // TODO: is this right?
this.guildId = data.guild_id;
this.status = data.status;
this.activities = data.activities;
this.clientStatus = data.client_status;
}
@action
update(data: GatewayPresenceUpdateDispatchData) {
Object.assign(this, data);
}
}