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:
parent
876b09b878
commit
ce230709e4
@ -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) => {
|
||||
|
@ -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({
|
||||
|
@ -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);
|
||||
this.presences.get(data.guild_id)?.set(data.user.id, new Presence(this.app, data));
|
||||
}
|
||||
|
||||
if ("client_status" in presence) {
|
||||
this.clientStatuses.set(
|
||||
presence.user.id,
|
||||
presence.client_status as OneKeyFrom<GatewayPresenceClientStatus>,
|
||||
);
|
||||
@action
|
||||
addAll(data: GatewayPresenceUpdateDispatchData[]) {
|
||||
data.forEach((p) => this.add(p));
|
||||
}
|
||||
|
||||
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(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@computed
|
||||
get all() {
|
||||
return Array.from(this.presences.values());
|
||||
}
|
||||
|
||||
// static getStatusColor(status: PresenceUpdateStatus) {
|
||||
// const theme =
|
||||
@action
|
||||
remove(id: Snowflake) {
|
||||
this.presences.delete(id);
|
||||
}
|
||||
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
@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;
|
||||
|
36
src/stores/objects/Presence.ts
Normal file
36
src/stores/objects/Presence.ts
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user