Files
discord.js/src/structures/User.js
Gus Caplan ed8fcf651a Centralise message sending logic in one method, remove sendTTSMessage, add client shortcut in RESTMethods (#1031)
* start wip rewrite of sending/editing messages

* pass the build, modify the edit method to fit the new system

* simplify the applyToClass method

* change handling of file options

* add back message splitting

* i couldn't help myself

* add some smart message options

* clean up, add sexy options

* fix indentation

* fix up splitting

* add \b

* add back old methods for hydar happiness

* clean up more

* move code handling to the rest method

* clean up this.rest.client

* Update TextBasedChannel.js

* add docs back for the bad methods

* fix reply in group dms

* srsly gawdl3y

* make code better

* fix changes for gawdl3y

* fix checking

* remove getter

* make code handling more robust

* k

* fix up sendEmbed docs

* stupid

* fix up more docs because aaaaa

* no more pls
2016-12-28 23:58:30 -05:00

278 lines
7.0 KiB
JavaScript

const TextBasedChannel = require('./interface/TextBasedChannel');
const Constants = require('../util/Constants');
const Presence = require('./Presence').Presence;
/**
* Represents a user on Discord.
* @implements {TextBasedChannel}
*/
class User {
constructor(client, data) {
/**
* The Client that created the instance of the the User.
* @name User#client
* @type {Client}
* @readonly
*/
Object.defineProperty(this, 'client', { value: client });
if (data) this.setup(data);
}
setup(data) {
/**
* The ID of the user
* @type {string}
*/
this.id = data.id;
/**
* The username of the user
* @type {string}
*/
this.username = data.username;
/**
* A discriminator based on username for the user
* @type {string}
*/
this.discriminator = data.discriminator;
/**
* The ID of the user's avatar
* @type {string}
*/
this.avatar = data.avatar;
/**
* Whether or not the user is a bot.
* @type {boolean}
*/
this.bot = Boolean(data.bot);
/**
* The ID of the last message sent by the user, if one was sent.
* @type {?string}
*/
this.lastMessageID = null;
}
patch(data) {
for (const prop of ['id', 'username', 'discriminator', 'avatar', 'bot']) {
if (typeof data[prop] !== 'undefined') this[prop] = data[prop];
}
if (data.token) this.client.token = data.token;
}
/**
* The timestamp the user was created at
* @type {number}
* @readonly
*/
get createdTimestamp() {
return (this.id / 4194304) + 1420070400000;
}
/**
* The time the user was created
* @type {Date}
* @readonly
*/
get createdAt() {
return new Date(this.createdTimestamp);
}
/**
* The presence of this user
* @type {Presence}
* @readonly
*/
get presence() {
if (this.client.presences.has(this.id)) return this.client.presences.get(this.id);
for (const guild of this.client.guilds.values()) {
if (guild.presences.has(this.id)) return guild.presences.get(this.id);
}
return new Presence();
}
/**
* A link to the user's avatar (if they have one, otherwise null)
* @type {?string}
* @readonly
*/
get avatarURL() {
if (!this.avatar) return null;
return Constants.Endpoints.avatar(this.id, this.avatar);
}
/**
* A link to the user's default avatar
* @type {string}
* @readonly
*/
get defaultAvatarURL() {
let defaultAvatars = Object.values(Constants.DefaultAvatars);
let defaultAvatar = this.discriminator % defaultAvatars.length;
return Constants.Endpoints.assets(`${defaultAvatars[defaultAvatar]}.png`);
}
/**
* A link to the user's avatar if they have one. Otherwise a link to their default avatar will be returned
* @type {string}
* @readonly
*/
get displayAvatarURL() {
return this.avatarURL || this.defaultAvatarURL;
}
/**
* The note that is set for the user
* <warn>This is only available when using a user account.</warn>
* @type {?string}
* @readonly
*/
get note() {
return this.client.user.notes.get(this.id) || null;
}
/**
* Check whether the user is typing in a channel.
* @param {ChannelResolvable} channel The channel to check in
* @returns {boolean}
*/
typingIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
return channel._typing.has(this.id);
}
/**
* Get the time that the user started typing.
* @param {ChannelResolvable} channel The channel to get the time in
* @returns {?Date}
*/
typingSinceIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
return channel._typing.has(this.id) ? new Date(channel._typing.get(this.id).since) : null;
}
/**
* Get the amount of time the user has been typing in a channel for (in milliseconds), or -1 if they're not typing.
* @param {ChannelResolvable} channel The channel to get the time in
* @returns {number}
*/
typingDurationIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
return channel._typing.has(this.id) ? channel._typing.get(this.id).elapsedTime : -1;
}
/**
* The DM between the client's user and this user
* @type {?DMChannel}
*/
get dmChannel() {
return this.client.channels.filter(c => c.type === 'dm').find(c => c.recipient.id === this.id);
}
/**
* Deletes a DM channel (if one exists) between the client and the user. Resolves with the channel if successful.
* @returns {Promise<DMChannel>}
*/
deleteDM() {
return this.client.rest.methods.deleteChannel(this);
}
/**
* Sends a friend request to the user
* <warn>This is only available when using a user account.</warn>
* @returns {Promise<User>}
*/
addFriend() {
return this.client.rest.methods.addFriend(this);
}
/**
* Removes the user from your friends
* <warn>This is only available when using a user account.</warn>
* @returns {Promise<User>}
*/
removeFriend() {
return this.client.rest.methods.removeFriend(this);
}
/**
* Blocks the user
* <warn>This is only available when using a user account.</warn>
* @returns {Promise<User>}
*/
block() {
return this.client.rest.methods.blockUser(this);
}
/**
* Unblocks the user
* <warn>This is only available when using a user account.</warn>
* @returns {Promise<User>}
*/
unblock() {
return this.client.rest.methods.unblockUser(this);
}
/**
* Get the profile of the user
* <warn>This is only available when using a user account.</warn>
* @returns {Promise<UserProfile>}
*/
fetchProfile() {
return this.client.rest.methods.fetchUserProfile(this);
}
/**
* Sets a note for the user
* <warn>This is only available when using a user account.</warn>
* @param {string} note The note to set for the user
* @returns {Promise<User>}
*/
setNote(note) {
return this.client.rest.methods.setNote(this, note);
}
/**
* Checks if the user is equal to another. It compares username, ID, discriminator, status and the game being played.
* It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties.
* @param {User} user User to compare with
* @returns {boolean}
*/
equals(user) {
let equal = user &&
this.id === user.id &&
this.username === user.username &&
this.discriminator === user.discriminator &&
this.avatar === user.avatar &&
this.bot === Boolean(user.bot);
return equal;
}
/**
* When concatenated with a string, this automatically concatenates the user's mention instead of the User object.
* @returns {string}
* @example
* // logs: Hello from <@123456789>!
* console.log(`Hello from ${user}!`);
*/
toString() {
return `<@${this.id}>`;
}
// These are here only for documentation purposes - they are implemented by TextBasedChannel
send() { return; }
sendMessage() { return; }
sendEmbed() { return; }
sendFile() { return; }
sendCode() { return; }
}
TextBasedChannel.applyToClass(User);
module.exports = User;