diff --git a/src/structures/Emoji.js b/src/structures/Emoji.js index 246c95740..1a86aac1b 100644 --- a/src/structures/Emoji.js +++ b/src/structures/Emoji.js @@ -49,6 +49,12 @@ class Emoji { */ this.managed = data.managed; + /** + * Whether this emoji is animated + * @type {boolean} + */ + this.animated = data.animated; + this._roles = data.roles; } @@ -89,7 +95,7 @@ class Emoji { * @readonly */ get url() { - return Constants.Endpoints.CDN(this.client.options.http.cdn).Emoji(this.id); + return Constants.Endpoints.CDN(this.client.options.http.cdn).Emoji(this.id, this.animated ? 'gif' : 'png'); } /** @@ -187,7 +193,11 @@ class Emoji { * msg.reply(`Hello! ${emoji}`); */ toString() { - return this.requiresColons ? `<:${this.name}:${this.id}>` : this.name; + if (!this.id || !this.requiresColons) { + return this.name; + } + + return `<${this.animated ? 'a' : ''}:${this.name}:${this.id}>`; } /** diff --git a/src/util/Constants.js b/src/util/Constants.js index e66304800..d969aa4c0 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -202,7 +202,7 @@ const Endpoints = exports.Endpoints = { Member: m => exports.Endpoints.Guild(m.guild).Member(m), CDN(root) { return { - Emoji: emojiID => `${root}/emojis/${emojiID}.png`, + Emoji: (emojiID, format = 'png') => `${root}/emojis/${emojiID}.${format}`, Asset: name => `${root}/assets/${name}`, Avatar: (userID, hash) => `${root}/avatars/${userID}/${hash}.${hash.startsWith('a_') ? 'gif' : 'png'}?size=2048`, Icon: (guildID, hash) => `${root}/icons/${guildID}/${hash}.jpg`, diff --git a/src/util/Util.js b/src/util/Util.js index c23051a65..393cedf02 100644 --- a/src/util/Util.js +++ b/src/util/Util.js @@ -68,22 +68,17 @@ class Util { * Parses emoji info out of a string. The string must be one of: * * A UTF-8 emoji (no ID) * * A URL-encoded UTF-8 emoji (no ID) - * * A Discord custom emoji (`<:name:id>`) + * * A Discord custom emoji (`<:name:id>` or ``) * @param {string} text Emoji string to parse - * @returns {Object} Object with `name` and `id` properties + * @returns {?Object} Object with `animated`, `name`, and `id` properties * @private */ static parseEmoji(text) { if (text.includes('%')) text = decodeURIComponent(text); - if (text.includes(':')) { - const [name, id] = text.split(':'); - return { name, id }; - } else { - return { - name: text, - id: null, - }; - } + if (!text.includes(':')) return { animated: false, name: text, id: null }; + const m = text.match(/?/); + if (!m) return null; + return { animated: Boolean(m[1]), name: m[2], id: m[3] }; } /**