-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
406 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
packages/discord.js/src/client/actions/MessagePollVoteAdd.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
'use strict'; | ||
|
||
const Action = require('./Action'); | ||
|
||
class MessagePollVoteAddAction extends Action { | ||
handle(data) { | ||
const channel = this.getChannel(data); | ||
if (!channel?.isTextBased()) return false; | ||
|
||
const message = this.getMessage(data, channel); | ||
if (!message) return false; | ||
|
||
const { poll } = message; | ||
|
||
const answer = poll.answers.get(data.answer_id); | ||
if (!answer) { | ||
console.log('???'); | ||
return false; | ||
} | ||
|
||
/** | ||
* Emitted whenever a user votes in a poll. | ||
* @event Client#messagePollVoteAdd | ||
* @param {PollAnswer} answer The answer that was voted on | ||
* @param {Snowflake} userId The id of the user that voted | ||
*/ | ||
this.client.emit('messagePollVoteAdd', answer, data.user_id); | ||
|
||
return { poll }; | ||
} | ||
} | ||
|
||
module.exports = MessagePollVoteAddAction; |
33 changes: 33 additions & 0 deletions
33
packages/discord.js/src/client/actions/MessagePollVoteRemove.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
'use strict'; | ||
|
||
const Action = require('./Action'); | ||
|
||
class MessagePollVoteRemoveAction extends Action { | ||
handle(data) { | ||
const channel = this.getChannel(data); | ||
if (!channel?.isTextBased()) return false; | ||
|
||
const message = this.getMessage(data, channel); | ||
if (!message) return false; | ||
|
||
const { poll } = message; | ||
|
||
const answer = poll.answers.get(data.answer_id); | ||
if (!answer) { | ||
console.log('???'); | ||
return false; | ||
} | ||
|
||
/** | ||
* Emitted whenever a user removes their vote in a poll. | ||
* @event Client#messagePollVoteRemove | ||
* @param {PollAnswer} answer The answer where the vote was removed | ||
* @param {Snowflake} userId The id of the user that removed their vote | ||
*/ | ||
this.client.emit('messagePollVoteRemove', answer, data.user_id); | ||
|
||
return { poll }; | ||
} | ||
} | ||
|
||
module.exports = MessagePollVoteRemoveAction; |
5 changes: 5 additions & 0 deletions
5
packages/discord.js/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use strict'; | ||
|
||
module.exports = (client, packet) => { | ||
client.actions.MessagePollVoteAdd.handle(packet.d); | ||
}; |
5 changes: 5 additions & 0 deletions
5
packages/discord.js/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use strict'; | ||
|
||
module.exports = (client, packet) => { | ||
client.actions.MessagePollVoteRemove.handle(packet.d); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
'use strict'; | ||
|
||
const { Collection } = require('@discordjs/collection'); | ||
const Base = require('./Base'); | ||
const { PollAnswer } = require('./PollAnswer'); | ||
const { PollAnswerResult } = require('./PollAnswerResult'); | ||
const { DiscordjsError } = require('../errors/DJSError'); | ||
const { ErrorCodes } = require('../errors/index'); | ||
|
||
/** | ||
* Represents a Poll | ||
* @extends {Base} | ||
*/ | ||
class Poll extends Base { | ||
constructor(client, data, message) { | ||
super(client); | ||
|
||
/** | ||
* The message that started this poll | ||
* @name Poll#message | ||
* @type {Message} | ||
* @readonly | ||
*/ | ||
|
||
Object.defineProperty(this, 'message', { value: message }); | ||
|
||
this._patch(data); | ||
} | ||
|
||
_patch(data) { | ||
/** | ||
* The question text of this poll | ||
* @type {string} | ||
*/ | ||
this.question = data.question.text; | ||
|
||
/** | ||
* The answers of this poll | ||
* @type {Collection<number, PollAnswer>} | ||
*/ | ||
this.answers = data.answers.reduce( | ||
(acc, answer) => acc.set(answer.answer_id, new PollAnswer(this.client, answer, this)), | ||
new Collection(), | ||
); | ||
|
||
/** | ||
* The timestamp when this poll expires | ||
* @type {number} | ||
*/ | ||
this.expiresTimestamp = Date.parse(data.expiry); | ||
|
||
/** | ||
* Whether this poll allows multiple answers | ||
* @type {boolean} | ||
*/ | ||
this.allowMultiselect = data.allow_multiselect; | ||
|
||
/** | ||
* The layout type of this poll | ||
* @type {PollLayoutType} | ||
*/ | ||
this.layoutType = data.layout_type; | ||
|
||
if (data.results) { | ||
/** | ||
* @typedef {Object} PollResults | ||
* @property {Collection<number, PollAnswerResult>} answerCounts The counts of each answer | ||
* @property {boolean} isFinalized Whether the results are finalized | ||
*/ | ||
|
||
/** | ||
* The results of this poll | ||
* @type {?PollResults} | ||
*/ | ||
this.results = { | ||
answerCounts: data.results.answer_counts.reduce( | ||
(acc, result) => acc.set(result.id, new PollAnswerResult(result)), | ||
new Collection(), | ||
), | ||
isFinalized: data.results.is_finalized, | ||
}; | ||
} else { | ||
this.results = null; | ||
} | ||
} | ||
|
||
/** | ||
* The date when this poll expires | ||
* @type {Date} | ||
* @readonly | ||
*/ | ||
get expiresAt() { | ||
return new Date(this.expiresTimestamp); | ||
} | ||
|
||
/** | ||
* End this poll | ||
* @returns {Promise<Message>} | ||
*/ | ||
async end() { | ||
if (Date.now() > this.expiresTimestamp) { | ||
throw new DiscordjsError(ErrorCodes.PollAlreadyExpired); | ||
} | ||
|
||
const message = await this.client.rest.post(`/channels/${this.message.channel.id}/poll/${this.message.id}/expire`); | ||
|
||
this.message._patch(message); | ||
|
||
return this.message; | ||
} | ||
} | ||
|
||
exports.Poll = Poll; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use strict'; | ||
|
||
const { Collection } = require('@discordjs/collection'); | ||
const { makeURLSearchParams } = require('@discordjs/rest'); | ||
const Base = require('./Base'); | ||
const { Emoji } = require('./Emoji'); | ||
|
||
/** | ||
* Represents an answer to a {@link Poll} | ||
* @extends {Base} | ||
*/ | ||
class PollAnswer extends Base { | ||
constructor(client, data, poll) { | ||
super(client); | ||
|
||
/** | ||
* The {@link Poll} this answer is part of | ||
* @name PollAnswer#poll | ||
* @type {Poll} | ||
* @readonly | ||
*/ | ||
Object.defineProperty(this, 'poll', { value: poll }); | ||
|
||
/** | ||
* The id of this answer | ||
* @type {number} | ||
*/ | ||
this.id = data.answer_id; | ||
|
||
/** | ||
* The text of this answer | ||
* @type {?string} | ||
*/ | ||
this.text = data.poll_media.text ?? null; | ||
|
||
/** | ||
* The raw emoji of this answer | ||
* @name PollAnswer#_emoji | ||
* @type {?APIPartialEmoji} | ||
* @private | ||
*/ | ||
Object.defineProperty(this, '_emoji', { value: data.poll_media.emoji ?? null }); | ||
|
||
this._patch(data); | ||
} | ||
|
||
/** | ||
* The emoji of this answer | ||
* @type {?(GuildEmoji|Emoji)} | ||
*/ | ||
get emoji() { | ||
if (!this._emoji || (!this._emoji.id && !this._emoji.name)) return null; | ||
return this.client.emojis.resolve(this._emoji.id) ?? new Emoji(this.client, this._emoji); | ||
} | ||
|
||
/** | ||
* @typedef {Object} FetchPollVotersOptions | ||
* @property {number} [limit] The maximum number of voters to fetch | ||
* @property {Snowflake} [after] The user id to fetch voters after | ||
*/ | ||
|
||
/** | ||
* Fetches the users that voted for this answer | ||
* @param {FetchPollVotersOptions} [options={}] The options for fetching voters | ||
* @returns {Promise<Collection<Snowflake, User>>} | ||
*/ | ||
async fetchVoters({ after, limit } = {}) { | ||
const voters = await this.client.rest.get( | ||
`/channels/${this.poll.message.channel.id}/polls/${this.poll.message.id}/answers/${this.id}`, | ||
{ query: makeURLSearchParams({ limit, after }) }, | ||
); | ||
return voters.users.reduce((acc, user) => acc.set(user.id, this.client.users._add(user, false)), new Collection()); | ||
} | ||
} | ||
|
||
exports.PollAnswer = PollAnswer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Represents the results of a {@link PollAnswer} | ||
*/ | ||
class PollAnswerResult { | ||
constructor(data) { | ||
/** | ||
* The id of the {@link PollAnswer} this result is for | ||
* @type {number} | ||
*/ | ||
this.id = data.id; | ||
|
||
this._patch(data); | ||
} | ||
|
||
_patch(data) { | ||
/** | ||
* The count of votes for this answer | ||
* @type {number} | ||
*/ | ||
this.count = data.count; | ||
} | ||
} | ||
|
||
exports.PollAnswerResult = PollAnswerResult; |
Oops, something went wrong.