mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-16 11:33:30 +01:00
resolveImage backport (#1822)
* add resolveImage * add groupDMChannel#setIcon + icon getter * doc fix * crawl no kill pls * *whistles* * channe
This commit is contained in:
@@ -174,6 +174,20 @@ class ClientDataResolver {
|
|||||||
return String(data);
|
return String(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image.
|
||||||
|
* @param {string|BufferResolvable|Base64Resolvable} image The image to be resolved
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
resolveImage(image) {
|
||||||
|
if (!image) return Promise.resolve(null);
|
||||||
|
if (typeof image === 'string' && image.startsWith('data:')) {
|
||||||
|
return Promise.resolve(image);
|
||||||
|
}
|
||||||
|
return this.resolveFile(image).then(this.resolveBase64);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data that resolves to give a Base64 string, typically for image uploading. This can be:
|
* Data that resolves to give a Base64 string, typically for image uploading. This can be:
|
||||||
* * A Buffer
|
* * A Buffer
|
||||||
@@ -192,19 +206,25 @@ class ClientDataResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data that can be resolved to give a Buffer. This can be:
|
* Data that can be resolved to give a Buffer. This can be:
|
||||||
* * A Buffer
|
* * A Buffer
|
||||||
* * The path to a local file
|
* * The path to a local file
|
||||||
* * A URL
|
* * A URL
|
||||||
* @typedef {string|Buffer} BufferResolvable
|
* * A Stream
|
||||||
*/
|
* @typedef {string|Buffer} BufferResolvable
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a BufferResolvable to a Buffer.
|
* @external Stream
|
||||||
* @param {BufferResolvable} resource The buffer resolvable to resolve
|
* @see {@link https://nodejs.org/api/stream.html}
|
||||||
* @returns {Promise<Buffer>}
|
*/
|
||||||
*/
|
|
||||||
resolveBuffer(resource) {
|
/**
|
||||||
|
* Resolves a BufferResolvable to a Buffer.
|
||||||
|
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
|
||||||
|
* @returns {Promise<Buffer>}
|
||||||
|
*/
|
||||||
|
resolveFile(resource) {
|
||||||
if (resource instanceof Buffer) return Promise.resolve(resource);
|
if (resource instanceof Buffer) return Promise.resolve(resource);
|
||||||
if (this.client.browser && resource instanceof ArrayBuffer) return Promise.resolve(convertToBuffer(resource));
|
if (this.client.browser && resource instanceof ArrayBuffer) return Promise.resolve(convertToBuffer(resource));
|
||||||
|
|
||||||
@@ -229,38 +249,18 @@ class ClientDataResolver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (resource.pipe && typeof resource.pipe === 'function') {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const buffers = [];
|
||||||
|
resource.once('error', reject);
|
||||||
|
resource.on('data', data => buffers.push(data));
|
||||||
|
resource.once('end', () => resolve(Buffer.concat(buffers)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(new TypeError('The resource must be a string or Buffer.'));
|
return Promise.reject(new TypeError('The resource must be a string or Buffer.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @external Stream
|
|
||||||
* @see {@link https://nodejs.org/api/stream.html}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a Stream to a Buffer.
|
|
||||||
* @param {Stream} resource The stream to convert
|
|
||||||
* @returns {Promise<Buffer>}
|
|
||||||
*/
|
|
||||||
resolveFile(resource) {
|
|
||||||
return resource ? this.resolveBuffer(resource)
|
|
||||||
.catch(() => {
|
|
||||||
if (resource.pipe && typeof resource.pipe === 'function') {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const buffers = [];
|
|
||||||
resource.once('error', reject);
|
|
||||||
resource.on('data', data => buffers.push(data));
|
|
||||||
resource.once('end', () => resolve(Buffer.concat(buffers)));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw new TypeError('The resource must be a string, Buffer or a valid file stream.');
|
|
||||||
}
|
|
||||||
}) :
|
|
||||||
Promise.reject(new TypeError('The resource must be a string, Buffer or a valid file stream.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data that can be resolved to give an emoji identifier. This can be:
|
* Data that can be resolved to give an emoji identifier. This can be:
|
||||||
* * The unicode representation of an emoji
|
* * The unicode representation of an emoji
|
||||||
|
|||||||
@@ -285,6 +285,13 @@ class RESTMethods {
|
|||||||
.then(() => channel);
|
.then(() => channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateGroupDMChannel(channel, _data) {
|
||||||
|
const data = {};
|
||||||
|
data.name = _data.name;
|
||||||
|
data.icon = _data.icon;
|
||||||
|
return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data).then(() => channel);
|
||||||
|
}
|
||||||
|
|
||||||
getExistingDM(recipient) {
|
getExistingDM(recipient) {
|
||||||
return this.client.channels.find(channel =>
|
return this.client.channels.find(channel =>
|
||||||
channel.recipient && channel.recipient.id === recipient.id
|
channel.recipient && channel.recipient.id === recipient.id
|
||||||
|
|||||||
@@ -152,13 +152,9 @@ class ClientUser extends User {
|
|||||||
* .catch(console.error);
|
* .catch(console.error);
|
||||||
*/
|
*/
|
||||||
setAvatar(avatar) {
|
setAvatar(avatar) {
|
||||||
if (typeof avatar === 'string' && avatar.startsWith('data:')) {
|
return this.client.resolver.resolveImage(avatar).then(data =>
|
||||||
return this.client.rest.methods.updateCurrentUser({ avatar });
|
this.client.rest.methods.updateCurrentUser({ avatar: data })
|
||||||
} else {
|
);
|
||||||
return this.client.resolver.resolveBuffer(avatar).then(data =>
|
|
||||||
this.client.rest.methods.updateCurrentUser({ avatar: data })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -337,7 +333,7 @@ class ClientUser extends User {
|
|||||||
}, reject)
|
}, reject)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return this.client.resolver.resolveBuffer(icon)
|
return this.client.resolver.resolveFile(icon)
|
||||||
.then(data => this.createGuild(name, { region, icon: this.client.resolver.resolveBase64(data) || null }));
|
.then(data => this.createGuild(name, { region, icon: this.client.resolver.resolveBase64(data) || null }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const Channel = require('./Channel');
|
const Channel = require('./Channel');
|
||||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||||
const Collection = require('../util/Collection');
|
const Collection = require('../util/Collection');
|
||||||
|
const Constants = require('../util/Constants');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{ type: 3,
|
{ type: 3,
|
||||||
@@ -105,6 +106,23 @@ class GroupDMChannel extends Channel {
|
|||||||
return this.client.users.get(this.ownerID);
|
return this.client.users.get(this.ownerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to this guild's icon
|
||||||
|
* @type {?string}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get iconURL() {
|
||||||
|
if (!this.icon) return null;
|
||||||
|
return Constants.Endpoints.Channel(this).Icon(this.client.options.http.cdn, this.icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
edit(data) {
|
||||||
|
const _data = {};
|
||||||
|
if (data.name) _data.name = data.name;
|
||||||
|
if (data.icon) _data.icon = data.icon;
|
||||||
|
return this.client.rest.methods.updateGroupDMChannel(this, _data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this channel equals another channel. It compares all properties, so for most operations
|
* Whether this channel equals another channel. It compares all properties, so for most operations
|
||||||
* it is advisable to just compare `channel.id === channel2.id` as it is much faster and is often
|
* it is advisable to just compare `channel.id === channel2.id` as it is much faster and is often
|
||||||
@@ -140,6 +158,20 @@ class GroupDMChannel extends Channel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a new GroupDMChannel icon.
|
||||||
|
* @param {Base64Resolvable|BufferResolvable} icon The new icon of the group dm
|
||||||
|
* @returns {Promise<Guild>}
|
||||||
|
* @example
|
||||||
|
* // Edit the group dm icon
|
||||||
|
* channel.setIcon('./icon.png')
|
||||||
|
* .then(updated => console.log('Updated the channel icon'))
|
||||||
|
* .catch(console.error);
|
||||||
|
*/
|
||||||
|
setIcon(icon) {
|
||||||
|
return this.client.resolver.resolveImage(icon).then(data => this.edit({ icon: data }));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When concatenated with a string, this automatically concatenates the channel's name instead of the Channel object.
|
* When concatenated with a string, this automatically concatenates the channel's name instead of the Channel object.
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
|||||||
@@ -615,9 +615,9 @@ class Guild {
|
|||||||
if (data.afkChannel) _data.afk_channel_id = this.client.resolver.resolveChannel(data.afkChannel).id;
|
if (data.afkChannel) _data.afk_channel_id = this.client.resolver.resolveChannel(data.afkChannel).id;
|
||||||
if (data.systemChannel) _data.system_channel_id = this.client.resolver.resolveChannel(data.systemChannel).id;
|
if (data.systemChannel) _data.system_channel_id = this.client.resolver.resolveChannel(data.systemChannel).id;
|
||||||
if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout);
|
if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout);
|
||||||
if (data.icon) _data.icon = this.client.resolver.resolveBase64(data.icon);
|
if (data.icon) _data.icon = data.icon;
|
||||||
if (data.owner) _data.owner_id = this.client.resolver.resolveUser(data.owner).id;
|
if (data.owner) _data.owner_id = this.client.resolver.resolveUser(data.owner).id;
|
||||||
if (data.splash) _data.splash = this.client.resolver.resolveBase64(data.splash);
|
if (data.splash) _data.splash = data.splash;
|
||||||
if (typeof data.explicitContentFilter !== 'undefined') {
|
if (typeof data.explicitContentFilter !== 'undefined') {
|
||||||
_data.explicit_content_filter = Number(data.explicitContentFilter);
|
_data.explicit_content_filter = Number(data.explicitContentFilter);
|
||||||
}
|
}
|
||||||
@@ -627,7 +627,7 @@ class Guild {
|
|||||||
/**
|
/**
|
||||||
* Edit the level of the explicit content filter.
|
* Edit the level of the explicit content filter.
|
||||||
* @param {number} explicitContentFilter The new level of the explicit content filter
|
* @param {number} explicitContentFilter The new level of the explicit content filter
|
||||||
* @param {string} [reason] Reason for changing the level of the guild's explicit content filter
|
* @param {string} [reason] Reason for changing the level of the guild's explicit content filter
|
||||||
* @returns {Promise<Guild>}
|
* @returns {Promise<Guild>}
|
||||||
*/
|
*/
|
||||||
setExplicitContentFilter(explicitContentFilter, reason) {
|
setExplicitContentFilter(explicitContentFilter, reason) {
|
||||||
@@ -637,7 +637,7 @@ class Guild {
|
|||||||
/**
|
/**
|
||||||
* Edit the name of the guild.
|
* Edit the name of the guild.
|
||||||
* @param {string} name The new name of the guild
|
* @param {string} name The new name of the guild
|
||||||
* @param {string} [reason] Reason for changing the guild's name
|
* @param {string} [reason] Reason for changing the guild's name
|
||||||
* @returns {Promise<Guild>}
|
* @returns {Promise<Guild>}
|
||||||
* @example
|
* @example
|
||||||
* // Edit the guild name
|
* // Edit the guild name
|
||||||
@@ -697,7 +697,7 @@ class Guild {
|
|||||||
/**
|
/**
|
||||||
* Edit the system channel of the guild.
|
* Edit the system channel of the guild.
|
||||||
* @param {ChannelResolvable} systemChannel The new system channel
|
* @param {ChannelResolvable} systemChannel The new system channel
|
||||||
* @param {string} [reason] Reason for changing the guild's system channel
|
* @param {string} [reason] Reason for changing the guild's system channel
|
||||||
* @returns {Promise<Guild>}
|
* @returns {Promise<Guild>}
|
||||||
*/
|
*/
|
||||||
setSystemChannel(systemChannel, reason) {
|
setSystemChannel(systemChannel, reason) {
|
||||||
@@ -721,17 +721,17 @@ class Guild {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new guild icon.
|
* Set a new guild icon.
|
||||||
* @param {Base64Resolvable} icon The new icon of the guild
|
* @param {Base64Resolvable|BufferResolvable} icon The new icon of the guild
|
||||||
* @param {string} [reason] Reason for changing the guild's icon
|
* @param {string} [reason] Reason for changing the guild's icon
|
||||||
* @returns {Promise<Guild>}
|
* @returns {Promise<Guild>}
|
||||||
* @example
|
* @example
|
||||||
* // Edit the guild icon
|
* // Edit the guild icon
|
||||||
* guild.setIcon(fs.readFileSync('./icon.png'))
|
* guild.setIcon('./icon.png')
|
||||||
* .then(updated => console.log('Updated the guild icon'))
|
* .then(updated => console.log('Updated the guild icon'))
|
||||||
* .catch(console.error);
|
* .catch(console.error);
|
||||||
*/
|
*/
|
||||||
setIcon(icon, reason) {
|
setIcon(icon, reason) {
|
||||||
return this.edit({ icon }, reason);
|
return this.client.resolver.resolveImage(icon).then(data => this.edit({ icon: data, reason }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -751,17 +751,17 @@ class Guild {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new guild splash screen.
|
* Set a new guild splash screen.
|
||||||
* @param {Base64Resolvable} splash The new splash screen of the guild
|
* @param {BufferResolvable|Base64Resolvable} splash The new splash screen of the guild
|
||||||
* @param {string} [reason] Reason for changing the guild's splash screen
|
* @param {string} [reason] Reason for changing the guild's splash screen
|
||||||
* @returns {Promise<Guild>}
|
* @returns {Promise<Guild>}
|
||||||
* @example
|
* @example
|
||||||
* // Edit the guild splash
|
* // Edit the guild splash
|
||||||
* guild.setIcon(fs.readFileSync('./splash.png'))
|
* guild.setSplash('./splash.png')
|
||||||
* .then(updated => console.log('Updated the guild splash'))
|
* .then(updated => console.log('Updated the guild splash'))
|
||||||
* .catch(console.error);
|
* .catch(console.error);
|
||||||
*/
|
*/
|
||||||
setSplash(splash, reason) {
|
setSplash(splash) {
|
||||||
return this.edit({ splash }, reason);
|
return this.client.resolver.resolveImage(splash).then(data => this.edit({ splash: data }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -952,7 +952,7 @@ class Guild {
|
|||||||
if (typeof attachment === 'string' && attachment.startsWith('data:')) {
|
if (typeof attachment === 'string' && attachment.startsWith('data:')) {
|
||||||
resolve(this.client.rest.methods.createEmoji(this, attachment, name, roles, reason));
|
resolve(this.client.rest.methods.createEmoji(this, attachment, name, roles, reason));
|
||||||
} else {
|
} else {
|
||||||
this.client.resolver.resolveBuffer(attachment).then(data => {
|
this.client.resolver.resolveFile(attachment).then(data => {
|
||||||
const dataURI = this.client.resolver.resolveBase64(data);
|
const dataURI = this.client.resolver.resolveBase64(data);
|
||||||
resolve(this.client.rest.methods.createEmoji(this, dataURI, name, roles, reason));
|
resolve(this.client.rest.methods.createEmoji(this, dataURI, name, roles, reason));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class TextChannel extends GuildChannel {
|
|||||||
if (typeof avatar === 'string' && avatar.startsWith('data:')) {
|
if (typeof avatar === 'string' && avatar.startsWith('data:')) {
|
||||||
resolve(this.client.rest.methods.createWebhook(this, name, avatar, reason));
|
resolve(this.client.rest.methods.createWebhook(this, name, avatar, reason));
|
||||||
} else {
|
} else {
|
||||||
this.client.resolver.resolveBuffer(avatar).then(data =>
|
this.client.resolver.resolveFile(avatar).then(data =>
|
||||||
resolve(this.client.rest.methods.createWebhook(this, name, data, reason))
|
resolve(this.client.rest.methods.createWebhook(this, name, data, reason))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ class Webhook {
|
|||||||
*/
|
*/
|
||||||
edit(name = this.name, avatar) {
|
edit(name = this.name, avatar) {
|
||||||
if (avatar) {
|
if (avatar) {
|
||||||
return this.client.resolver.resolveBuffer(avatar).then(file => {
|
return this.client.resolver.resolveFile(avatar).then(file => {
|
||||||
const dataURI = this.client.resolver.resolveBase64(file);
|
const dataURI = this.client.resolver.resolveBase64(file);
|
||||||
return this.client.rest.methods.editWebhook(this, name, dataURI);
|
return this.client.rest.methods.editWebhook(this, name, dataURI);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ const Endpoints = exports.Endpoints = {
|
|||||||
webhooks: `${base}/webhooks`,
|
webhooks: `${base}/webhooks`,
|
||||||
search: `${base}/messages/search`,
|
search: `${base}/messages/search`,
|
||||||
pins: `${base}/pins`,
|
pins: `${base}/pins`,
|
||||||
|
Icon: (root, hash) => Endpoints.CDN(root).GDMIcon(channelID, hash),
|
||||||
Pin: messageID => `${base}/pins/${messageID}`,
|
Pin: messageID => `${base}/pins/${messageID}`,
|
||||||
Recipient: recipientID => `${base}/recipients/${recipientID}`,
|
Recipient: recipientID => `${base}/recipients/${recipientID}`,
|
||||||
Message: messageID => {
|
Message: messageID => {
|
||||||
@@ -195,6 +196,7 @@ const Endpoints = exports.Endpoints = {
|
|||||||
Asset: name => `${root}/assets/${name}`,
|
Asset: name => `${root}/assets/${name}`,
|
||||||
Avatar: (userID, hash) => `${root}/avatars/${userID}/${hash}.${hash.startsWith('a_') ? 'gif' : 'png'}?size=2048`,
|
Avatar: (userID, hash) => `${root}/avatars/${userID}/${hash}.${hash.startsWith('a_') ? 'gif' : 'png'}?size=2048`,
|
||||||
Icon: (guildID, hash) => `${root}/icons/${guildID}/${hash}.jpg`,
|
Icon: (guildID, hash) => `${root}/icons/${guildID}/${hash}.jpg`,
|
||||||
|
GDMIcon: (channelID, hash) => `${root}/channel-icons/${channelID}/${hash}.jpg?size=2048`,
|
||||||
Splash: (guildID, hash) => `${root}/splashes/${guildID}/${hash}.jpg`,
|
Splash: (guildID, hash) => `${root}/splashes/${guildID}/${hash}.jpg`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user