Merge pull request #255 from vector-im/bwindels/send-local-echo-profile

Show correct profile for pending messages
This commit is contained in:
Bruno Windels 2021-03-03 13:55:26 +00:00 committed by GitHub
commit f5bba54fd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 14 deletions

View file

@ -313,6 +313,14 @@ export class Room extends EventEmitter {
if (this._memberList) { if (this._memberList) {
this._memberList.afterSync(memberChanges); this._memberList.afterSync(memberChanges);
} }
if (this._timeline) {
for (const [userId, memberChange] of memberChanges.entries()) {
if (userId === this._user.id) {
this._timeline.updateOwnMember(memberChange.member);
break;
}
}
}
} }
let emitChange = false; let emitChange = false;
if (summaryChanges) { if (summaryChanges) {
@ -646,14 +654,13 @@ export class Room extends EventEmitter {
this._roomEncryption.notifyTimelineClosed(); this._roomEncryption.notifyTimelineClosed();
} }
}, },
user: this._user,
clock: this._platform.clock, clock: this._platform.clock,
logger: this._platform.logger, logger: this._platform.logger,
}); });
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(); await this._timeline.load(this._user);
return this._timeline; return this._timeline;
}); });
} }

View file

@ -19,15 +19,17 @@ import {Disposables} from "../../../utils/Disposables.js";
import {Direction} from "./Direction.js"; import {Direction} from "./Direction.js";
import {TimelineReader} from "./persistence/TimelineReader.js"; import {TimelineReader} from "./persistence/TimelineReader.js";
import {PendingEventEntry} from "./entries/PendingEventEntry.js"; import {PendingEventEntry} from "./entries/PendingEventEntry.js";
import {RoomMember} from "../members/RoomMember.js";
export class Timeline { export class Timeline {
constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, user, clock}) { constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock}) {
this._roomId = roomId; this._roomId = roomId;
this._storage = storage; this._storage = storage;
this._closeCallback = closeCallback; this._closeCallback = closeCallback;
this._fragmentIdComparer = fragmentIdComparer; this._fragmentIdComparer = fragmentIdComparer;
this._disposables = new Disposables(); this._disposables = new Disposables();
this._remoteEntries = new SortedArray((a, b) => a.compare(b)); this._remoteEntries = new SortedArray((a, b) => a.compare(b));
this._ownMember = null;
this._timelineReader = new TimelineReader({ this._timelineReader = new TimelineReader({
roomId: this._roomId, roomId: this._roomId,
storage: this._storage, storage: this._storage,
@ -35,7 +37,7 @@ export class Timeline {
}); });
this._readerRequest = null; this._readerRequest = null;
const localEntries = new MappedList(pendingEvents, pe => { const localEntries = new MappedList(pendingEvents, pe => {
return new PendingEventEntry({pendingEvent: pe, user, clock}); return new PendingEventEntry({pendingEvent: pe, member: this._ownMember, clock});
}, (pee, params) => { }, (pee, params) => {
pee.notifyUpdate(params); pee.notifyUpdate(params);
}); });
@ -43,9 +45,16 @@ export class Timeline {
} }
/** @package */ /** @package */
async load() { async load(user) {
const txn = this._storage.readTxn(this._timelineReader.readTxnStores.concat(this._storage.storeNames.roomMembers));
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)); const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(30, txn));
try { try {
const entries = await readerRequest.complete(); const entries = await readerRequest.complete();
this._remoteEntries.setManySorted(entries); this._remoteEntries.setManySorted(entries);
@ -54,6 +63,10 @@ export class Timeline {
} }
} }
updateOwnMember(member) {
this._ownMember = member;
}
replaceEntries(entries) { replaceEntries(entries) {
for (const entry of entries) { for (const entry of entries) {
this._remoteEntries.replace(entry); this._remoteEntries.replace(entry);

View file

@ -17,10 +17,11 @@ limitations under the License.
import {BaseEntry, PENDING_FRAGMENT_ID} from "./BaseEntry.js"; import {BaseEntry, PENDING_FRAGMENT_ID} from "./BaseEntry.js";
export class PendingEventEntry extends BaseEntry { export class PendingEventEntry extends BaseEntry {
constructor({pendingEvent, user, clock}) { constructor({pendingEvent, member, clock}) {
super(null); super(null);
this._pendingEvent = pendingEvent; this._pendingEvent = pendingEvent;
this._user = user; /** @type {RoomMember} */
this._member = member;
this._clock = clock; this._clock = clock;
} }
@ -49,7 +50,15 @@ export class PendingEventEntry extends BaseEntry {
} }
get sender() { get sender() {
return this._user.id; return this._member?.userId;
}
get displayName() {
return this._member?.name;
}
get avatarUrl() {
return this._member?.avatarUrl;
} }
get timestamp() { get timestamp() {

View file

@ -95,7 +95,7 @@ export class TimelineReader {
this._decryptEntries = decryptEntries; this._decryptEntries = decryptEntries;
} }
_openTxn() { get readTxnStores() {
const stores = [ const stores = [
this._storage.storeNames.timelineEvents, this._storage.storeNames.timelineEvents,
this._storage.storeNames.timelineFragments, this._storage.storeNames.timelineFragments,
@ -103,19 +103,19 @@ export class TimelineReader {
if (this._decryptEntries) { if (this._decryptEntries) {
stores.push(this._storage.storeNames.inboundGroupSessions); stores.push(this._storage.storeNames.inboundGroupSessions);
} }
return this._storage.readTxn(stores); return stores;
} }
readFrom(eventKey, direction, amount) { readFrom(eventKey, direction, amount) {
return new ReaderRequest(async r => { return new ReaderRequest(async r => {
const txn = this._openTxn(); const txn = this._storage.readTxn(this.readTxnStores);
return await this._readFrom(eventKey, direction, amount, r, txn); return await this._readFrom(eventKey, direction, amount, r, txn);
}); });
} }
readFromEnd(amount) { readFromEnd(amount, existingTxn = null) {
return new ReaderRequest(async r => { return new ReaderRequest(async r => {
const txn = this._openTxn(); const txn = existingTxn || this._storage.readTxn(this.readTxnStores);
const liveFragment = await txn.timelineFragments.liveFragment(this._roomId); const liveFragment = await txn.timelineFragments.liveFragment(this._roomId);
let entries; let entries;
// room hasn't been synced yet // room hasn't been synced yet