if we don't have our own member yet, fetch it from the server and store
This commit is contained in:
parent
d94aeff98c
commit
be3d734319
4 changed files with 62 additions and 10 deletions
|
@ -189,6 +189,10 @@ export class HomeServerApi {
|
||||||
return this._get(`/rooms/${encodeURIComponent(roomId)}/messages`, params, null, options);
|
return this._get(`/rooms/${encodeURIComponent(roomId)}/messages`, params, null, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
roomState(roomId, eventType, stateKey, options = null) {
|
||||||
|
return this._get(`/rooms/${encodeURIComponent(roomId)}/state/${encodeURIComponent(eventType)}/${encodeURIComponent(stateKey)}`, null, null, options);
|
||||||
|
}
|
||||||
|
|
||||||
// params is at, membership and not_membership
|
// params is at, membership and not_membership
|
||||||
members(roomId, params, options = null) {
|
members(roomId, params, options = null) {
|
||||||
return this._get(`/rooms/${encodeURIComponent(roomId)}/members`, params, null, options);
|
return this._get(`/rooms/${encodeURIComponent(roomId)}/members`, params, null, options);
|
||||||
|
|
|
@ -425,8 +425,13 @@ export class Room extends EventEmitter {
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
sendEvent(eventType, content, attachments, log = null) {
|
sendEvent(eventType, content, attachments, log = null) {
|
||||||
this._platform.logger.wrapOrRun(log, "send", log => {
|
this._platform.logger.wrapOrRun(log, "send", async log => {
|
||||||
log.set("id", this.id);
|
log.set("id", this.id);
|
||||||
|
if (this._timeline) {
|
||||||
|
// ensure we have our own member loaded for the local echo
|
||||||
|
await this._timeline.ensureOwnMember(
|
||||||
|
this._user, this._summary.data.membership, this._hsApi, log);
|
||||||
|
}
|
||||||
return this._sendQueue.enqueueEvent(eventType, content, attachments, log);
|
return this._sendQueue.enqueueEvent(eventType, content, attachments, log);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -678,7 +683,12 @@ export class Room extends EventEmitter {
|
||||||
if (this._roomEncryption) {
|
if (this._roomEncryption) {
|
||||||
this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));
|
this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));
|
||||||
}
|
}
|
||||||
await this._timeline.load(this._user, log);
|
if (this._sendQueue.pendingEvents.length !== 0) {
|
||||||
|
// ensure we have our own member loaded for the local echo
|
||||||
|
await this._timeline.ensureOwnMember(
|
||||||
|
this._user, this._summary.data.membership, this._hsApi, log);
|
||||||
|
}
|
||||||
|
await this._timeline.load(log);
|
||||||
return this._timeline;
|
return this._timeline;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,15 @@ export class RoomMember {
|
||||||
this._data = data;
|
this._data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async fromFetch(roomId, userId, hsApi, log) {
|
||||||
|
const memberEvent = await hsApi.roomState(this._roomId, EVENT_TYPE, userId, {log}).response();
|
||||||
|
return RoomMember.fromMemberEvent(memberEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromUserId(roomId, userId, membership) {
|
||||||
|
return new RoomMember({roomId, userId, membership});
|
||||||
|
}
|
||||||
|
|
||||||
static fromMemberEvent(roomId, memberEvent) {
|
static fromMemberEvent(roomId, memberEvent) {
|
||||||
const userId = memberEvent?.state_key;
|
const userId = memberEvent?.state_key;
|
||||||
if (typeof userId !== "string") {
|
if (typeof userId !== "string") {
|
||||||
|
|
|
@ -45,14 +45,8 @@ export class Timeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @package */
|
/** @package */
|
||||||
async load(user, log) {
|
async load(log) {
|
||||||
const txn = await this._storage.readTxn(this._timelineReader.readTxnStores.concat(this._storage.storeNames.roomMembers));
|
const txn = await this._storage.readTxn(this._timelineReader.readTxnStores);
|
||||||
const memberData = await txn.roomMembers.get(this._roomId, user.id);
|
|
||||||
this._ownMember = new RoomMember(memberData);
|
|
||||||
// it should be fine to not update the local entries,
|
|
||||||
// as they should only populate once the view subscribes to it
|
|
||||||
// if they are populated already, the sender profile would be empty
|
|
||||||
|
|
||||||
// 30 seems to be a good amount to fill the entire screen
|
// 30 seems to be a good amount to fill the entire screen
|
||||||
const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(30, txn, log));
|
const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(30, txn, log));
|
||||||
try {
|
try {
|
||||||
|
@ -63,6 +57,41 @@ export class Timeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async ensureOwnMember(user, myMembership, hsApi, log) {
|
||||||
|
if (this._ownMember) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const txn = await this._storage.readTxn(this._storage.storeNames.roomMembers);
|
||||||
|
const memberData = await txn.roomMembers.get(this._roomId, user.id);
|
||||||
|
if (memberData) {
|
||||||
|
this._ownMember = new RoomMember(memberData);
|
||||||
|
} else {
|
||||||
|
await log.wrap("own member missing", async log => {
|
||||||
|
// important this *never* throws, not even when offline,
|
||||||
|
// as it would prevent enqueueing a message, or opening the timeline
|
||||||
|
try {
|
||||||
|
this._ownMember = await RoomMember.fromFetch(this._roomId, user.id, hsApi, log);
|
||||||
|
const writeTxn = await this._storage.readWriteTxn(this._storage.storeNames.roomMembers);
|
||||||
|
// check we still don't have the member after the fetch (e.g. from sync)
|
||||||
|
// just to make sure we don't overwrite it
|
||||||
|
const memberData = await writeTxn.roomMembers.get(this._roomId, user.id);
|
||||||
|
if(!memberData) {
|
||||||
|
writeTxn.roomMembers.set(this._roomId, this._ownMember.serialize());
|
||||||
|
await writeTxn.complete();
|
||||||
|
} else {
|
||||||
|
this._ownMember = new RoomMember(memberData);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
log.error = err;
|
||||||
|
if (!this._ownMember) {
|
||||||
|
log.set("fallback", true);
|
||||||
|
this._ownMember = RoomMember.fromUserId(this._roomId, user.id, myMembership);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateOwnMember(member) {
|
updateOwnMember(member) {
|
||||||
this._ownMember = member;
|
this._ownMember = member;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue