Fix MessageLoggerEnhanced React child crash from persisted render state (#854)
Co-authored-by: justjxke <Jake0300@protonmai.com>
This commit is contained in:
parent
b7e49fb6d1
commit
5610ba99d0
3 changed files with 24 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ import { DBSchema, IDBPDatabase, openDB } from "idb";
|
||||||
|
|
||||||
import { LoggedMessageJSON } from "./types";
|
import { LoggedMessageJSON } from "./types";
|
||||||
import { getMessageStatus } from "./utils";
|
import { getMessageStatus } from "./utils";
|
||||||
|
import { stripTransientRenderState } from "./utils/cleanUp";
|
||||||
import { DB_NAME, DB_VERSION } from "./utils/constants";
|
import { DB_NAME, DB_VERSION } from "./utils/constants";
|
||||||
import { getAttachmentBlobUrl } from "./utils/saveImage";
|
import { getAttachmentBlobUrl } from "./utils/saveImage";
|
||||||
|
|
||||||
|
|
@ -61,6 +62,7 @@ async function cacheRecords(records: DBMessageRecord[]) {
|
||||||
async function cacheRecord(record?: DBMessageRecord | null) {
|
async function cacheRecord(record?: DBMessageRecord | null) {
|
||||||
if (!record) return record;
|
if (!record) return record;
|
||||||
|
|
||||||
|
stripTransientRenderState(record.message);
|
||||||
cachedMessages.set(record.message_id, record.message);
|
cachedMessages.set(record.message_id, record.message);
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
@ -207,6 +209,8 @@ export async function getMessagesByChannelAndAfterTimestampIDB(channel_id: strin
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addMessageIDB(message: LoggedMessageJSON, status: DBMessageStatus) {
|
export async function addMessageIDB(message: LoggedMessageJSON, status: DBMessageStatus) {
|
||||||
|
stripTransientRenderState(message);
|
||||||
|
|
||||||
await db.put("messages", {
|
await db.put("messages", {
|
||||||
channel_id: message.channel_id,
|
channel_id: message.channel_id,
|
||||||
message_id: message.id,
|
message_id: message.id,
|
||||||
|
|
@ -218,6 +222,8 @@ export async function addMessageIDB(message: LoggedMessageJSON, status: DBMessag
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addMessagesBulkIDB(messages: LoggedMessageJSON[], status?: DBMessageStatus) {
|
export async function addMessagesBulkIDB(messages: LoggedMessageJSON[], status?: DBMessageStatus) {
|
||||||
|
messages.forEach(stripTransientRenderState);
|
||||||
|
|
||||||
const tx = db.transaction("messages", "readwrite");
|
const tx = db.transaction("messages", "readwrite");
|
||||||
const { store } = tx;
|
const { store } = tx;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,11 +189,18 @@ function messageCreateHandler(payload: MessageCreatePayload) {
|
||||||
|
|
||||||
async function processMessageFetch(response: FetchMessagesResponse) {
|
async function processMessageFetch(response: FetchMessagesResponse) {
|
||||||
try {
|
try {
|
||||||
if (!response.ok || response.body.length === 0) {
|
if (!response.ok) {
|
||||||
Flogger.error("Failed to fetch messages", response);
|
Flogger.error("Failed to fetch messages", response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(response.body)) {
|
||||||
|
Flogger.error("Failed to fetch messages: response body is not an array", response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.body.length === 0) return;
|
||||||
|
|
||||||
const firstMessage = response.body[response.body.length - 1];
|
const firstMessage = response.body[response.body.length - 1];
|
||||||
const messages = await idb.getMessagesByChannelAndAfterTimestampIDB(firstMessage.channel_id, firstMessage.timestamp);
|
const messages = await idb.getMessagesByChannelAndAfterTimestampIDB(firstMessage.channel_id, firstMessage.timestamp);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,18 @@ import { MessageStore } from "@webpack/common";
|
||||||
import { LoggedMessageJSON, RefrencedMessage } from "../types";
|
import { LoggedMessageJSON, RefrencedMessage } from "../types";
|
||||||
import { getGuildIdByChannel, isGhostPinged } from "./index";
|
import { getGuildIdByChannel, isGhostPinged } from "./index";
|
||||||
|
|
||||||
|
export function stripTransientRenderState(message: any) {
|
||||||
|
// These runtime-only fields can contain React elements and must never be persisted.
|
||||||
|
delete message.customRenderedContent;
|
||||||
|
delete message.__messageloggerDiff;
|
||||||
|
delete message.__messageloggerDiffKey;
|
||||||
|
delete message.__messageloggerAggregated;
|
||||||
|
delete message.__messageloggerLastAppliedKey;
|
||||||
|
}
|
||||||
|
|
||||||
export function cleanupMessage(message: any, removeDetails: boolean = true): LoggedMessageJSON {
|
export function cleanupMessage(message: any, removeDetails: boolean = true): LoggedMessageJSON {
|
||||||
const ret: LoggedMessageJSON = typeof message.toJS === "function" ? JSON.parse(JSON.stringify(message.toJS())) : { ...message };
|
const ret: LoggedMessageJSON = typeof message.toJS === "function" ? JSON.parse(JSON.stringify(message.toJS())) : { ...message };
|
||||||
|
stripTransientRenderState(ret);
|
||||||
if (removeDetails) {
|
if (removeDetails) {
|
||||||
ret.author.phone = undefined;
|
ret.author.phone = undefined;
|
||||||
ret.author.email = undefined;
|
ret.author.email = undefined;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue