-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: application emojis * chore: requested changes --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
45f7e1a
commit 5d92525
Showing
9 changed files
with
402 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
packages/discord.js/src/managers/ApplicationEmojiManager.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
'use strict'; | ||
|
||
const { Collection } = require('@discordjs/collection'); | ||
const { Routes } = require('discord-api-types/v10'); | ||
const CachedManager = require('./CachedManager'); | ||
const { DiscordjsTypeError, ErrorCodes } = require('../errors'); | ||
const ApplicationEmoji = require('../structures/ApplicationEmoji'); | ||
const { resolveImage } = require('../util/DataResolver'); | ||
|
||
/** | ||
* Manages API methods for ApplicationEmojis and stores their cache. | ||
* @extends {CachedManager} | ||
*/ | ||
class ApplicationEmojiManager extends CachedManager { | ||
constructor(application, iterable) { | ||
super(application.client, ApplicationEmoji, iterable); | ||
|
||
/** | ||
* The application this manager belongs to | ||
* @type {ClientApplication} | ||
*/ | ||
this.application = application; | ||
} | ||
|
||
_add(data, cache) { | ||
return super._add(data, cache, { extras: [this.application] }); | ||
} | ||
|
||
/** | ||
* Options used for creating an emoji of the application | ||
* @typedef {Object} ApplicationEmojiCreateOptions | ||
* @property {BufferResolvable|Base64Resolvable} attachment The image for the emoji | ||
* @property {string} name The name for the emoji | ||
*/ | ||
|
||
/** | ||
* Creates a new custom emoji of the application. | ||
* @param {ApplicationEmojiCreateOptions} options Options for creating the emoji | ||
* @returns {Promise<Emoji>} The created emoji | ||
* @example | ||
* // Create a new emoji from a URL | ||
* application.emojis.create({ attachment: 'https://i.imgur.com/w3duR07.png', name: 'rip' }) | ||
* .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) | ||
* .catch(console.error); | ||
* @example | ||
* // Create a new emoji from a file on your computer | ||
* application.emojis.create({ attachment: './memes/banana.png', name: 'banana' }) | ||
* .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) | ||
* .catch(console.error); | ||
*/ | ||
async create({ attachment, name }) { | ||
attachment = await resolveImage(attachment); | ||
if (!attachment) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType); | ||
|
||
const body = { image: attachment, name }; | ||
|
||
const emoji = await this.client.rest.post(Routes.applicationEmojis(this.application.id), { body }); | ||
return this._add(emoji); | ||
} | ||
|
||
/** | ||
* Obtains one or more emojis from Discord, or the emoji cache if they're already available. | ||
* @param {Snowflake} [id] The emoji's id | ||
* @param {BaseFetchOptions} [options] Additional options for this fetch | ||
* @returns {Promise<ApplicationEmoji|Collection<Snowflake, ApplicationEmoji>>} | ||
* @example | ||
* // Fetch all emojis from the application | ||
* message.application.emojis.fetch() | ||
* .then(emojis => console.log(`There are ${emojis.size} emojis.`)) | ||
* .catch(console.error); | ||
* @example | ||
* // Fetch a single emoji | ||
* message.application.emojis.fetch('222078108977594368') | ||
* .then(emoji => console.log(`The emoji name is: ${emoji.name}`)) | ||
* .catch(console.error); | ||
*/ | ||
async fetch(id, { cache = true, force = false } = {}) { | ||
if (id) { | ||
if (!force) { | ||
const existing = this.cache.get(id); | ||
if (existing) return existing; | ||
} | ||
const emoji = await this.client.rest.get(Routes.applicationEmoji(this.application.id, id)); | ||
return this._add(emoji, cache); | ||
} | ||
|
||
const { items: data } = await this.client.rest.get(Routes.applicationEmojis(this.application.id)); | ||
const emojis = new Collection(); | ||
for (const emoji of data) emojis.set(emoji.id, this._add(emoji, cache)); | ||
return emojis; | ||
} | ||
|
||
/** | ||
* Deletes an emoji. | ||
* @param {EmojiResolvable} emoji The Emoji resolvable to delete | ||
* @returns {Promise<void>} | ||
*/ | ||
async delete(emoji) { | ||
const id = this.resolveId(emoji); | ||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); | ||
await this.client.rest.delete(Routes.applicationEmoji(this.application.id, id)); | ||
} | ||
|
||
/** | ||
* Edits an emoji. | ||
* @param {EmojiResolvable} emoji The Emoji resolvable to edit | ||
* @param {ApplicationEmojiEditOptions} options The options to provide | ||
* @returns {Promise<ApplicationEmoji>} | ||
*/ | ||
async edit(emoji, options) { | ||
const id = this.resolveId(emoji); | ||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); | ||
|
||
const newData = await this.client.rest.patch(Routes.applicationEmoji(this.application.id, id), { | ||
body: { | ||
name: options.name, | ||
}, | ||
}); | ||
const existing = this.cache.get(id); | ||
if (existing) { | ||
existing._patch(newData); | ||
return existing; | ||
} | ||
return this._add(newData); | ||
} | ||
|
||
/** | ||
* Fetches the author for this emoji | ||
* @param {EmojiResolvable} emoji The emoji to fetch the author of | ||
* @returns {Promise<User>} | ||
*/ | ||
async fetchAuthor(emoji) { | ||
const id = this.resolveId(emoji); | ||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); | ||
|
||
const data = await this.client.rest.get(Routes.applicationEmoji(this.application.id, id)); | ||
|
||
return this._add(data).author; | ||
} | ||
} | ||
|
||
module.exports = ApplicationEmojiManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
'use strict'; | ||
|
||
const { Emoji } = require('./Emoji'); | ||
|
||
/** | ||
* Represents a custom emoji. | ||
* @extends {Emoji} | ||
*/ | ||
class ApplicationEmoji extends Emoji { | ||
constructor(client, data, application) { | ||
super(client, data); | ||
|
||
/** | ||
* The application this emoji originates from | ||
* @type {ClientApplication} | ||
*/ | ||
this.application = application; | ||
|
||
/** | ||
* The user who created this emoji | ||
* @type {?User} | ||
*/ | ||
this.author = null; | ||
|
||
this.managed = null; | ||
this.requiresColons = null; | ||
|
||
this._patch(data); | ||
} | ||
|
||
_patch(data) { | ||
if ('name' in data) this.name = data.name; | ||
if (data.user) this.author = this.client.users._add(data.user); | ||
|
||
if ('managed' in data) { | ||
/** | ||
* Whether this emoji is managed by an external service | ||
* @type {?boolean} | ||
*/ | ||
this.managed = data.managed; | ||
} | ||
|
||
if ('require_colons' in data) { | ||
/** | ||
* Whether or not this emoji requires colons surrounding it | ||
* @type {?boolean} | ||
*/ | ||
this.requiresColons = data.require_colons; | ||
} | ||
} | ||
|
||
/** | ||
* Fetches the author for this emoji | ||
* @returns {Promise<User>} | ||
*/ | ||
fetchAuthor() { | ||
return this.application.emojis.fetchAuthor(this); | ||
} | ||
|
||
/** | ||
* Data for editing an emoji. | ||
* @typedef {Object} ApplicationEmojiEditOptions | ||
* @property {string} [name] The name of the emoji | ||
*/ | ||
|
||
/** | ||
* Edits the emoji. | ||
* @param {ApplicationEmojiEditOptions} options The options to provide | ||
* @returns {Promise<ApplicationEmoji>} | ||
* @example | ||
* // Edit an emoji | ||
* emoji.edit({ name: 'newemoji' }) | ||
* .then(emoji => console.log(`Edited emoji ${emoji}`)) | ||
* .catch(console.error); | ||
*/ | ||
edit(options) { | ||
return this.application.emojis.edit(this.id, options); | ||
} | ||
|
||
/** | ||
* Sets the name of the emoji. | ||
* @param {string} name The new name for the emoji | ||
* @returns {Promise<ApplicationEmoji>} | ||
*/ | ||
setName(name) { | ||
return this.edit({ name }); | ||
} | ||
|
||
/** | ||
* Deletes the emoji. | ||
* @returns {Promise<ApplicationEmoji>} | ||
*/ | ||
async delete() { | ||
await this.application.emojis.delete(this.id); | ||
return this; | ||
} | ||
|
||
/** | ||
* Whether this emoji is the same as another one. | ||
* @param {ApplicationEmoji|APIEmoji} other The emoji to compare it to | ||
* @returns {boolean} | ||
*/ | ||
equals(other) { | ||
if (other instanceof ApplicationEmoji) { | ||
return ( | ||
other.animated === this.animated && | ||
other.id === this.id && | ||
other.name === this.name && | ||
other.managed === this.managed && | ||
other.requiresColons === this.requiresColons | ||
); | ||
} | ||
|
||
return other.id === this.id && other.name === this.name; | ||
} | ||
} | ||
|
||
module.exports = ApplicationEmoji; |
Oops, something went wrong.