mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat!: Support animated WebP (#10911)
* feat: support animated WebP * refactor: change the rest * fix: remove redundant code
This commit is contained in:
@@ -23,7 +23,7 @@ test('avatar default', () => {
|
||||
});
|
||||
|
||||
test('avatar dynamic-animated', () => {
|
||||
expect(cdn.avatar(id, animatedHash)).toEqual(`${baseCDN}/avatars/${id}/${animatedHash}.gif`);
|
||||
expect(cdn.avatar(id, animatedHash)).toEqual(`${baseCDN}/avatars/${id}/${animatedHash}.webp?animated=true`);
|
||||
});
|
||||
|
||||
test('avatar dynamic-not-animated', () => {
|
||||
@@ -50,28 +50,16 @@ test('discoverySplash default', () => {
|
||||
expect(cdn.discoverySplash(id, hash)).toEqual(`${baseCDN}/discovery-splashes/${id}/${hash}.webp`);
|
||||
});
|
||||
|
||||
test('emoji static', () => {
|
||||
expect(cdn.emoji(id, false)).toEqual(`${baseCDN}/emojis/${id}.webp`);
|
||||
});
|
||||
|
||||
test('emoji static with JPG extension', () => {
|
||||
expect(cdn.emoji(id, false, { extension: 'jpg' })).toEqual(`${baseCDN}/emojis/${id}.jpg`);
|
||||
});
|
||||
|
||||
test('emoji static with JPG extension with force static', () => {
|
||||
expect(cdn.emoji(id, false, { extension: 'jpg', forceStatic: true })).toEqual(`${baseCDN}/emojis/${id}.jpg`);
|
||||
test('emoji', () => {
|
||||
expect(cdn.emoji(id)).toEqual(`${baseCDN}/emojis/${id}.webp`);
|
||||
});
|
||||
|
||||
test('emoji animated', () => {
|
||||
expect(cdn.emoji(id, true)).toEqual(`${baseCDN}/emojis/${id}.gif`);
|
||||
expect(cdn.emoji(id, { animated: true })).toEqual(`${baseCDN}/emojis/${id}.webp?animated=true`);
|
||||
});
|
||||
|
||||
test('emoji animated with JPG extension', () => {
|
||||
expect(cdn.emoji(id, true, { extension: 'jpg' })).toEqual(`${baseCDN}/emojis/${id}.gif`);
|
||||
});
|
||||
|
||||
test('emoji animated with JPG extension with force static', () => {
|
||||
expect(cdn.emoji(id, true, { extension: 'jpg', forceStatic: true })).toEqual(`${baseCDN}/emojis/${id}.jpg`);
|
||||
test('emoji with GIF format', () => {
|
||||
expect(cdn.emoji(id, { extension: 'gif' })).toEqual(`${baseCDN}/emojis/${id}.gif`);
|
||||
});
|
||||
|
||||
test('guildMemberAvatar default', () => {
|
||||
@@ -80,7 +68,7 @@ test('guildMemberAvatar default', () => {
|
||||
|
||||
test('guildMemberAvatar dynamic-animated', () => {
|
||||
expect(cdn.guildMemberAvatar(id, id, animatedHash)).toEqual(
|
||||
`${baseCDN}/guilds/${id}/users/${id}/avatars/${animatedHash}.gif`,
|
||||
`${baseCDN}/guilds/${id}/users/${id}/avatars/${animatedHash}.webp?animated=true`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -94,7 +82,7 @@ test('guildMemberBanner default', () => {
|
||||
|
||||
test('guildMemberBanner dynamic-animated', () => {
|
||||
expect(cdn.guildMemberBanner(id, id, animatedHash)).toEqual(
|
||||
`${baseCDN}/guilds/${id}/users/${id}/banners/${animatedHash}.gif`,
|
||||
`${baseCDN}/guilds/${id}/users/${id}/banners/${animatedHash}.webp?animated=true`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -111,7 +99,7 @@ test('icon default', () => {
|
||||
});
|
||||
|
||||
test('icon dynamic-animated', () => {
|
||||
expect(cdn.icon(id, animatedHash)).toEqual(`${baseCDN}/icons/${id}/${animatedHash}.gif`);
|
||||
expect(cdn.icon(id, animatedHash)).toEqual(`${baseCDN}/icons/${id}/${animatedHash}.webp?animated=true`);
|
||||
});
|
||||
|
||||
test('icon dynamic-not-animated', () => {
|
||||
@@ -157,5 +145,7 @@ test('makeURL throws on invalid extension', () => {
|
||||
});
|
||||
|
||||
test('makeURL valid size', () => {
|
||||
expect(cdn.avatar(id, animatedHash, { size: 512 })).toEqual(`${baseCDN}/avatars/${id}/${animatedHash}.gif?size=512`);
|
||||
expect(cdn.avatar(id, animatedHash, { size: 512 })).toEqual(
|
||||
`${baseCDN}/avatars/${id}/${animatedHash}.webp?animated=true&size=512`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -11,27 +11,44 @@ import {
|
||||
} from './utils/constants.js';
|
||||
|
||||
/**
|
||||
* The options used for image URLs
|
||||
* The options used for image URLs.
|
||||
*/
|
||||
export interface BaseImageURLOptions {
|
||||
/**
|
||||
* The extension to use for the image URL
|
||||
* The extension to use for the image URL.
|
||||
*
|
||||
* @defaultValue `'webp'`
|
||||
*/
|
||||
extension?: ImageExtension;
|
||||
/**
|
||||
* The size specified in the image URL
|
||||
* The size specified in the image URL.
|
||||
*/
|
||||
size?: ImageSize;
|
||||
}
|
||||
|
||||
export interface EmojiURLOptionsWebp extends BaseImageURLOptions {
|
||||
/**
|
||||
* Whether to use the `animated` query parameter.
|
||||
*/
|
||||
animated?: boolean;
|
||||
extension?: 'webp';
|
||||
}
|
||||
|
||||
export interface EmojiURLOptionsNotWebp extends BaseImageURLOptions {
|
||||
extension: Exclude<ImageExtension, 'webp'>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The options used for image URLs with animated content
|
||||
* The options used for emoji URLs.
|
||||
*/
|
||||
export type EmojiURLOptions = EmojiURLOptionsNotWebp | EmojiURLOptionsWebp;
|
||||
|
||||
/**
|
||||
* The options used for image URLs that may be animated.
|
||||
*/
|
||||
export interface ImageURLOptions extends BaseImageURLOptions {
|
||||
/**
|
||||
* Whether or not to prefer the static version of an image asset.
|
||||
* Whether to prefer the static asset.
|
||||
*/
|
||||
forceStatic?: boolean;
|
||||
}
|
||||
@@ -39,11 +56,15 @@ export interface ImageURLOptions extends BaseImageURLOptions {
|
||||
/**
|
||||
* The options to use when making a CDN URL
|
||||
*/
|
||||
export interface MakeURLOptions {
|
||||
interface MakeURLOptions {
|
||||
/**
|
||||
* The allowed extensions that can be used
|
||||
*/
|
||||
allowedExtensions?: readonly string[];
|
||||
/**
|
||||
* Whether to use the `animated` query parameter
|
||||
*/
|
||||
animated?: boolean;
|
||||
/**
|
||||
* The base URL.
|
||||
*
|
||||
@@ -162,11 +183,10 @@ export class CDN {
|
||||
* Generates an emoji's URL.
|
||||
*
|
||||
* @param emojiId - The emoji id
|
||||
* @param animated - Whether the emoji is animated
|
||||
* @param options - Optional options for the emoji
|
||||
*/
|
||||
public emoji(emojiId: string, animated: boolean, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/emojis/${emojiId}`, animated ? 'a_' : '', options);
|
||||
public emoji(emojiId: string, options?: Readonly<EmojiURLOptions>): string {
|
||||
return this.makeURL(`/emojis/${emojiId}`, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,7 +330,7 @@ export class CDN {
|
||||
hash: string,
|
||||
{ forceStatic = false, ...options }: Readonly<ImageURLOptions> = {},
|
||||
): string {
|
||||
return this.makeURL(route, !forceStatic && hash.startsWith('a_') ? { ...options, extension: 'gif' } : options);
|
||||
return this.makeURL(route, !forceStatic && hash.startsWith('a_') ? { ...options, animated: true } : options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,6 +346,7 @@ export class CDN {
|
||||
base = this.cdn,
|
||||
extension = 'webp',
|
||||
size,
|
||||
animated,
|
||||
}: Readonly<MakeURLOptions> = {},
|
||||
): string {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
@@ -341,6 +362,10 @@ export class CDN {
|
||||
|
||||
const url = new URL(`${base}${route}.${extension}`);
|
||||
|
||||
if (animated !== undefined) {
|
||||
url.searchParams.set('animated', String(animated));
|
||||
}
|
||||
|
||||
if (size) {
|
||||
url.searchParams.set('size', String(size));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user