Plugin
ValidReply
Fixes "Message could not be loaded" upon hovering over the reply
1
import { Devs } from "@utils/constants";2
import definePlugin from "@utils/types";3
import { Channel, Message, User } from "@vencord/discord-types";4
import { findByCodeLazy } from "@webpack";5
import { FluxDispatcher, RestAPI } from "@webpack/common";6
7
const enum ReferencedMessageState {8
Loaded,9
NotLoaded,10
Deleted11
}12
13
interface Reply {14
baseAuthor: User,15
baseMessage: Message;16
channel: Channel;17
referencedMessage: { state: ReferencedMessageState; };18
compact: boolean;19
isReplyAuthorBlocked: boolean;20
}21
22
const fetching = new Map<string, string>();23
let ReplyStore: any;24
25
const createMessageRecord = findByCodeLazy(".createFromServer(", ".isBlockedForMessage", "messageReference:");26
27
export default definePlugin({28
name: "ValidReply",29
description: 039;Fixes "Message could not be loaded" upon hovering over the reply039;,30
tags: ["Chat", "Utility"],31
authors: [Devs.newwares],32
patches: [33
{34
// Same find as in ReplyTimestamp35
find: "#{intl::REPLY_QUOTE_MESSAGE_NOT_LOADED}",36
replacement: {37
match: /#{intl::REPLY_QUOTE_MESSAGE_NOT_LOADED}\)/,38
replace: "$&,onMouseEnter:()=>$self.fetchReply(arguments[0])"39
}40
},41
{42
find: "ReferencedMessageStore",43
replacement: [44
{45
match: /_channelCaches=new Map;/,46
replace: "$&_=$self.setReplyStore(this);"47
}48
]49
}50
],51
52
setReplyStore(store: any) {53
ReplyStore = store;54
},55
56
async fetchReply(reply: Reply) {57
const { channel_id: channelId, message_id: messageId } = reply.baseMessage.messageReference!;58
59
if (fetching.has(messageId)) {60
return;61
}62
fetching.set(messageId, channelId);63
64
RestAPI.get({65
url: `/channels/${channelId}/messages`,66
query: {67
limit: 1,68
around: messageId69
},70
retries: 271
})72
.then(res => {73
const reply: Message | undefined = res?.body?.[0];74
if (!reply) return;75
76
if (reply.id !== messageId) {77
ReplyStore.set(channelId, messageId, {78
state: ReferencedMessageState.Deleted79
});80
81
FluxDispatcher.dispatch({82
type: "MESSAGE_DELETE",83
channelId: channelId,84
message: messageId85
});86
} else {87
ReplyStore.set(reply.channel_id, reply.id, {88
state: ReferencedMessageState.Loaded,89
message: createMessageRecord(reply)90
});91
92
FluxDispatcher.dispatch({93
type: "MESSAGE_UPDATE",94
message: reply95
});96
}97
})98
.catch(() => { })99
.finally(() => {100
fetching.delete(messageId);101
});102
}103
});104