diff --git a/src/matrix/room/sending/PendingEvent.js b/src/matrix/room/sending/PendingEvent.js index 7738847f..731707e5 100644 --- a/src/matrix/room/sending/PendingEvent.js +++ b/src/matrix/room/sending/PendingEvent.js @@ -16,7 +16,7 @@ limitations under the License. import {createEnum} from "../../../utils/enum.js"; import {AbortError} from "../../../utils/error.js"; import {REDACTION_TYPE} from "../common.js"; -import {getRelationFromContent} from "../timeline/relations.js"; +import {getRelationFromContent, getRelationTarget, setRelationTarget} from "../timeline/relations.js"; export const SendStatus = createEnum( "Waiting", @@ -54,7 +54,7 @@ export class PendingEvent { const relation = getRelationFromContent(this.content); if (relation) { // may be null when target is not sent yet, is intended - return relation.event_id; + return getRelationTarget(relation); } else { return this._data.relatedEventId; } @@ -63,7 +63,7 @@ export class PendingEvent { setRelatedEventId(eventId) { const relation = getRelationFromContent(this.content); if (relation) { - relation.event_id = eventId; + setRelationTarget(relation, eventId); } else { this._data.relatedEventId = eventId; } diff --git a/src/matrix/room/sending/SendQueue.js b/src/matrix/room/sending/SendQueue.js index d6b16ac1..dd562610 100644 --- a/src/matrix/room/sending/SendQueue.js +++ b/src/matrix/room/sending/SendQueue.js @@ -19,7 +19,7 @@ import {ConnectionError} from "../../error.js"; import {PendingEvent, SendStatus} from "./PendingEvent.js"; import {makeTxnId, isTxnId} from "../../common.js"; import {REDACTION_TYPE} from "../common.js"; -import {getRelationFromContent, REACTION_TYPE, ANNOTATION_RELATION_TYPE} from "../timeline/relations.js"; +import {getRelationFromContent, getRelationTarget, setRelationTarget, REACTION_TYPE, ANNOTATION_RELATION_TYPE} from "../timeline/relations.js"; export class SendQueue { constructor({roomId, storage, hsApi, pendingEvents}) { @@ -206,11 +206,13 @@ export class SendQueue { const relation = getRelationFromContent(content); let relatedTxnId = null; if (relation) { - if (isTxnId(relation.event_id)) { - relatedTxnId = relation.event_id; - relation.event_id = null; + const relationTarget = getRelationTarget(relation); + if (isTxnId(relationTarget)) { + relatedTxnId = relationTarget; + setRelationTarget(relation, null); } if (relation.rel_type === ANNOTATION_RELATION_TYPE) { + // Here we know the shape of the relation, and can use event_id safely const isAlreadyAnnotating = this._pendingEvents.array.some(pe => { const r = getRelationFromContent(pe.content); return pe.eventType === eventType && r && r.key === relation.key && diff --git a/src/matrix/room/timeline/persistence/RelationWriter.js b/src/matrix/room/timeline/persistence/RelationWriter.js index b56988be..4944cc64 100644 --- a/src/matrix/room/timeline/persistence/RelationWriter.js +++ b/src/matrix/room/timeline/persistence/RelationWriter.js @@ -30,7 +30,8 @@ export class RelationWriter { const {relatedEventId} = sourceEntry; if (relatedEventId) { const relation = getRelation(sourceEntry.event); - if (relation) { + if (relation && relation.rel_type) { + // we don't consider replies (which aren't relations in the MSC2674 sense) txn.timelineRelations.add(this._roomId, relation.event_id, relation.rel_type, sourceEntry.id); } const target = await txn.timelineEvents.getByEventId(this._roomId, relatedEventId); @@ -120,7 +121,7 @@ export class RelationWriter { log.set("id", redactedEvent.event_id); const relation = getRelation(redactedEvent); - if (relation) { + if (relation && relation.rel_type) { txn.timelineRelations.remove(this._roomId, relation.event_id, relation.rel_type, redactedEvent.event_id); } // check if we're the target of a relation and remove all relations then as well diff --git a/src/matrix/room/timeline/relations.js b/src/matrix/room/timeline/relations.js index 5bf0f490..4009d8c4 100644 --- a/src/matrix/room/timeline/relations.js +++ b/src/matrix/room/timeline/relations.js @@ -29,13 +29,25 @@ export function createAnnotation(targetId, key) { }; } +export function getRelationTarget(relation) { + return relation.event_id || relation["m.in_reply_to"]?.event_id +} + +export function setRelationTarget(relation, target) { + if (relation.event_id !== undefined) { + relation.event_id = target; + } else if (relation["m.in_reply_to"]) { + relation["m.in_reply_to"].event_id = target; + } +} + export function getRelatedEventId(event) { if (event.type === REDACTION_TYPE) { return event.redacts; } else { const relation = getRelation(event); if (relation) { - return relation.event_id; + return getRelationTarget(relation); } } return null;