mirror of
https://github.com/spacebarchat/client.git
synced 2024-11-25 11:42:30 +01:00
rewrite presence store
This commit is contained in:
parent
876b09b878
commit
ce230709e4
@ -2,6 +2,7 @@ import {
|
|||||||
APIGuildMember,
|
APIGuildMember,
|
||||||
APIMessage,
|
APIMessage,
|
||||||
ChannelType,
|
ChannelType,
|
||||||
|
GatewayActivity,
|
||||||
GatewayChannelCreateDispatchData,
|
GatewayChannelCreateDispatchData,
|
||||||
GatewayChannelDeleteDispatchData,
|
GatewayChannelDeleteDispatchData,
|
||||||
GatewayChannelUpdateDispatchData,
|
GatewayChannelUpdateDispatchData,
|
||||||
@ -42,10 +43,23 @@ const GATEWAY_VERSION = "9";
|
|||||||
const GATEWAY_ENCODING = "json";
|
const GATEWAY_ENCODING = "json";
|
||||||
const RECONNECT_TIMEOUT = 10000; // start at 10 seconds, doubles each time
|
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 {
|
export default class GatewayConnectionStore {
|
||||||
private readonly logger: Logger = new Logger("GatewayConnectionStore");
|
private readonly logger: Logger = new Logger("GatewayConnectionStore");
|
||||||
@observable private socket: WebSocket | null = null;
|
@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;
|
@observable public readyState: number = WebSocket.CLOSED;
|
||||||
|
|
||||||
private app: AppStore;
|
private app: AppStore;
|
||||||
@ -67,6 +81,7 @@ export default class GatewayConnectionStore {
|
|||||||
|
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts connection to gateway
|
* Starts connection to gateway
|
||||||
*/
|
*/
|
||||||
@ -449,8 +464,9 @@ export default class GatewayConnectionStore {
|
|||||||
*/
|
*/
|
||||||
private onReady = (data: GatewayReadyDispatchData) => {
|
private onReady = (data: GatewayReadyDispatchData) => {
|
||||||
this.logger.info(`[Ready] took ${Date.now() - this.connectionStartTime!}ms`);
|
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.sessionId = session_id;
|
||||||
|
this.session = (sessions as GatewaySession[]).find((x) => x.session_id === session_id);
|
||||||
|
|
||||||
this.app.setUser(user);
|
this.app.setUser(user);
|
||||||
|
|
||||||
@ -665,7 +681,7 @@ export default class GatewayConnectionStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private onPresenceUpdate = (data: GatewayPresenceUpdateDispatchData) => {
|
private onPresenceUpdate = (data: GatewayPresenceUpdateDispatchData) => {
|
||||||
this.app.presences.add(data);
|
this.app.presences.update(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onTypingStart = (data: GatewayTypingStartDispatchData) => {
|
private onTypingStart = (data: GatewayTypingStartDispatchData) => {
|
||||||
|
@ -63,6 +63,12 @@ export default class GuildMemberListStore {
|
|||||||
data: [],
|
data: [],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// handle presence
|
||||||
|
this.app.presences.add({
|
||||||
|
...item.member.presence,
|
||||||
|
guild_id: this.guild.id,
|
||||||
|
});
|
||||||
|
|
||||||
const member = this.guild.members.get(item.member.id);
|
const member = this.guild.members.get(item.member.id);
|
||||||
if (member) {
|
if (member) {
|
||||||
listData[listData.length - 1].data.push({
|
listData[listData.length - 1].data.push({
|
||||||
|
@ -1,29 +1,11 @@
|
|||||||
import {
|
import type { GatewayPresenceUpdateDispatchData, Snowflake } from "@spacebarchat/spacebar-api-types/v9";
|
||||||
GatewayActivity,
|
import { ObservableMap, action, computed, makeObservable, observable } from "mobx";
|
||||||
GatewayGuildMemberListUpdateMember,
|
|
||||||
GatewayPresenceClientStatus,
|
|
||||||
GatewayPresenceUpdate,
|
|
||||||
PresenceUpdateStatus,
|
|
||||||
Snowflake,
|
|
||||||
} from "@spacebarchat/spacebar-api-types/v9";
|
|
||||||
import { action, makeObservable, observable } from "mobx";
|
|
||||||
import { OneKeyFrom } from "../utils/interfaces/common";
|
|
||||||
import AppStore from "./AppStore";
|
import AppStore from "./AppStore";
|
||||||
|
import Presence from "./objects/Presence";
|
||||||
|
|
||||||
export default class PresenceStore {
|
export default class PresenceStore {
|
||||||
private readonly app: AppStore;
|
private readonly app: AppStore;
|
||||||
@observable presences = observable.map<Snowflake, PresenceUpdateStatus>();
|
@observable presences = observable.map<Snowflake, ObservableMap<Snowflake, Presence>>();
|
||||||
@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>>();
|
|
||||||
|
|
||||||
constructor(app: AppStore) {
|
constructor(app: AppStore) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
@ -32,50 +14,45 @@ export default class PresenceStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
add(presence: GatewayPresenceUpdate | GatewayGuildMemberListUpdateMember["presence"]) {
|
add(data: GatewayPresenceUpdateDispatchData) {
|
||||||
if (presence.status) {
|
if (!this.presences.has(data.guild_id)) {
|
||||||
this.presences.set(presence.user.id, presence.status);
|
this.presences.set(data.guild_id, observable.map<Snowflake, Presence>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presence.activities) {
|
this.presences.get(data.guild_id)?.set(data.user.id, new Presence(this.app, data));
|
||||||
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(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static getStatusColor(status: PresenceUpdateStatus) {
|
@action
|
||||||
// const theme =
|
addAll(data: GatewayPresenceUpdateDispatchData[]) {
|
||||||
|
data.forEach((p) => this.add(p));
|
||||||
|
}
|
||||||
|
|
||||||
// switch (status) {
|
@computed
|
||||||
// case 'online':
|
get all() {
|
||||||
// return theme.colors.palette.green80;
|
return Array.from(this.presences.values());
|
||||||
// case 'idle':
|
}
|
||||||
// return theme.colors.palette.yellow80;
|
|
||||||
// case 'dnd':
|
@action
|
||||||
// return theme.colors.palette.red80;
|
remove(id: Snowflake) {
|
||||||
// case 'offline':
|
this.presences.delete(id);
|
||||||
// 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() {
|
get size() {
|
||||||
return this.presences.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