import { EventTimelineSet, MatrixEvent } from 'matrix-js-sdk'; import { getEventEdits, trimReplyFromBody } from './room'; import { DiffToken, wordDiff } from './wordDiff'; const isPlainText = (content: Record | undefined): content is { body: string } => !!content && typeof content.body === 'string' && content.format === undefined && content.formatted_body === undefined; /** * [Gitea #144] Word diff of the *last* edit to `mEvent`: the newest edit's body * against the one it replaced (an earlier edit, or the original). Only for * plain-text bodies — formatted edits return `undefined` and the caller falls * back to the history viewer. */ export function getLastEditDiff( mEvent: MatrixEvent, timelineSet: EventTimelineSet, ): DiffToken[] | undefined { const eventId = mEvent.getId(); if (!eventId) return undefined; const relations = getEventEdits(timelineSet, eventId, mEvent.getType()); if (!relations) return undefined; const edits = relations .getRelations() .filter((e) => e.getSender() === mEvent.getSender()) .sort((m1, m2) => m2.getTs() - m1.getTs()); const latest = edits[0]; if (!latest) return undefined; const after = latest.getContent()['m.new_content'] as Record | undefined; const before = (edits[1]?.getContent()['m.new_content'] ?? mEvent.getContent()) as | Record | undefined; if (!isPlainText(after) || !isPlainText(before)) return undefined; return wordDiff(trimReplyFromBody(before.body), trimReplyFromBody(after.body)); }