mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat: add support for role icons (#6633)
This commit is contained in:
@@ -4,6 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const Role = require('../structures/Role');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
const Permissions = require('../util/Permissions');
|
||||
const { resolveColor, setPosition } = require('../util/Util');
|
||||
|
||||
@@ -104,6 +105,10 @@ class RoleManager extends CachedManager {
|
||||
* @property {PermissionResolvable} [permissions] The permissions for the new role
|
||||
* @property {number} [position] The position of the new role
|
||||
* @property {boolean} [mentionable] Whether or not the new role should be mentionable
|
||||
* @property {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} [icon] The icon for the role
|
||||
* <warn>The `EmojiResolvable` should belong to the same guild as the role.
|
||||
* If not, pass the emoji's URL directly</warn>
|
||||
* @property {?string} [unicodeEmoji] The unicode emoji for the role
|
||||
* @property {string} [reason] The reason for creating this role
|
||||
*/
|
||||
|
||||
@@ -128,9 +133,14 @@ class RoleManager extends CachedManager {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async create(options = {}) {
|
||||
let { name, color, hoist, permissions, position, mentionable, reason } = options;
|
||||
let { name, color, hoist, permissions, position, mentionable, reason, icon, unicodeEmoji } = options;
|
||||
color &&= resolveColor(color);
|
||||
if (typeof permissions !== 'undefined') permissions = new Permissions(permissions);
|
||||
if (icon) {
|
||||
const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
|
||||
icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
|
||||
if (typeof icon !== 'string') icon = undefined;
|
||||
}
|
||||
|
||||
const data = await this.client.api.guilds(this.guild.id).roles.post({
|
||||
data: {
|
||||
@@ -139,6 +149,8 @@ class RoleManager extends CachedManager {
|
||||
hoist,
|
||||
permissions,
|
||||
mentionable,
|
||||
icon,
|
||||
unicode_emoji: unicodeEmoji,
|
||||
},
|
||||
reason,
|
||||
});
|
||||
@@ -182,12 +194,21 @@ class RoleManager extends CachedManager {
|
||||
});
|
||||
}
|
||||
|
||||
let icon = data.icon;
|
||||
if (icon) {
|
||||
const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
|
||||
icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
|
||||
if (typeof icon !== 'string') icon = undefined;
|
||||
}
|
||||
|
||||
const _data = {
|
||||
name: data.name,
|
||||
color: typeof data.color === 'undefined' ? undefined : resolveColor(data.color),
|
||||
hoist: data.hoist,
|
||||
permissions: typeof data.permissions === 'undefined' ? undefined : new Permissions(data.permissions),
|
||||
mentionable: data.mentionable,
|
||||
icon,
|
||||
unicode_emoji: data.unicodeEmoji,
|
||||
};
|
||||
|
||||
const d = await this.client.api.guilds(this.guild.id).roles(role.id).patch({ data: _data, reason });
|
||||
|
||||
@@ -186,6 +186,7 @@ class Guild extends AnonymousGuild {
|
||||
* * THREE_DAY_THREAD_ARCHIVE
|
||||
* * SEVEN_DAY_THREAD_ARCHIVE
|
||||
* * PRIVATE_THREADS
|
||||
* * ROLE_ICONS
|
||||
* @typedef {string} Features
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#guild-object-guild-features}
|
||||
*/
|
||||
|
||||
@@ -91,6 +91,18 @@ class Role extends Base {
|
||||
*/
|
||||
this.deleted = false;
|
||||
|
||||
/**
|
||||
* The icon hash of the role
|
||||
* @type {?string}
|
||||
*/
|
||||
this.icon = data.icon;
|
||||
|
||||
/**
|
||||
* The unicode emoji for the role
|
||||
* @type {?string}
|
||||
*/
|
||||
this.unicodeEmoji = data.unicode_emoji;
|
||||
|
||||
/**
|
||||
* The tags this role has
|
||||
* @type {?Object}
|
||||
@@ -191,6 +203,10 @@ class Role extends Base {
|
||||
* @property {number} [position] The position of the role
|
||||
* @property {PermissionResolvable} [permissions] The permissions of the role
|
||||
* @property {boolean} [mentionable] Whether or not the role should be mentionable
|
||||
* @property {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} [icon] The icon for the role
|
||||
* <warn>The `EmojiResolvable` should belong to the same guild as the role.
|
||||
* If not, pass the emoji's URL directly</warn>
|
||||
* @property {?string} [unicodeEmoji] The unicode emoji for the role
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -300,6 +316,33 @@ class Role extends Base {
|
||||
return this.edit({ mentionable }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new icon for the role.
|
||||
* @param {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} icon The icon for the role
|
||||
* <warn>The `EmojiResolvable` should belong to the same guild as the role.
|
||||
* If not, pass the emoji's URL directly</warn>
|
||||
* @param {string} [reason] Reason for changing the role's icon
|
||||
* @returns {Promise<Role>}
|
||||
*/
|
||||
setIcon(icon, reason) {
|
||||
return this.edit({ icon }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new unicode emoji for the role.
|
||||
* @param {?string} unicodeEmoji The new unicode emoji for the role
|
||||
* @param {string} [reason] Reason for changing the role's unicode emoji
|
||||
* @returns {Promise<Role>}
|
||||
* @example
|
||||
* // Set a new unicode emoji for the role
|
||||
* role.setUnicodeEmoji('🤖')
|
||||
* .then(updated => console.log(`Set unicode emoji for the role to ${updated.unicodeEmoji}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setUnicodeEmoji(unicodeEmoji, reason) {
|
||||
return this.edit({ unicodeEmoji }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used to set position of a role.
|
||||
* @typedef {Object} SetRolePositionOptions
|
||||
@@ -350,6 +393,16 @@ class Role extends Base {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to the role's icon
|
||||
* @param {StaticImageURLOptions} [options={}] Options for the image URL
|
||||
* @returns {?string}
|
||||
*/
|
||||
iconURL({ format, size } = {}) {
|
||||
if (!this.icon) return null;
|
||||
return this.client.rest.cdn.RoleIcon(this.id, this.icon, format, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this role equals another role. It compares all properties, so for most operations
|
||||
* it is advisable to just compare `role.id === role2.id` as it is much faster and is often
|
||||
@@ -366,7 +419,9 @@ class Role extends Base {
|
||||
this.hoist === role.hoist &&
|
||||
this.position === role.position &&
|
||||
this.permissions.bitfield === role.permissions.bitfield &&
|
||||
this.managed === role.managed
|
||||
this.managed === role.managed &&
|
||||
this.icon === role.icon &&
|
||||
this.unicodeEmoji === role.unicodeEmoji
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ exports.Endpoints = {
|
||||
TeamIcon: (teamId, hash, options) => makeImageUrl(`${root}/team-icons/${teamId}/${hash}`, options),
|
||||
Sticker: (stickerId, stickerFormat) =>
|
||||
`${root}/stickers/${stickerId}.${stickerFormat === 'LOTTIE' ? 'json' : 'png'}`,
|
||||
RoleIcon: (roleId, hash, format = 'webp', size) =>
|
||||
makeImageUrl(`${root}/role-icons/${roleId}/${hash}`, { size, format }),
|
||||
};
|
||||
},
|
||||
invite: (root, code) => `${root}/${code}`,
|
||||
|
||||
11
typings/index.d.ts
vendored
11
typings/index.d.ts
vendored
@@ -1647,16 +1647,21 @@ export class Role extends Base {
|
||||
public rawPosition: number;
|
||||
public tags: RoleTagData | null;
|
||||
public comparePositionTo(role: RoleResolvable): number;
|
||||
public icon: string | null;
|
||||
public unicodeEmoji: string | null;
|
||||
public delete(reason?: string): Promise<Role>;
|
||||
public edit(data: RoleData, reason?: string): Promise<Role>;
|
||||
public equals(role: Role): boolean;
|
||||
public iconURL(options?: StaticImageURLOptions): string | null;
|
||||
public permissionsIn(channel: GuildChannel | Snowflake): Readonly<Permissions>;
|
||||
public setColor(color: ColorResolvable, reason?: string): Promise<Role>;
|
||||
public setHoist(hoist?: boolean, reason?: string): Promise<Role>;
|
||||
public setMentionable(mentionable?: boolean, reason?: string): Promise<Role>;
|
||||
public setName(name: string, reason?: string): Promise<Role>;
|
||||
public setPermissions(permissions: PermissionResolvable, reason?: string): Promise<Role>;
|
||||
public setIcon(icon: BufferResolvable | Base64Resolvable | EmojiResolvable | null, reason?: string): Promise<Role>;
|
||||
public setPosition(position: number, options?: SetRolePositionOptions): Promise<Role>;
|
||||
public setUnicodeEmoji(unicodeEmoji: string | null, reason?: string): Promise<Role>;
|
||||
public toJSON(): unknown;
|
||||
public toString(): RoleMention;
|
||||
|
||||
@@ -2362,6 +2367,7 @@ export const Constants: {
|
||||
{ format, size }: { format: AllowedImageFormat; size: AllowedImageSize },
|
||||
) => string;
|
||||
Sticker: (stickerId: Snowflake, stickerFormat: StickerFormatType) => string;
|
||||
RoleIcon: (roleId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize) => string;
|
||||
};
|
||||
};
|
||||
WSCodes: {
|
||||
@@ -4069,7 +4075,8 @@ export type GuildFeatures =
|
||||
| 'MORE_STICKERS'
|
||||
| 'THREE_DAY_THREAD_ARCHIVE'
|
||||
| 'SEVEN_DAY_THREAD_ARCHIVE'
|
||||
| 'PRIVATE_THREADS';
|
||||
| 'PRIVATE_THREADS'
|
||||
| 'ROLE_ICONS';
|
||||
|
||||
export interface GuildMemberEditData {
|
||||
nick?: string | null;
|
||||
@@ -4740,6 +4747,8 @@ export interface RoleData {
|
||||
position?: number;
|
||||
permissions?: PermissionResolvable;
|
||||
mentionable?: boolean;
|
||||
icon?: BufferResolvable | Base64Resolvable | EmojiResolvable | null;
|
||||
unicodeEmoji?: string | null;
|
||||
}
|
||||
|
||||
export type RoleMention = '@everyone' | `<@&${Snowflake}>`;
|
||||
|
||||
Reference in New Issue
Block a user