feat(presence): added caching and last gateway event!
This commit is contained in:
		
							parent
							
								
									484c6e3c7b
								
							
						
					
					
						commit
						fb110946e0
					
				
					 9 changed files with 124 additions and 25 deletions
				
			
		|  | @ -22,6 +22,8 @@ export const guildCreate: GatewayEventHandler = async ( | |||
| 
 | ||||
|   await guild.roles.fromPayload(d.roles) | ||||
| 
 | ||||
|   if (d.presences !== undefined) await guild.presences.fromPayload(d.presences) | ||||
| 
 | ||||
|   if (d.voice_states !== undefined) | ||||
|     await guild.voiceStates.fromPayload(d.voice_states) | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ export const guildDelte: GatewayEventHandler = async ( | |||
|     await guild.members.flush() | ||||
|     await guild.channels.flush() | ||||
|     await guild.roles.flush() | ||||
|     await guild.presences.flush() | ||||
|     await gateway.client.guilds.delete(d.id) | ||||
| 
 | ||||
|     gateway.client.emit('guildDelete', guild) | ||||
|  |  | |||
|  | @ -14,7 +14,13 @@ export const guildMembersChunk: GatewayEventHandler = async ( | |||
|     await guild.members.set(member.user.id, member) | ||||
|   } | ||||
| 
 | ||||
|   // TODO: Cache Presences
 | ||||
|   if (d.chunk_index === 0) await guild.presences.flush() | ||||
| 
 | ||||
|   if (d.presences !== undefined) { | ||||
|     for (const pres of d.presences) { | ||||
|       await guild.presences.set(pres.user.id, pres) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   gateway.client.emit('guildMembersChunk', guild, { | ||||
|     members: d.members.map((m) => m.user.id), | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ import { inviteCreate } from './inviteCreate.ts' | |||
| import { inviteDelete } from './inviteDelete.ts' | ||||
| import { MessageReaction } from '../../structures/messageReaction.ts' | ||||
| import { Invite } from '../../structures/invite.ts' | ||||
| import { Presence } from '../../structures/presence.ts' | ||||
| 
 | ||||
| export const gatewayHandlers: { | ||||
|   [eventCode in GatewayEvents]: GatewayEventHandler | undefined | ||||
|  | @ -150,5 +151,6 @@ export interface ClientEvents extends EventTypes { | |||
|   voiceStateAdd: (state: VoiceState) => void | ||||
|   voiceStateRemove: (state: VoiceState) => void | ||||
|   voiceStateUpdate: (state: VoiceState, after: VoiceState) => void | ||||
|   presenceUpdate: (presence: Presence) => void | ||||
|   webhooksUpdate: (guild: Guild, channel: GuildTextChannel) => void | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,16 @@ | |||
| import { PresenceUpdatePayload } from '../../types/gateway.ts' | ||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| 
 | ||||
| export const presenceUpdate: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|   d: any | ||||
| ) => {} | ||||
|   d: PresenceUpdatePayload | ||||
| ) => { | ||||
|   const guild = await gateway.client.guilds.get(d.guild_id) | ||||
|   if (guild === undefined) return | ||||
| 
 | ||||
|   await guild.presences.set(d.user.id, d) | ||||
|   const presence = await guild.presences.get(d.user.id) | ||||
|   if (presence === undefined) return | ||||
| 
 | ||||
|   gateway.client.emit('presenceUpdate', presence) | ||||
| } | ||||
|  |  | |||
							
								
								
									
										39
									
								
								src/managers/presences.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/managers/presences.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { Guild } from '../structures/guild.ts' | ||||
| import { Presence } from '../structures/presence.ts' | ||||
| import { User } from '../structures/user.ts' | ||||
| import { PresenceUpdatePayload } from '../types/gateway.ts' | ||||
| import { BaseManager } from './base.ts' | ||||
| 
 | ||||
| export class GuildPresencesManager extends BaseManager< | ||||
|   PresenceUpdatePayload, | ||||
|   Presence | ||||
| > { | ||||
|   guild: Guild | ||||
| 
 | ||||
|   constructor(client: Client, guild: Guild) { | ||||
|     super(client, `presences:${guild.id}`, Presence) | ||||
|     this.guild = guild | ||||
|   } | ||||
| 
 | ||||
|   async get(id: string): Promise<Presence | undefined> { | ||||
|     const raw = await this._get(id) | ||||
|     if (raw === undefined) return | ||||
|     let user = await this.client.users.get(raw.user.id) | ||||
|     if (user === undefined) user = new User(this.client, raw.user) | ||||
|     const guild = await this.client.guilds.get(raw.guild_id) | ||||
|     if (guild === undefined) return | ||||
|     const presence = new Presence(this.client, raw, user, guild) | ||||
|     return presence | ||||
|   } | ||||
| 
 | ||||
|   async fromPayload( | ||||
|     data: PresenceUpdatePayload[] | ||||
|   ): Promise<GuildPresencesManager> { | ||||
|     await this.flush() | ||||
|     for (const pres of data) { | ||||
|       await this.set(pres.user.id, pres) | ||||
|     } | ||||
|     return this | ||||
|   } | ||||
| } | ||||
|  | @ -7,7 +7,6 @@ import { | |||
|   IntegrationAccountPayload, | ||||
|   IntegrationExpireBehavior, | ||||
| } from '../types/guild.ts' | ||||
| import { PresenceUpdatePayload } from '../types/gateway.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { RolesManager } from '../managers/roles.ts' | ||||
| import { InviteManager } from '../managers/invites.ts' | ||||
|  | @ -21,6 +20,7 @@ import { Application } from './application.ts' | |||
| import { GUILD_BAN, GUILD_BANS, GUILD_INTEGRATIONS } from '../types/endpoint.ts' | ||||
| import { GuildVoiceStatesManager } from '../managers/guildVoiceStates.ts' | ||||
| import { RequestMembersOptions } from '../gateway/index.ts' | ||||
| import { GuildPresencesManager } from '../managers/presences.ts' | ||||
| 
 | ||||
| export class GuildBan extends Base { | ||||
|   guild: Guild | ||||
|  | @ -147,7 +147,7 @@ export class Guild extends Base { | |||
|   voiceStates: GuildVoiceStatesManager | ||||
|   members: MembersManager | ||||
|   channels: GuildChannelsManager | ||||
|   presences?: PresenceUpdatePayload[] | ||||
|   presences: GuildPresencesManager | ||||
|   maxPresences?: number | ||||
|   maxMembers?: number | ||||
|   vanityURLCode?: string | ||||
|  | @ -169,6 +169,7 @@ export class Guild extends Base { | |||
|     this.unavailable = data.unavailable | ||||
|     this.members = new MembersManager(this.client, this) | ||||
|     this.voiceStates = new GuildVoiceStatesManager(client, this) | ||||
|     this.presences = new GuildPresencesManager(client, this) | ||||
|     this.channels = new GuildChannelsManager( | ||||
|       this.client, | ||||
|       this.client.channels, | ||||
|  | @ -203,7 +204,6 @@ export class Guild extends Base { | |||
|       this.joinedAt = data.joined_at | ||||
|       this.large = data.large | ||||
|       this.memberCount = data.member_count | ||||
|       this.presences = data.presences | ||||
|       this.maxPresences = data.max_presences | ||||
|       this.maxMembers = data.max_members | ||||
|       this.vanityURLCode = data.vanity_url_code | ||||
|  | @ -252,7 +252,6 @@ export class Guild extends Base { | |||
|       this.joinedAt = data.joined_at ?? this.joinedAt | ||||
|       this.large = data.large ?? this.large | ||||
|       this.memberCount = data.member_count ?? this.memberCount | ||||
|       this.presences = data.presences ?? this.presences | ||||
|       this.maxPresences = data.max_presences ?? this.maxPresences | ||||
|       this.maxMembers = data.max_members ?? this.maxMembers | ||||
|       this.vanityURLCode = data.vanity_url_code ?? this.vanityURLCode | ||||
|  |  | |||
|  | @ -1,5 +1,15 @@ | |||
| import { ActivityGame, ClientActivity, StatusType } from '../types/presence.ts' | ||||
| import { StatusUpdatePayload } from '../types/gateway.ts' | ||||
| import { | ||||
|   ActivityGame, | ||||
|   ActivityPayload, | ||||
|   ClientActivity, | ||||
|   ClientStatus, | ||||
|   StatusType, | ||||
| } from '../types/presence.ts' | ||||
| import { PresenceUpdatePayload, StatusUpdatePayload } from '../types/gateway.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { User } from './user.ts' | ||||
| import { Client } from '../models/client.ts' | ||||
| 
 | ||||
| enum ActivityTypes { | ||||
|   PLAYING = 0, | ||||
|  | @ -7,7 +17,37 @@ enum ActivityTypes { | |||
|   LISTENING = 2, | ||||
|   WATCHING = 3, | ||||
|   CUSTOM_STATUS = 4, | ||||
|   COMPETING = 5 | ||||
|   COMPETING = 5, | ||||
| } | ||||
| 
 | ||||
| export class Presence extends Base { | ||||
|   user: User | ||||
|   guild: Guild | ||||
|   status: StatusType | ||||
|   // TODO: Maybe a new structure for this?
 | ||||
|   activities: ActivityPayload[] | ||||
|   clientStatus: ClientStatus | ||||
| 
 | ||||
|   constructor( | ||||
|     client: Client, | ||||
|     data: PresenceUpdatePayload, | ||||
|     user: User, | ||||
|     guild: Guild | ||||
|   ) { | ||||
|     super(client, data) | ||||
|     this.user = user | ||||
|     this.guild = guild | ||||
|     this.status = data.status | ||||
|     this.activities = data.activities | ||||
|     this.clientStatus = data.client_status | ||||
|   } | ||||
| 
 | ||||
|   fromPayload(data: PresenceUpdatePayload): Presence { | ||||
|     this.status = data.status | ||||
|     this.activities = data.activities | ||||
|     this.clientStatus = data.client_status | ||||
|     return this | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class ClientPresence { | ||||
|  | @ -48,7 +88,7 @@ export class ClientPresence { | |||
|       afk: this.afk === undefined ? false : this.afk, | ||||
|       activities: this.createActivity(), | ||||
|       since: this.since === undefined ? null : this.since, | ||||
|       status: this.status === undefined ? 'online' : this.status | ||||
|       status: this.status === undefined ? 'online' : this.status, | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | @ -62,7 +102,7 @@ export class ClientPresence { | |||
|         : [this.activity] | ||||
|     if (activity === null) return activity | ||||
|     else { | ||||
|       activity.map(e => { | ||||
|       activity.map((e) => { | ||||
|         if (typeof e.type === 'string') e.type = ActivityTypes[e.type] | ||||
|         return e | ||||
|       }) | ||||
|  |  | |||
|  | @ -56,7 +56,7 @@ export enum ActivityFlags { | |||
|   SPECTATE = 1 << 2, | ||||
|   JOIN_REQUEST = 1 << 3, | ||||
|   SYNC = 1 << 4, | ||||
|   PLAY = 1 << 5 | ||||
|   PLAY = 1 << 5, | ||||
| } | ||||
| 
 | ||||
| export type ActivityType = | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue