MessageLogger: show edit history inline, not just the current content
This commit is contained in:
parent
8da18c4f07
commit
c7037387a9
2 changed files with 41 additions and 4 deletions
|
|
@ -20,6 +20,11 @@ const UserStore = findByStoreName("UserStore");
|
||||||
// forever if the plugin gets disabled.
|
// forever if the plugin gets disabled.
|
||||||
export const fakedMessages = new Map<string, string>();
|
export const fakedMessages = new Map<string, string>();
|
||||||
|
|
||||||
|
// Every past content version for a message, oldest first, current content NOT included (rowStyling
|
||||||
|
// appends that itself from the live record). Same id-in-external-map pattern as fakedMessages -
|
||||||
|
// row.message.id survives into the row JSON, a custom property doesn't (confirmed live).
|
||||||
|
export const editHistory = new Map<string, string[]>();
|
||||||
|
|
||||||
function currentUserId(): string | undefined {
|
function currentUserId(): string | undefined {
|
||||||
return UserStore?.getCurrentUser?.()?.id;
|
return UserStore?.getCurrentUser?.()?.id;
|
||||||
}
|
}
|
||||||
|
|
@ -162,6 +167,10 @@ function handleUpdate(event: any): void {
|
||||||
if (!storage.options?.logEdited) return;
|
if (!storage.options?.logEdited) return;
|
||||||
if (ignoredFor(original, true)) return;
|
if (ignoredFor(original, true)) return;
|
||||||
|
|
||||||
|
const history = editHistory.get(updated.id) ?? [];
|
||||||
|
history.push(original.content ?? "");
|
||||||
|
editHistory.set(updated.id, history);
|
||||||
|
|
||||||
addLogEntry(snapshotMessage(original, "edited", newContent, false), limitsFromStorage());
|
addLogEntry(snapshotMessage(original, "edited", newContent, false), limitsFromStorage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,4 +214,5 @@ export function revertFakedMessages(): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fakedMessages.clear();
|
fakedMessages.clear();
|
||||||
|
editHistory.clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,45 @@ import { ReactNative } from "@vendetta/metro/common";
|
||||||
import { after, before } from "@vendetta/patcher";
|
import { after, before } from "@vendetta/patcher";
|
||||||
import { waitFor } from "@shared/lib/waitFor";
|
import { waitFor } from "@shared/lib/waitFor";
|
||||||
import { rawFind, rawFindByName } from "@shared/lib/rawFind";
|
import { rawFind, rawFindByName } from "@shared/lib/rawFind";
|
||||||
import { fakedMessages } from "./fluxIntercept";
|
import { editHistory, fakedMessages } from "./fluxIntercept";
|
||||||
|
|
||||||
const TAG = "[MessageLogger]";
|
const TAG = "[MessageLogger]";
|
||||||
|
|
||||||
|
function textNode(text: string) {
|
||||||
|
return { content: text, type: "text" };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirmed live: message.content in the row JSON is an array of {content, type} rich-text nodes,
|
||||||
|
// not a plain string. Old versions get an inline "(edited)" tag of their own here, stacked above
|
||||||
|
// the current content - the current version keeps Discord's own native "(edited)" tag rather than
|
||||||
|
// getting a second one from here, since that already renders correctly on a genuinely-edited
|
||||||
|
// message with no help needed.
|
||||||
|
function applyEditHistory(message: any) {
|
||||||
|
const history = editHistory.get(message.id);
|
||||||
|
if (!history?.length) return;
|
||||||
|
|
||||||
|
const currentContent: any[] = Array.isArray(message.content) ? message.content : [textNode(String(message.content ?? ""))];
|
||||||
|
const nodes: any[] = [];
|
||||||
|
for (const oldContent of history) {
|
||||||
|
nodes.push(textNode(oldContent || "(empty)"));
|
||||||
|
nodes.push(textNode(" (edited)\n"));
|
||||||
|
}
|
||||||
|
nodes.push(...currentContent);
|
||||||
|
message.content = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
// Confirmed live: whatever builds the row JSON sent across the native bridge only carries known
|
// Confirmed live: whatever builds the row JSON sent across the native bridge only carries known
|
||||||
// schema fields through - a custom property set directly on the MessageRecord (confirmed present
|
// schema fields through - a custom property set directly on the MessageRecord (confirmed present
|
||||||
// there via eval) never survives into row.message here. message.id does survive, though, so
|
// there via eval) never survives into row.message here. message.id does survive, though, so
|
||||||
// checking membership in fluxIntercept's own fakedMessages map (already tracked there for onUnload
|
// checking membership in fluxIntercept's own fakedMessages/editHistory maps (already tracked there
|
||||||
// cleanup) works where a custom flag on the row itself can't.
|
// for onUnload cleanup / log capture) works where a custom flag on the row itself can't.
|
||||||
function handleRow(row: any) {
|
function handleRow(row: any) {
|
||||||
const message = row?.message;
|
const message = row?.message;
|
||||||
if (!message?.id || !fakedMessages.has(message.id)) return;
|
if (!message?.id) return;
|
||||||
|
|
||||||
|
applyEditHistory(message);
|
||||||
|
|
||||||
|
if (!fakedMessages.has(message.id)) return;
|
||||||
|
|
||||||
message.edited = "deleted";
|
message.edited = "deleted";
|
||||||
message.textColor = ReactNative.processColor("#E4404380");
|
message.textColor = ReactNative.processColor("#E4404380");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue