Make powerLevels observable
Signed-off-by: RMidhunSuresh <rmidhunsuresh@gmail.com>
This commit is contained in:
parent
d1f465e6cc
commit
8a976ef24b
4 changed files with 50 additions and 30 deletions
|
@ -6,8 +6,10 @@ import {Disambiguator} from "./disambiguator.js";
|
|||
export class MemberListViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const powerLevels = options.powerLevelsObservable.get();
|
||||
// We should subscribe to the observable here so that we can resort when pl changes
|
||||
this.memberTileViewModels = this._mapTileViewModels(this._filterJoinedMembers(options.members))
|
||||
.sortValues(createMemberComparator(options.powerLevels));
|
||||
.sortValues(createMemberComparator(powerLevels));
|
||||
this.nameDisambiguator = new Disambiguator();
|
||||
this.mediaRepository = options.mediaRepository;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ export class RightPanelViewModel extends ViewModel {
|
|||
async _getMemberArguments() {
|
||||
const list = await this._room.loadMemberList();
|
||||
const room = this._room;
|
||||
return {members: list.members, powerLevels: room.powerLevels, mediaRepository: room.mediaRepository};
|
||||
const powerLevelsObservable = await this._room.observePowerLevels();
|
||||
return {members: list.members, powerLevelsObservable, mediaRepository: room.mediaRepository};
|
||||
}
|
||||
|
||||
_setupNavigation() {
|
||||
|
|
|
@ -28,6 +28,9 @@ import {EventEntry} from "./timeline/entries/EventEntry.js";
|
|||
import {ObservedEventMap} from "./ObservedEventMap.js";
|
||||
import {DecryptionSource} from "../e2ee/common.js";
|
||||
import {ensureLogItem} from "../../logging/utils.js";
|
||||
import {TimelineReader} from "./timeline/persistence/TimelineReader.js";
|
||||
import {PowerLevels} from "./timeline/PowerLevels.js";
|
||||
import {RetainedObservableValue} from "../../observable/ObservableValue.js";
|
||||
|
||||
const EVENT_ENCRYPTED_TYPE = "m.room.encrypted";
|
||||
|
||||
|
@ -388,8 +391,44 @@ export class BaseRoom extends EventEmitter {
|
|||
return this._summary.data.membership;
|
||||
}
|
||||
|
||||
get powerLevels() {
|
||||
return this._timeline.powerLevels;
|
||||
async loadPowerLevels() {
|
||||
const timelineReader = new TimelineReader({
|
||||
roomId: this._roomId,
|
||||
storage: this._storage,
|
||||
fragmentIdComparer: this._fragmentIdComparer
|
||||
});
|
||||
const txn = await this._storage.readTxn(
|
||||
timelineReader.readTxnStores.concat(this._storage.storeNames.roomMembers, this._storage.storeNames.roomState)
|
||||
);
|
||||
const powerLevelsState = await txn.roomState.get(this._roomId, "m.room.power_levels", "");
|
||||
if (powerLevelsState) {
|
||||
return new PowerLevels({
|
||||
powerLevelEvent: powerLevelsState.event,
|
||||
ownUserId: this._user.id,
|
||||
membership: this.membership
|
||||
});
|
||||
}
|
||||
const createState = await txn.roomState.get(this._roomId, "m.room.create", "");
|
||||
if (createState) {
|
||||
return new PowerLevels({
|
||||
createEvent: createState.event,
|
||||
ownUserId: this._user.id,
|
||||
membership: this.membership
|
||||
});
|
||||
} else {
|
||||
const membership = this.membership;
|
||||
return new PowerLevels({ownUserId: this._user.id, membership});
|
||||
}
|
||||
}
|
||||
|
||||
async observePowerLevels() {
|
||||
let observable = this._powerLevels;
|
||||
if (!observable) {
|
||||
const powerLevels = await this.loadPowerLevels();
|
||||
observable = new RetainedObservableValue(powerLevels, () => { this._powerLevels = null; });
|
||||
this._powerLevels = observable;
|
||||
}
|
||||
return observable;
|
||||
}
|
||||
|
||||
enableSessionBackup(sessionBackup) {
|
||||
|
@ -433,6 +472,7 @@ export class BaseRoom extends EventEmitter {
|
|||
},
|
||||
clock: this._platform.clock,
|
||||
logger: this._platform.logger,
|
||||
powerLevelsObservable: await this.observePowerLevels()
|
||||
});
|
||||
try {
|
||||
if (this._roomEncryption) {
|
||||
|
|
|
@ -21,12 +21,11 @@ import {Direction} from "./Direction.js";
|
|||
import {TimelineReader} from "./persistence/TimelineReader.js";
|
||||
import {PendingEventEntry} from "./entries/PendingEventEntry.js";
|
||||
import {RoomMember} from "../members/RoomMember.js";
|
||||
import {PowerLevels} from "./PowerLevels.js";
|
||||
import {getRelation, ANNOTATION_RELATION_TYPE} from "./relations.js";
|
||||
import {REDACTION_TYPE} from "../common.js";
|
||||
|
||||
export class Timeline {
|
||||
constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock}) {
|
||||
constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock, powerLevelsObservable}) {
|
||||
this._roomId = roomId;
|
||||
this._storage = storage;
|
||||
this._closeCallback = closeCallback;
|
||||
|
@ -44,7 +43,8 @@ export class Timeline {
|
|||
});
|
||||
this._readerRequest = null;
|
||||
this._allEntries = null;
|
||||
this._powerLevels = null;
|
||||
this._powerLevels = powerLevelsObservable.get();
|
||||
this._disposables.track(powerLevelsObservable.subscribe(powerLevels => this._powerLevels = powerLevels));
|
||||
}
|
||||
|
||||
/** @package */
|
||||
|
@ -66,7 +66,6 @@ export class Timeline {
|
|||
// as they should only populate once the view subscribes to it
|
||||
// if they are populated already, the sender profile would be empty
|
||||
|
||||
this._powerLevels = await this._loadPowerLevels(membership, txn);
|
||||
// 30 seems to be a good amount to fill the entire screen
|
||||
const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(30, txn, log));
|
||||
try {
|
||||
|
@ -78,28 +77,6 @@ export class Timeline {
|
|||
// txn should be assumed to have finished here, as decryption will close it.
|
||||
}
|
||||
|
||||
async _loadPowerLevels(membership, txn) {
|
||||
// TODO: update power levels as state is updated
|
||||
const powerLevelsState = await txn.roomState.get(this._roomId, "m.room.power_levels", "");
|
||||
if (powerLevelsState) {
|
||||
return new PowerLevels({
|
||||
powerLevelEvent: powerLevelsState.event,
|
||||
ownUserId: this._ownMember.userId,
|
||||
membership
|
||||
});
|
||||
}
|
||||
const createState = await txn.roomState.get(this._roomId, "m.room.create", "");
|
||||
if (createState) {
|
||||
return new PowerLevels({
|
||||
createEvent: createState.event,
|
||||
ownUserId: this._ownMember.userId,
|
||||
membership
|
||||
});
|
||||
} else {
|
||||
return new PowerLevels({ownUserId: this._ownMember.userId, membership});
|
||||
}
|
||||
}
|
||||
|
||||
_setupEntries(timelineEntries) {
|
||||
this._remoteEntries.setManySorted(timelineEntries);
|
||||
if (this._pendingEvents) {
|
||||
|
|
Reference in a new issue