diff --git a/CHANGELOG.md b/CHANGELOG.md index 85d14e3309..7b1342ed34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2714](https://github.com/Pycord-Development/pycord/pull/2714)) - Added the ability to pass a `datetime.time` object to `format_dt` ([#2747](https://github.com/Pycord-Development/pycord/pull/2747)) +- Added `RawMessageUpdateEvent.new_message` - message update events now contain full + message objects ([#2780](https://github.com/Pycord-Development/pycord/pull/2780)) ### Fixed diff --git a/discord/message.py b/discord/message.py index 55a6bfd6b4..e5d629e2a9 100644 --- a/discord/message.py +++ b/discord/message.py @@ -1012,26 +1012,6 @@ def _clear_emoji(self, emoji) -> Reaction | None: del self.reactions[index] return reaction - def _update(self, data): - # In an update scheme, 'author' key has to be handled before 'member' - # otherwise they overwrite each other which is undesirable. - # Since there's no good way to do this we have to iterate over every - # handler rather than iterating over the keys which is a little slower - for key, handler in self._HANDLERS: - try: - value = data[key] - except KeyError: - continue - else: - handler(self, value) - - # clear the cached properties - for attr in self._CACHED_SLOTS: - try: - delattr(self, attr) - except AttributeError: - pass - def _handle_edited_timestamp(self, value: str) -> None: self._edited_timestamp = utils.parse_time(value) diff --git a/discord/raw_models.py b/discord/raw_models.py index 73da688b7f..80cc490705 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -176,15 +176,21 @@ class RawMessageUpdateEvent(_RawReprMixin): cached_message: Optional[:class:`Message`] The cached message, if found in the internal message cache. Represents the message before it is modified by the data in :attr:`RawMessageUpdateEvent.data`. + new_message: Optional[:class:`Message`] + The new message object. Represents the message after it is modified by the data in + :attr:`RawMessageUpdateEvent.data`. + + .. versionadded:: 2.7 """ __slots__ = ("message_id", "channel_id", "guild_id", "data", "cached_message") - def __init__(self, data: MessageUpdateEvent) -> None: + def __init__(self, data: MessageUpdateEvent, new_message: Message) -> None: self.message_id: int = int(data["id"]) self.channel_id: int = int(data["channel_id"]) self.data: MessageUpdateEvent = data self.cached_message: Message | None = None + self.new_message: Message = new_message try: self.guild_id: int | None = int(data["guild_id"]) diff --git a/discord/state.py b/discord/state.py index 52a9cc0989..eb26753c9f 100644 --- a/discord/state.py +++ b/discord/state.py @@ -772,21 +772,19 @@ def parse_message_delete_bulk(self, data) -> None: self._messages.remove(msg) # type: ignore def parse_message_update(self, data) -> None: - raw = RawMessageUpdateEvent(data) - message = self._get_message(raw.message_id) - if message is not None: - older_message = copy.copy(message) - raw.cached_message = older_message - self.dispatch("raw_message_edit", raw) - message._update(data) - # Coerce the `after` parameter to take the new updated Member - # ref: #5999 - older_message.author = message.author - self.dispatch("message_edit", older_message, message) + old_message = self._get_message(raw.message_id) + if old_message is not None: + self._messages.remove(old_message) + channel, _ = self._get_guild_channel(data) + message = Message(channel=channel, data=data, state=self) + self._messages.append(message) + raw = RawMessageUpdateEvent(data, message) + self.dispatch("raw_message_edit", raw) + if old_message is not None: + self.dispatch("message_edit", old_message, message) else: if poll_data := data.get("poll"): self.store_raw_poll(poll_data, raw) - self.dispatch("raw_message_edit", raw) if "components" in data and self._view_store.is_message_tracked(raw.message_id): self._view_store.update_from_message(raw.message_id, data["components"])