This commit is contained in:
RMidhunSuresh 2021-12-06 11:36:45 +05:30
parent 196e3726cb
commit b753507b8d
5 changed files with 60 additions and 5 deletions

View file

@ -254,8 +254,16 @@ export function tests() {
// 2. setup queue & timeline // 2. setup queue & timeline
const queue = new SendQueue({roomId, storage, hsApi: new MockHomeServer().api}); const queue = new SendQueue({roomId, storage, hsApi: new MockHomeServer().api});
const powerLevelsObservable = new ObservableValue(new PowerLevels({ ownUserId: alice, membership: "join" })); const powerLevelsObservable = new ObservableValue(new PowerLevels({ ownUserId: alice, membership: "join" }));
const timeline = new Timeline({roomId, storage, fragmentIdComparer, const timeline = new Timeline({
clock: new MockClock(), pendingEvents: queue.pendingEvents, powerLevelsObservable}); roomId,
storage,
fragmentIdComparer,
clock: new MockClock(),
pendingEvents: queue.pendingEvents,
powerLevelsObservable,
fetchEventFromHomeserver: () => {},
fetchEventFromStorage: () => {}
});
// 3. load the timeline, which will load the message with the reaction // 3. load the timeline, which will load the message with the reaction
await timeline.load(new User(alice), "join", new NullLogItem()); await timeline.load(new User(alice), "join", new NullLogItem());
const tiles = mapMessageEntriesToBaseMessageTile(timeline, queue); const tiles = mapMessageEntriesToBaseMessageTile(timeline, queue);

View file

@ -128,6 +128,10 @@ export class HomeServerApi {
return this._get("/sync", {since, timeout, filter}, undefined, options); return this._get("/sync", {since, timeout, filter}, undefined, options);
} }
event(roomId, eventId) {
return this._get(`/rooms/${encodeURIComponent(roomId)}/event/${encodeURIComponent(eventId)}`);
}
// params is from, dir and optionally to, limit, filter. // params is from, dir and optionally to, limit, filter.
messages(roomId: string, params: Record<string, any>, options?: IRequestOptions): IHomeServerRequest { messages(roomId: string, params: Record<string, any>, options?: IRequestOptions): IHomeServerRequest {
return this._get(`/rooms/${encodeURIComponent(roomId)}/messages`, params, undefined, options); return this._get(`/rooms/${encodeURIComponent(roomId)}/messages`, params, undefined, options);

View file

@ -501,7 +501,9 @@ export class BaseRoom extends EventEmitter {
}, },
clock: this._platform.clock, clock: this._platform.clock,
logger: this._platform.logger, logger: this._platform.logger,
powerLevelsObservable: await this.observePowerLevels() powerLevelsObservable: await this.observePowerLevels(),
fetchEventFromStorage: eventId => this._readEventById(eventId),
fetchEventFromHomeserver: eventId => this._getEventFromHomeserver(eventId)
}); });
try { try {
if (this._roomEncryption) { if (this._roomEncryption) {
@ -559,6 +561,12 @@ export class BaseRoom extends EventEmitter {
} }
} }
async _getEventFromHomeserver(eventId) {
const response = await this._hsApi.event(this._roomId, eventId).response();
const entry = new EventEntry({ event: response }, this._fragmentIdComparer);
return entry;
}
dispose() { dispose() {
this._roomEncryption?.dispose(); this._roomEncryption?.dispose();

View file

@ -25,8 +25,10 @@ import {getRelation, ANNOTATION_RELATION_TYPE} from "./relations.js";
import {REDACTION_TYPE} from "../common.js"; import {REDACTION_TYPE} from "../common.js";
export class Timeline { export class Timeline {
constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock, powerLevelsObservable}) { constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock, powerLevelsObservable, fetchEventFromStorage, fetchEventFromHomeserver}) {
this._roomId = roomId; this._roomId = roomId;
this._fetchEventFromStorage = fetchEventFromStorage;
this._fetchEventFromHomeserver = fetchEventFromHomeserver;
this._storage = storage; this._storage = storage;
this._closeCallback = closeCallback; this._closeCallback = closeCallback;
this._fragmentIdComparer = fragmentIdComparer; this._fragmentIdComparer = fragmentIdComparer;
@ -78,6 +80,7 @@ export class Timeline {
const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(20, txn, log)); const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(20, txn, log));
try { try {
const entries = await readerRequest.complete(); const entries = await readerRequest.complete();
await this._loadRelatedEvents(entries);
this._setupEntries(entries); this._setupEntries(entries);
} finally { } finally {
this._disposables.disposeTracked(readerRequest); this._disposables.disposeTracked(readerRequest);
@ -211,8 +214,9 @@ export class Timeline {
} }
/** @package */ /** @package */
replaceEntries(entries) { replaceEntries(entries) {
this._addLocalRelationsToNewRemoteEntries(entries); this._addLocalRelationsToNewRemoteEntries(entries);
this._loadRelatedEvents(entries);
for (const entry of entries) { for (const entry of entries) {
try { try {
this._remoteEntries.getAndUpdate(entry, Timeline._entryUpdater); this._remoteEntries.getAndUpdate(entry, Timeline._entryUpdater);
@ -236,8 +240,30 @@ export class Timeline {
/** @package */ /** @package */
addEntries(newEntries) { addEntries(newEntries) {
this._addLocalRelationsToNewRemoteEntries(newEntries); this._addLocalRelationsToNewRemoteEntries(newEntries);
this._loadRelatedEvents(newEntries);
this._remoteEntries.setManySorted(newEntries); this._remoteEntries.setManySorted(newEntries);
} }
async _loadRelatedEvents(entries) {
const filteredEntries = entries.filter(e => !!e.relation);
for (const entry of filteredEntries) {
const id = entry.relatedEventId;
let relatedEvent;
// find in remote events
relatedEvent = this.getByEventId(id);
// find in storage
if (!relatedEvent) {
relatedEvent = await this._fetchEventFromStorage(id);
}
// fetch from hs
if (!relatedEvent) {
relatedEvent = await this._fetchEventFromHomeserver(id);
}
if (relatedEvent) {
entry.setRelatedEntry(relatedEvent);
}
}
}
// tries to prepend `amount` entries to the `entries` list. // tries to prepend `amount` entries to the `entries` list.
/** /**

View file

@ -24,6 +24,7 @@ export class EventEntry extends BaseEventEntry {
this._eventEntry = eventEntry; this._eventEntry = eventEntry;
this._decryptionError = null; this._decryptionError = null;
this._decryptionResult = null; this._decryptionResult = null;
this._relatedEntry = null;
} }
clone() { clone() {
@ -41,6 +42,10 @@ export class EventEntry extends BaseEventEntry {
} }
} }
setRelatedEntry(entry) {
this._relatedEntry = entry;
}
get event() { get event() {
return this._eventEntry.event; return this._eventEntry.event;
} }
@ -122,6 +127,10 @@ export class EventEntry extends BaseEventEntry {
return getRelatedEventId(this.event); return getRelatedEventId(this.event);
} }
get relatedEntry() {
return this._relatedEntry;
}
get isRedacted() { get isRedacted() {
return super.isRedacted || isRedacted(this._eventEntry.event); return super.isRedacted || isRedacted(this._eventEntry.event);
} }