From 4d572670f15d1ce2ffde979eb70714e251d09443 Mon Sep 17 00:00:00 2001 From: Eric <45801973+waresnew@users.noreply.github.com> Date: Tue, 14 May 2024 22:10:29 -0400 Subject: [PATCH] new plugin ValidReply ~ fix "Message could not be loaded" (#2337) Co-authored-by: V --- src/plugins/validReply/README.md | 7 ++ src/plugins/validReply/index.ts | 106 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/plugins/validReply/README.md create mode 100644 src/plugins/validReply/index.ts diff --git a/src/plugins/validReply/README.md b/src/plugins/validReply/README.md new file mode 100644 index 0000000..49e313c --- /dev/null +++ b/src/plugins/validReply/README.md @@ -0,0 +1,7 @@ +# ValidReply + +Fixes referenced (replied to) messages showing as "Message could not be loaded". + +Hover the text to load the message! + +![](https://github.com/Vendicated/Vencord/assets/45801973/d3286acf-e822-4b7f-a4e7-8ced18f581af) diff --git a/src/plugins/validReply/index.ts b/src/plugins/validReply/index.ts new file mode 100644 index 0000000..21a1bdd --- /dev/null +++ b/src/plugins/validReply/index.ts @@ -0,0 +1,106 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; +import { findByPropsLazy } from "@webpack"; +import { FluxDispatcher, RestAPI } from "@webpack/common"; +import { Message, User } from "discord-types/general"; +import { Channel } from "discord-types/general/index.js"; + +const enum ReferencedMessageState { + Loaded, + NotLoaded, + Deleted +} + +interface Reply { + baseAuthor: User, + baseMessage: Message; + channel: Channel; + referencedMessage: { state: ReferencedMessageState; }; + compact: boolean; + isReplyAuthorBlocked: boolean; +} + +const fetching = new Map(); +let ReplyStore: any; + +const { createMessageRecord } = findByPropsLazy("createMessageRecord"); + +export default definePlugin({ + name: "ValidReply", + description: 'Fixes "Message could not be loaded" upon hovering over the reply', + authors: [Devs.newwares], + patches: [ + { + find: "Messages.REPLY_QUOTE_MESSAGE_NOT_LOADED", + replacement: { + match: /Messages\.REPLY_QUOTE_MESSAGE_NOT_LOADED/, + replace: "$&,onMouseEnter:()=>$self.fetchReply(arguments[0])" + } + }, + { + find: "ReferencedMessageStore", + replacement: { + match: /constructor\(\)\{\i\(this,"_channelCaches",new Map\)/, + replace: "$&;$self.setReplyStore(this);" + } + } + ], + + setReplyStore(store: any) { + ReplyStore = store; + }, + + async fetchReply(reply: Reply) { + const { channel_id: channelId, message_id: messageId } = reply.baseMessage.messageReference!; + + if (fetching.has(messageId)) { + return; + } + fetching.set(messageId, channelId); + + RestAPI.get({ + url: `/channels/${channelId}/messages`, + query: { + limit: 1, + around: messageId + }, + retries: 2 + }) + .then(res => { + const reply: Message | undefined = res?.body?.[0]; + if (!reply) return; + + if (reply.id !== messageId) { + ReplyStore.set(channelId, messageId, { + state: ReferencedMessageState.Deleted + }); + + FluxDispatcher.dispatch({ + type: "MESSAGE_DELETE", + channelId: channelId, + message: messageId + }); + } else { + ReplyStore.set(reply.channel_id, reply.id, { + state: ReferencedMessageState.Loaded, + message: createMessageRecord(reply) + }); + + FluxDispatcher.dispatch({ + type: "MESSAGE_UPDATE", + message: reply + }); + } + }) + .catch(() => { }) + .finally(() => { + fetching.delete(messageId); + }); + } +});