From 17b8b23b806fc26a2293bd851adca6c10c7f648e Mon Sep 17 00:00:00 2001 From: SpaceEEC Date: Sat, 1 Feb 2020 18:27:20 +0100 Subject: [PATCH] feat(Presence/Game): multiple activities and custom status (#3747) * feat(Presence): add activities * feat(Game): add created* and emoji --- src/structures/Presence.js | 57 ++++++++++++++++++++++++++++++++------ typings/index.d.ts | 2 ++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/structures/Presence.js b/src/structures/Presence.js index 98683040b3a2..2e0febb24699 100644 --- a/src/structures/Presence.js +++ b/src/structures/Presence.js @@ -1,4 +1,5 @@ const { ActivityFlags, Endpoints } = require('../util/Constants'); +const ReactionEmoji = require('./ReactionEmoji'); /** * The status of this presence: @@ -30,18 +31,35 @@ class Presence { */ Object.defineProperty(this, 'client', { value: client }); + this.update(data); + } + + update(data) { /** * The status of this presence: * @type {PresenceStatus} */ - this.status = data.status || 'offline'; + this.status = data.status || this.status || 'offline'; /** * The game that the user is playing * @type {?Game} + * @deprecated */ this.game = data.game ? new Game(data.game, this) : null; + if (data.activities) { + /** + * The activities of this presence + * @type {Game[]} + */ + this.activities = data.activities.map(activity => new Game(activity, this)); + } else if (data.activity || data.game) { + this.activities = [new Game(data.activity || data.game, this)]; + } else { + this.activities = []; + } + /** * The devices this presence is on * @type {?Object} @@ -52,12 +70,6 @@ class Presence { this.clientStatus = data.client_status || null; } - update(data) { - this.status = data.status || this.status; - this.game = data.game ? new Game(data.game, this) : null; - this.clientStatus = data.client_status || null; - } - /** * Whether this presence is equal to another * @param {Presence} presence The presence to compare with @@ -67,7 +79,8 @@ class Presence { return this === presence || ( presence && this.status === presence.status && - (this.game ? this.game.equals(presence.game) : !presence.game) && + this.activities.length === presence.activities.length && + this.activities.every((activity, index) => activity.equals(presence.activities[index])) && this.clientStatus.web === presence.clientStatus.web && this.clientStatus.mobile === presence.clientStatus.mobile && this.clientStatus.desktop === presence.clientStatus.desktop @@ -147,10 +160,38 @@ class Game { */ this.assets = data.assets ? new RichPresenceAssets(this, data.assets) : null; + if (data.emoji) { + /** + * Emoji for a custom activity + * There is no `reaction` property for this emoji. + * @type {?ReactionEmoji} + */ + this.emoji = new ReactionEmoji({ message: { client: this.presence.client } }, data.emoji); + this.emoji.reaction = null; + } else { + this.emoji = null; + } + + + /** + * Creation date of the activity + * @type {number} + */ + this.createdTimestamp = new Date(data.created_at).getTime(); + this.syncID = data.sync_id; this._flags = data.flags; } + /** + * The time the activity was created at + * @type {Date} + * @readonly + */ + get createdAt() { + return new Date(this.createdTimestamp); + } + get flags() { const flags = []; for (const [name, flag] of Object.entries(ActivityFlags)) { diff --git a/typings/index.d.ts b/typings/index.d.ts index 1c7c1cc2ea9f..dc9e689b3682 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -439,6 +439,7 @@ declare module 'discord.js' { public applicationID: string; public assets: RichPresenceAssets; public details: string; + public emoji: Omit | null; public name: string; public readonly streaming: boolean; public party: { @@ -1011,6 +1012,7 @@ declare module 'discord.js' { export class Presence { constructor(data: object, client: Client); + public activities: Game[]; public readonly client: Client; public game: Game; public status: PresenceStatusData;