Only display rooms in the sliding window
Buggy: some rooms disappear entirely for some reason.
This commit is contained in:
parent
4f7468a95a
commit
0b2d09b796
5 changed files with 60 additions and 5 deletions
|
@ -41,6 +41,7 @@ export class SessionViewModel extends ViewModel {
|
||||||
invites: this._sessionContainer.session.invites,
|
invites: this._sessionContainer.session.invites,
|
||||||
rooms: this._sessionContainer.session.rooms,
|
rooms: this._sessionContainer.session.rooms,
|
||||||
compareFn: this._sessionContainer.sync.compare.bind(this._sessionContainer.sync),
|
compareFn: this._sessionContainer.sync.compare.bind(this._sessionContainer.sync),
|
||||||
|
includeRoomFn: this._sessionContainer.sync.includeRoom.bind(this._sessionContainer.sync),
|
||||||
})));
|
})));
|
||||||
this._settingsViewModel = null;
|
this._settingsViewModel = null;
|
||||||
this._roomViewModelObservable = null;
|
this._roomViewModelObservable = null;
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {ViewModel} from "../../ViewModel.js";
|
||||||
import {RoomTileViewModel} from "./RoomTileViewModel.js";
|
import {RoomTileViewModel} from "./RoomTileViewModel.js";
|
||||||
import {InviteTileViewModel} from "./InviteTileViewModel.js";
|
import {InviteTileViewModel} from "./InviteTileViewModel.js";
|
||||||
import {RoomFilter} from "./RoomFilter.js";
|
import {RoomFilter} from "./RoomFilter.js";
|
||||||
|
import {FilteredMap} from "../../../observable/map/FilteredMap.js";
|
||||||
import {ApplyMap} from "../../../observable/map/ApplyMap.js";
|
import {ApplyMap} from "../../../observable/map/ApplyMap.js";
|
||||||
import {addPanelIfNeeded} from "../../navigation/index.js";
|
import {addPanelIfNeeded} from "../../navigation/index.js";
|
||||||
import { PlaceholderRoomTileViewModel } from "./PlaceholderRoomTileViewModel.js";
|
import { PlaceholderRoomTileViewModel } from "./PlaceholderRoomTileViewModel.js";
|
||||||
|
@ -26,9 +27,13 @@ import { PlaceholderRoomTileViewModel } from "./PlaceholderRoomTileViewModel.js"
|
||||||
export class LeftPanelViewModel extends ViewModel {
|
export class LeftPanelViewModel extends ViewModel {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
const {rooms, invites, compareFn} = options;
|
const {rooms, invites, compareFn, includeRoomFn} = options;
|
||||||
this._tileViewModelsMap = this._mapTileViewModels(rooms, invites);
|
this._tileViewModelsMap = this._mapTileViewModels(rooms, invites);
|
||||||
this._tileViewModelsFilterMap = new ApplyMap(this._tileViewModelsMap);
|
this._tileViewModelsSlidingWindow = new FilteredMap(this._tileViewModelsMap, (r, roomId) => {
|
||||||
|
const include = includeRoomFn(roomId);
|
||||||
|
return include;
|
||||||
|
});
|
||||||
|
this._tileViewModelsFilterMap = new ApplyMap(this._tileViewModelsSlidingWindow);
|
||||||
this._tileViewModels = this._tileViewModelsFilterMap.sortValues((a, b) => a.compare(b));
|
this._tileViewModels = this._tileViewModelsFilterMap.sortValues((a, b) => a.compare(b));
|
||||||
this._currentTileVM = null;
|
this._currentTileVM = null;
|
||||||
this._setupNavigation();
|
this._setupNavigation();
|
||||||
|
|
|
@ -128,7 +128,7 @@ export class Sync3 {
|
||||||
this.status = new ObservableValue(SyncStatus.Stopped);
|
this.status = new ObservableValue(SyncStatus.Stopped);
|
||||||
this.error = null;
|
this.error = null;
|
||||||
// Hydrogen only has 1 list currently (no DM section) so we only need 1 range
|
// Hydrogen only has 1 list currently (no DM section) so we only need 1 range
|
||||||
this.ranges = [[0, 49]];
|
this.ranges = [[0, 4]];
|
||||||
this.roomIndexToRoomId = {};
|
this.roomIndexToRoomId = {};
|
||||||
this.roomIdToRoomIndex = {};
|
this.roomIdToRoomIndex = {};
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,11 @@ export class Sync3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compare(roomIdA: string, roomIdB: string) {
|
includeRoom(roomId: string): boolean {
|
||||||
|
return this.roomIdToRoomIndex[roomId] !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
compare(roomIdA: string, roomIdB: string): number {
|
||||||
if (roomIdA === roomIdB) {
|
if (roomIdA === roomIdB) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -325,6 +329,9 @@ export class Sync3 {
|
||||||
await syncTxn.complete(log);
|
await syncTxn.complete(log);
|
||||||
|
|
||||||
// Sync v3 specific
|
// Sync v3 specific
|
||||||
|
// work out which rooms are no longer being tracked (they'll be deleted in indexToRoom but exist in this.roomIndexToRoomId)
|
||||||
|
// and then force update those rooms to force the FilteredMap to re-evalute to remove them from the left panel room list
|
||||||
|
const deletedRoomIDs = deletedElements(Object.values(this.roomIndexToRoomId), Object.values(indexToRoom));
|
||||||
// atomically move all the rooms to their new positions
|
// atomically move all the rooms to their new positions
|
||||||
// We need to do this BEFORE calling afterSync as that causes the room list to be sorted
|
// We need to do this BEFORE calling afterSync as that causes the room list to be sorted
|
||||||
// which eventually causes Sync3.compare to be called, so we need it to be using the latest
|
// which eventually causes Sync3.compare to be called, so we need it to be using the latest
|
||||||
|
@ -335,6 +342,17 @@ export class Sync3 {
|
||||||
const index = Number(indexStr);
|
const index = Number(indexStr);
|
||||||
this.roomIdToRoomIndex[indexToRoom[index]] = index;
|
this.roomIdToRoomIndex[indexToRoom[index]] = index;
|
||||||
});
|
});
|
||||||
|
if (deletedRoomIDs.length > 0) {
|
||||||
|
console.log("DELETED ", deletedRoomIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now force update rooms which fell off the sliding window
|
||||||
|
deletedRoomIDs.forEach((roomId) => {
|
||||||
|
let room = this.session.rooms.get(roomId);
|
||||||
|
room.forceRefresh();
|
||||||
|
})
|
||||||
|
|
||||||
|
// END sync v3 specific
|
||||||
|
|
||||||
// update in-memory structs
|
// update in-memory structs
|
||||||
// this.session.afterSync(); // ???
|
// this.session.afterSync(); // ???
|
||||||
|
@ -528,6 +546,19 @@ const indexInRange = (ranges: number[][], i: number) => {
|
||||||
return isInRange;
|
return isInRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// returns the elements which exist in old but not in new
|
||||||
|
const deletedElements = (oldArr: string[], newArr: string[]): string[] => {
|
||||||
|
let set = {};
|
||||||
|
oldArr.forEach((k) => {
|
||||||
|
set[k] = true;
|
||||||
|
});
|
||||||
|
newArr.forEach((k) => {
|
||||||
|
delete set[k];
|
||||||
|
})
|
||||||
|
|
||||||
|
return Object.keys(set);
|
||||||
|
}
|
||||||
|
|
||||||
export function tests() {
|
export function tests() {
|
||||||
return {
|
return {
|
||||||
"processSyncOps": assert => {
|
"processSyncOps": assert => {
|
||||||
|
|
|
@ -76,6 +76,11 @@ export class BaseRoom extends EventEmitter {
|
||||||
return retryTimelineEntries;
|
return retryTimelineEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forcibly update this room in collections
|
||||||
|
forceRefresh() {
|
||||||
|
this._emitUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for retrying decryption from other sources than sync, like key backup.
|
* Used for retrying decryption from other sources than sync, like key backup.
|
||||||
* @internal
|
* @internal
|
||||||
|
|
|
@ -63,7 +63,20 @@ export class SortedMapList extends BaseObservableList {
|
||||||
|
|
||||||
onRemove(key, value) {
|
onRemove(key, value) {
|
||||||
const pair = {key, value};
|
const pair = {key, value};
|
||||||
const idx = sortedIndex(this._sortedPairs, pair, this._comparator);
|
// Don't call sortedIndex as it does a binary search for the removed item.
|
||||||
|
// Whilst that is faster than the O(n) search we're doing here, it's not valid to compare
|
||||||
|
// removed items as the system may have no ability to compare them at this point.
|
||||||
|
let idx = -1;
|
||||||
|
for (let i = 0; i < this._sortedPairs.length; i++) {
|
||||||
|
if (this._sortedPairs[i].key === key) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("removing ", key, idx, value);
|
||||||
// assert key === this._sortedPairs[idx].key;
|
// assert key === this._sortedPairs[idx].key;
|
||||||
this._sortedPairs.splice(idx, 1);
|
this._sortedPairs.splice(idx, 1);
|
||||||
this.emitRemove(idx, value);
|
this.emitRemove(idx, value);
|
||||||
|
|
Reference in a new issue