Merge pull request #240 from vector-im/bwindels/log-open-timeline

Log open timeline, fill gap and clear unread
This commit is contained in:
Bruno Windels 2021-02-24 10:32:11 +00:00 committed by GitHub
commit afc7902324
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 57 deletions

View file

@ -41,12 +41,12 @@ export class RoomViewModel extends ViewModel {
async load() { async load() {
this._room.on("change", this._onRoomChange); this._room.on("change", this._onRoomChange);
try { try {
const timeline = await this._room.openTimeline();
const timelineVM = this.track(new TimelineViewModel(this.childOptions({ const timelineVM = this.track(new TimelineViewModel(this.childOptions({
room: this._room, room: this._room,
timeline: this._room.openTimeline(), timeline,
ownUserId: this._ownUserId, ownUserId: this._ownUserId,
}))); })));
await timelineVM.load();
this._timelineVM = timelineVM; this._timelineVM = timelineVM;
this.emitChange("timelineViewModel"); this.emitChange("timelineViewModel");
} catch (err) { } catch (err) {

View file

@ -40,16 +40,9 @@ export class TimelineViewModel extends ViewModel {
super(options); super(options);
const {room, timeline, ownUserId} = options; const {room, timeline, ownUserId} = options;
this._timeline = this.track(timeline); this._timeline = this.track(timeline);
// once we support sending messages we could do
// timeline.entries.concat(timeline.pendingEvents)
// for an ObservableList that also contains local echos
this._tiles = new TilesCollection(timeline.entries, tilesCreator(this.childOptions({room, ownUserId}))); this._tiles = new TilesCollection(timeline.entries, tilesCreator(this.childOptions({room, ownUserId})));
} }
async load() {
await this._timeline.load();
}
/** /**
* @return {bool} startReached if the start of the timeline was reached * @return {bool} startReached if the start of the timeline was reached
*/ */

View file

@ -408,7 +408,11 @@ export class Room extends EventEmitter {
fillGap(fragmentEntry, amount, log = null) { fillGap(fragmentEntry, amount, log = null) {
// TODO move some/all of this out of Room // TODO move some/all of this out of Room
return this._platform.logger.wrapOrRun(log, "fillGap", async log => { return this._platform.logger.wrapOrRun(log, "fillGap", async log => {
log.set("id", this.id);
log.set("fragment", fragmentEntry.fragmentId);
log.set("dir", fragmentEntry.direction.asApiString());
if (fragmentEntry.edgeReached) { if (fragmentEntry.edgeReached) {
log.set("edgeReached", true);
return; return;
} }
const response = await this._hsApi.messages(this._roomId, { const response = await this._hsApi.messages(this._roomId, {
@ -544,61 +548,67 @@ export class Room extends EventEmitter {
this._emitCollectionChange(this); this._emitCollectionChange(this);
} }
async clearUnread() { async clearUnread(log = null) {
if (this.isUnread || this.notificationCount) { if (this.isUnread || this.notificationCount) {
const txn = this._storage.readWriteTxn([ return await this._platform.logger.wrapOrRun(log, "clearUnread", async log => {
this._storage.storeNames.roomSummary, log.set("id", this.id);
]); const txn = this._storage.readWriteTxn([
let data; this._storage.storeNames.roomSummary,
try { ]);
data = this._summary.writeClearUnread(txn); let data;
} catch (err) { try {
txn.abort(); data = this._summary.writeClearUnread(txn);
throw err; } catch (err) {
} txn.abort();
await txn.complete();
this._summary.applyChanges(data);
this._emitUpdate();
try {
const lastEventId = await this._getLastEventId();
if (lastEventId) {
await this._hsApi.receipt(this._roomId, "m.read", lastEventId);
}
} catch (err) {
// ignore ConnectionError
if (err.name !== "ConnectionError") {
throw err; throw err;
} }
} await txn.complete();
this._summary.applyChanges(data);
this._emitUpdate();
try {
const lastEventId = await this._getLastEventId();
if (lastEventId) {
await this._hsApi.receipt(this._roomId, "m.read", lastEventId);
}
} catch (err) {
// ignore ConnectionError
if (err.name !== "ConnectionError") {
throw err;
}
}
});
} }
} }
/** @public */ /** @public */
openTimeline() { openTimeline(log = null) {
if (this._timeline) { return this._platform.logger.wrapOrRun(log, "open timeline", async log => {
throw new Error("not dealing with load race here for now"); log.set("id", this.id);
} if (this._timeline) {
console.log(`opening the timeline for ${this._roomId}`); throw new Error("not dealing with load race here for now");
this._timeline = new Timeline({ }
roomId: this.id, this._timeline = new Timeline({
storage: this._storage, roomId: this.id,
fragmentIdComparer: this._fragmentIdComparer, storage: this._storage,
pendingEvents: this._sendQueue.pendingEvents, fragmentIdComparer: this._fragmentIdComparer,
closeCallback: () => { pendingEvents: this._sendQueue.pendingEvents,
console.log(`closing the timeline for ${this._roomId}`); closeCallback: () => {
this._timeline = null; this._timeline = null;
if (this._roomEncryption) { if (this._roomEncryption) {
this._roomEncryption.notifyTimelineClosed(); this._roomEncryption.notifyTimelineClosed();
} }
}, },
user: this._user, user: this._user,
clock: this._platform.clock clock: this._platform.clock,
logger: this._platform.logger,
});
if (this._roomEncryption) {
this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));
}
await this._timeline.load();
return this._timeline;
}); });
if (this._roomEncryption) {
this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));
}
return this._timeline;
} }
get mediaRepository() { get mediaRepository() {

View file

@ -52,7 +52,7 @@ export class SettingsView extends TemplateView {
row(vm.i18n`Version`, version), row(vm.i18n`Version`, version),
row(vm.i18n`Storage usage`, vm => `${vm.storageUsage} / ${vm.storageQuota}`), row(vm.i18n`Storage usage`, vm => `${vm.storageUsage} / ${vm.storageQuota}`),
row(vm.i18n`Debug logs`, t.button({onClick: () => vm.exportLogs()}, "Export")), row(vm.i18n`Debug logs`, t.button({onClick: () => vm.exportLogs()}, "Export")),
t.p(["Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages. For more information, review our ", t.p(["Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited, the usernames of other users and the names of files you send. They do not contain messages. For more information, review our ",
t.a({href: "https://element.io/privacy", target: "_blank", rel: "noopener"}, "privacy policy"), "."]), t.a({href: "https://element.io/privacy", target: "_blank", rel: "noopener"}, "privacy policy"), "."]),
]) ])
]); ]);