diff --git a/TODO.md b/TODO.md index 090d3ebe0..e11806d5d 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,7 @@ - [ ] sending files - [ ] updating user details - [x] deleting messages -- [ ] updating messages +- [x] updating messages - [ ] leaving guilds - [ ] deleting guilds - [ ] _joining guilds_ diff --git a/src/client/actions/ActionsManager.js b/src/client/actions/ActionsManager.js index aef572bc4..0bfc0cc47 100644 --- a/src/client/actions/ActionsManager.js +++ b/src/client/actions/ActionsManager.js @@ -8,6 +8,7 @@ class ActionsManager { this.register('MessageCreate'); this.register('MessageDelete'); + this.register('MessageUpdate'); } register(name) { diff --git a/src/client/actions/MessageUpdate.js b/src/client/actions/MessageUpdate.js new file mode 100644 index 000000000..13b414fe4 --- /dev/null +++ b/src/client/actions/MessageUpdate.js @@ -0,0 +1,38 @@ +'use strict'; + +const Action = require('./Action'); +const Constants = require('../../util/Constants'); +const CloneObject = require('../../util/CloneObject'); +const Message = require('../../structures/Message'); + +class MessageUpdateAction extends Action { + + constructor(client) { + super(client); + } + + handle(data) { + + let client = this.client; + let channel = client.store.get('channels', data.channel_id); + + if (channel) { + let message = channel.store.get('messages', data.id); + if (message && !message.equals(data, true)) { + let oldMessage = CloneObject(message); + message.patch(data); + return { + old: oldMessage, + updated: message, + }; + } + } + + return { + old: null, + updated: null, + }; + } +}; + +module.exports = MessageUpdateAction; diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 9d2093fa9..827861073 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -60,6 +60,18 @@ class RESTMethods{ .catch(reject); }); } + + UpdateMessage(message, content) { + return new Promise((resolve, reject) => { + this.rest.makeRequest('patch', Constants.Endpoints.CHANNEL_MESSAGE(message.channel.id, message.id), true, { + content, + }) + .then(data => { + resolve(this.rest.client.actions.MessageUpdate.handle(data).updated); + }) + .catch(reject); + }); + } } module.exports = RESTMethods; diff --git a/src/client/websocket/packets/handlers/MessageUpdate.js b/src/client/websocket/packets/handlers/MessageUpdate.js index e6daf2bbc..cf3232249 100644 --- a/src/client/websocket/packets/handlers/MessageUpdate.js +++ b/src/client/websocket/packets/handlers/MessageUpdate.js @@ -17,15 +17,11 @@ class MessageUpdateHandler extends AbstractHandler { handle(packet) { let data = packet.d; let client = this.packetManager.client; - let channel = client.store.get('channels', data.channel_id); - if (channel) { - let message = channel.store.get('messages', data.id); - if (message) { - let oldMessage = CloneObject(message); - message.patch(data); - client.emit(Constants.Events.MESSAGE_UPDATE, oldMessage, message); - } + let response = client.actions.MessageUpdate.handle(data); + + if (response.old) { + client.emit(Constants.Events.MESSAGE_UPDATE, response.old, response.updated); } } diff --git a/src/structures/Message.js b/src/structures/Message.js index 826ef049e..d5118ca70 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -72,9 +72,40 @@ class Message { this.id = data.id; } + equals(message, rawData) { + + let embedUpdate = !message.author && !message.attachments; + + if (embedUpdate) { + let base = this.id === message.id && + this.embeds.length === message.embeds.length; + return base; + } else { + let base = this.id === message.id && + this.author.id === message.author.id && + this.content === message.content && + this.tts === message.tts && + this.nonce === message.nonce && + this.embeds.length === message.embeds.length && + this.attachments.length === message.attachments.length; + + if (base && rawData) { + base = this.mentionEveryone === message.mentionEveryone && + this.timestamp.getTime() === new Date(data.timestamp).getTime() && + this.editedTimestamp === new Date(data.edited_timestamp).getTime(); + } + + return base; + } + } + delete() { return this.client.rest.methods.DeleteMessage(this); } + + edit(content) { + return this.client.rest.methods.UpdateMessage(this, content); + } } module.exports = Message; diff --git a/test/random.js b/test/random.js index f38301d9b..915185a7e 100644 --- a/test/random.js +++ b/test/random.js @@ -71,7 +71,7 @@ client.on('typingStop.', (channel, user, data) => { client.on('message', message => { if (message.author.username === 'hydrabolt') { message.channel.sendMessage('test').then(msg => { - msg.delete().catch(console.log); + msg.edit('woah!'); }); } });