Skip to content

Commit cafe58b

Browse files
authored
feat: Support animated WebP (#10987)
* feat: Support animated WebP (#10911) * feat: support animated WebP * refactor: change the rest * fix: remove redundant code * fix(CDN): Export `MakeURLOptions`
1 parent 7eca844 commit cafe58b

File tree

6 files changed

+52
-13
lines changed

6 files changed

+52
-13
lines changed

packages/discord.js/src/client/Client.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,11 @@ module.exports = Client;
638638
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
639639
*/
640640

641+
/**
642+
* @external EmojiURLOptions
643+
* @see {@link https://discord.js.org/docs/packages/rest/stable/EmojiURLOptions:TypeAlias}
644+
*/
645+
641646
/**
642647
* @external BaseImageURLOptions
643648
* @see {@link https://discord.js.org/docs/packages/rest/stable/BaseImageURLOptions:Interface}

packages/discord.js/src/structures/BaseGuildEmoji.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class BaseGuildEmoji extends Emoji {
5858
* @method imageURL
5959
* @memberof BaseGuildEmoji
6060
* @instance
61-
* @param {BaseImageURLOptions} [options] Options for the image URL
61+
* @param {EmojiURLOptions} [options] Options for the emoji URL
6262
* @returns {string}
6363
*/
6464

packages/discord.js/src/structures/Emoji.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Emoji extends Base {
4545

4646
/**
4747
* Returns a URL for the emoji or `null` if this is not a custom emoji.
48-
* @param {BaseImageURLOptions} [options] Options for the image URL
48+
* @param {EmojiURLOptions} [options] Options for the emoji URL
4949
* @returns {?string}
5050
*/
5151
imageURL(options) {

packages/discord.js/typings/index.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
} from '@discordjs/formatters';
3838
import { Awaitable, JSONEncodable } from '@discordjs/util';
3939
import { Collection, ReadonlyCollection } from '@discordjs/collection';
40-
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
40+
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions, EmojiURLOptions } from '@discordjs/rest';
4141
import {
4242
WebSocketManager as WSWebSocketManager,
4343
IShardingStrategy,
@@ -697,7 +697,7 @@ export abstract class BaseGuild extends Base {
697697

698698
export class BaseGuildEmoji extends Emoji {
699699
protected constructor(client: Client<true>, data: RawGuildEmojiData, guild: Guild | GuildPreview);
700-
public imageURL(options?: BaseImageURLOptions): string;
700+
public imageURL(options?: EmojiURLOptions): string;
701701
public get url(): string;
702702
public available: boolean | null;
703703
public get createdAt(): Date;
@@ -1492,7 +1492,7 @@ export class Emoji extends Base {
14921492
public id: Snowflake | null;
14931493
public name: string | null;
14941494
public get identifier(): string;
1495-
public imageURL(options?: BaseImageURLOptions): string | null;
1495+
public imageURL(options?: EmojiURLOptions): string | null;
14961496
public get url(): string | null;
14971497
public toJSON(): unknown;
14981498
public toString(): string;

packages/rest/__tests__/CDN.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,22 @@ test('discoverySplash default', () => {
5454
expect(cdn.discoverySplash(id, hash)).toEqual(`${baseCDN}/discovery-splashes/${id}/${hash}.webp`);
5555
});
5656

57-
test('emoji default', () => {
57+
test('emoji', () => {
5858
expect(cdn.emoji(id)).toEqual(`${baseCDN}/emojis/${id}.webp`);
5959
});
6060

6161
test('emoji gif', () => {
6262
expect(cdn.emoji(id, 'gif')).toEqual(`${baseCDN}/emojis/${id}.gif`);
6363
});
6464

65+
test('emoji animated', () => {
66+
expect(cdn.emoji(id, { animated: true })).toEqual(`${baseCDN}/emojis/${id}.webp?animated=true`);
67+
});
68+
69+
test('emoji with GIF format', () => {
70+
expect(cdn.emoji(id, { extension: 'gif' })).toEqual(`${baseCDN}/emojis/${id}.gif`);
71+
});
72+
6573
test('guildMemberAvatar default', () => {
6674
expect(cdn.guildMemberAvatar(id, id, hash)).toEqual(`${baseCDN}/guilds/${id}/users/${id}/avatars/${hash}.webp`);
6775
});

packages/rest/src/lib/CDN.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,44 @@ import { deprecationWarning } from './utils/utils.js';
1414
let deprecationEmittedForEmoji = false;
1515

1616
/**
17-
* The options used for image URLs
17+
* The options used for image URLs.
1818
*/
1919
export interface BaseImageURLOptions {
2020
/**
21-
* The extension to use for the image URL
21+
* The extension to use for the image URL.
2222
*
2323
* @defaultValue `'webp'`
2424
*/
2525
extension?: ImageExtension;
2626
/**
27-
* The size specified in the image URL
27+
* The size specified in the image URL.
2828
*/
2929
size?: ImageSize;
3030
}
3131

32+
export interface EmojiURLOptionsWebp extends BaseImageURLOptions {
33+
/**
34+
* Whether to use the `animated` query parameter.
35+
*/
36+
animated?: boolean;
37+
extension?: 'webp';
38+
}
39+
40+
export interface EmojiURLOptionsNotWebp extends BaseImageURLOptions {
41+
extension: Exclude<ImageExtension, 'webp'>;
42+
}
43+
3244
/**
33-
* The options used for image URLs with animated content
45+
* The options used for emoji URLs.
46+
*/
47+
export type EmojiURLOptions = EmojiURLOptionsNotWebp | EmojiURLOptionsWebp;
48+
49+
/**
50+
* The options used for image URLs that may be animated.
3451
*/
3552
export interface ImageURLOptions extends BaseImageURLOptions {
3653
/**
37-
* Whether or not to prefer the static version of an image asset.
54+
* Whether to prefer the static asset.
3855
*/
3956
forceStatic?: boolean;
4057
}
@@ -47,6 +64,10 @@ export interface MakeURLOptions {
4764
* The allowed extensions that can be used
4865
*/
4966
allowedExtensions?: readonly string[];
67+
/**
68+
* Whether to use the `animated` query parameter
69+
*/
70+
animated?: boolean;
5071
/**
5172
* The base URL.
5273
*
@@ -192,7 +213,7 @@ export class CDN {
192213
* @param emojiId - The emoji id
193214
* @param options - Optional options for the emoji
194215
*/
195-
public emoji(emojiId: string, options?: Readonly<BaseImageURLOptions>): string;
216+
public emoji(emojiId: string, options?: Readonly<EmojiURLOptions>): string;
196217

197218
/**
198219
* Generates an emoji's URL for an emoji.
@@ -204,7 +225,7 @@ export class CDN {
204225
// eslint-disable-next-line @typescript-eslint/unified-signatures
205226
public emoji(emojiId: string, extension?: ImageExtension): string;
206227

207-
public emoji(emojiId: string, options?: ImageExtension | Readonly<BaseImageURLOptions>): string {
228+
public emoji(emojiId: string, options?: ImageExtension | Readonly<EmojiURLOptions>): string {
208229
let resolvedOptions;
209230

210231
if (typeof options === 'string') {
@@ -381,6 +402,7 @@ export class CDN {
381402
base = this.cdn,
382403
extension = 'webp',
383404
size,
405+
animated,
384406
}: Readonly<MakeURLOptions> = {},
385407
): string {
386408
// eslint-disable-next-line no-param-reassign
@@ -396,6 +418,10 @@ export class CDN {
396418

397419
const url = new URL(`${base}${route}.${extension}`);
398420

421+
if (animated !== undefined) {
422+
url.searchParams.set('animated', String(animated));
423+
}
424+
399425
if (size) {
400426
url.searchParams.set('size', String(size));
401427
}

0 commit comments

Comments
 (0)