init
This commit is contained in:
151
node_modules/matrix-js-sdk/lib/models/relations-container.js
generated
vendored
Normal file
151
node_modules/matrix-js-sdk/lib/models/relations-container.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
||||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Relations } from "./relations.js";
|
||||
import { EventStatus, MatrixEventEvent } from "./event.js";
|
||||
import { logger } from "../logger.js";
|
||||
export class RelationsContainer {
|
||||
constructor(client, room) {
|
||||
// A tree of objects to access a set of related children for an event, as in:
|
||||
// this.relations.get(parentEventId).get(relationType).get(relationEventType)
|
||||
_defineProperty(this, "relations", new Map());
|
||||
this.client = client;
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of child events to a given event in this timeline set.
|
||||
*
|
||||
* @param eventId - The ID of the event that you'd like to access child events for.
|
||||
* For example, with annotations, this would be the ID of the event being annotated.
|
||||
* @param relationType - The type of relationship involved, such as "m.annotation", "m.reference", "m.replace", etc.
|
||||
* @param eventType - The relation event's type, such as "m.reaction", etc.
|
||||
* @throws If `eventId</code>, <code>relationType</code> or <code>eventType`
|
||||
* are not valid.
|
||||
*
|
||||
* @returns
|
||||
* A container for relation events or undefined if there are no relation events for
|
||||
* the relationType.
|
||||
*/
|
||||
getChildEventsForEvent(eventId, relationType, eventType) {
|
||||
return this.relations.get(eventId)?.get(relationType)?.get(eventType);
|
||||
}
|
||||
getAllChildEventsForEvent(parentEventId) {
|
||||
const relationsForEvent = this.relations.get(parentEventId) ?? new Map();
|
||||
const events = [];
|
||||
for (const relationsRecord of relationsForEvent.values()) {
|
||||
for (const relations of relationsRecord.values()) {
|
||||
events.push(...relations.getRelations());
|
||||
}
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an event as the target event if any Relations exist for it already.
|
||||
* Child events can point to other child events as their parent, so this method may be
|
||||
* called for events which are also logically child events.
|
||||
*
|
||||
* @param event - The event to check as relation target.
|
||||
*/
|
||||
aggregateParentEvent(event) {
|
||||
const relationsForEvent = this.relations.get(event.getId());
|
||||
if (!relationsForEvent) return;
|
||||
for (const relationsWithRelType of relationsForEvent.values()) {
|
||||
for (const relationsWithEventType of relationsWithRelType.values()) {
|
||||
relationsWithEventType.setTargetEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add relation events to the relevant relation collection.
|
||||
*
|
||||
* @param event - The new child event to be aggregated.
|
||||
* @param timelineSet - The event timeline set within which to search for the related event if any.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a relation event using a known target that is not in the timeline yet.
|
||||
*
|
||||
* @param event - The new child event to be aggregated.
|
||||
* @param timelineSet - The event timeline set within which to search for the related event.
|
||||
* @param targetEvent - The known relation target.
|
||||
* @returns A promise which resolves after aggregation.
|
||||
*/
|
||||
|
||||
aggregateChildEvent(event, timelineSet, targetEvent) {
|
||||
const aggregation = this.aggregateChildEventInternal(event, timelineSet, targetEvent);
|
||||
if (targetEvent) return aggregation;
|
||||
void aggregation.catch(error => logger.error("Failed to aggregate child event: ", error));
|
||||
}
|
||||
aggregateChildEventInternal(event, timelineSet, targetEvent) {
|
||||
if (event.isRedacted() || event.status === EventStatus.CANCELLED) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const relation = event.getRelation();
|
||||
if (!relation) return Promise.resolve();
|
||||
|
||||
// If the event is currently encrypted, wait until it has been decrypted.
|
||||
if (event.isBeingDecrypted() || event.shouldAttemptDecryption()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const onEventDecrypted = () => {
|
||||
if (event.isDecryptionFailure()) {
|
||||
// This could for example happen if the encryption keys are not yet available.
|
||||
// The event may still be decrypted later. Register the listener again.
|
||||
event.once(MatrixEventEvent.Decrypted, onEventDecrypted);
|
||||
return;
|
||||
}
|
||||
void this.aggregateChildEventInternal(event, timelineSet, targetEvent).then(resolve, reject);
|
||||
};
|
||||
event.once(MatrixEventEvent.Decrypted, onEventDecrypted);
|
||||
});
|
||||
}
|
||||
const {
|
||||
event_id: relatesToEventId,
|
||||
rel_type: relationType
|
||||
} = relation;
|
||||
const eventType = event.getType();
|
||||
let relationsForEvent = this.relations.get(relatesToEventId);
|
||||
if (!relationsForEvent) {
|
||||
relationsForEvent = new Map();
|
||||
this.relations.set(relatesToEventId, relationsForEvent);
|
||||
}
|
||||
let relationsWithRelType = relationsForEvent.get(relationType);
|
||||
if (!relationsWithRelType) {
|
||||
relationsWithRelType = new Map();
|
||||
relationsForEvent.set(relationType, relationsWithRelType);
|
||||
}
|
||||
let relationsWithEventType = relationsWithRelType.get(eventType);
|
||||
const isNewRelationCollection = !relationsWithEventType;
|
||||
let targetEventUpdate = Promise.resolve();
|
||||
if (!relationsWithEventType) {
|
||||
relationsWithEventType = new Relations(relationType, eventType, this.client);
|
||||
relationsWithRelType.set(eventType, relationsWithEventType);
|
||||
}
|
||||
if (isNewRelationCollection || targetEvent) {
|
||||
const room = this.room ?? timelineSet?.room;
|
||||
const relatesToEvent = timelineSet?.findEventById(relatesToEventId) ?? room?.findEventById(relatesToEventId) ?? room?.getPendingEvent(relatesToEventId) ?? targetEvent;
|
||||
if (relatesToEvent) {
|
||||
targetEventUpdate = relationsWithEventType.setTargetEvent(relatesToEvent);
|
||||
}
|
||||
}
|
||||
const addEventUpdate = relationsWithEventType.addEvent(event);
|
||||
return Promise.all([targetEventUpdate, addEventUpdate]).then(() => undefined);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=relations-container.js.map
|
||||
Reference in New Issue
Block a user