Implement sync v3 sorting

This commit is contained in:
Kegan Dougal 2021-11-30 13:24:08 +00:00
parent 29c60eb699
commit 956b4a9b96
5 changed files with 43 additions and 9 deletions

View file

@ -39,7 +39,8 @@ export class SessionViewModel extends ViewModel {
})));
this._leftPanelViewModel = this.track(new LeftPanelViewModel(this.childOptions({
invites: this._sessionContainer.session.invites,
rooms: this._sessionContainer.session.rooms
rooms: this._sessionContainer.session.rooms,
compareFn: this._sessionContainer.sync.compare.bind(this._sessionContainer.sync),
})));
this._settingsViewModel = null;
this._roomViewModelObservable = null;

View file

@ -26,7 +26,7 @@ import { PlaceholderRoomTileViewModel } from "./PlaceholderRoomTileViewModel.js"
export class LeftPanelViewModel extends ViewModel {
constructor(options) {
super(options);
const {rooms, invites} = options;
const {rooms, invites, compareFn} = options;
this._tileViewModelsMap = this._mapTileViewModels(rooms, invites);
this._tileViewModelsFilterMap = new ApplyMap(this._tileViewModelsMap);
this._tileViewModels = this._tileViewModelsFilterMap.sortValues((a, b) => a.compare(b));
@ -34,6 +34,7 @@ export class LeftPanelViewModel extends ViewModel {
this._setupNavigation();
this._closeUrl = this.urlCreator.urlForSegment("session");
this._settingsUrl = this.urlCreator.urlForSegment("settings");
this._compareFn = compareFn;
}
_mapTileViewModels(rooms, invites) {
@ -45,7 +46,11 @@ export class LeftPanelViewModel extends ViewModel {
} else if (roomOrInvite.isPlaceholder) {
vm = new PlaceholderRoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange}));
} else {
vm = new RoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange}));
vm = new RoomTileViewModel(this.childOptions({
room: roomOrInvite,
compareFn: this._compareFn,
emitChange,
}));
}
const isOpen = this.navigation.path.get("room")?.value === roomOrInvite.id;
if (isOpen) {

View file

@ -20,9 +20,10 @@ import {BaseTileViewModel} from "./BaseTileViewModel.js";
export class RoomTileViewModel extends BaseTileViewModel {
constructor(options) {
super(options);
const {room} = options;
const {room, compareFn} = options;
this._room = room;
this._url = this.urlCreator.openRoomActionUrl(this._room.id);
this._compareFn = compareFn;
}
get kind() {
@ -34,6 +35,8 @@ export class RoomTileViewModel extends BaseTileViewModel {
}
compare(other) {
return this._compareFn(this._room.id, other._room.id);
const parentComparison = super.compare(other);
if (parentComparison !== 0) {
return parentComparison;

View file

@ -97,8 +97,11 @@ interface RoomResponse {
};
type IndexToRoomId = {
[index: string]: string;
[index: number]: string;
};
type RoomIdToIndex = {
[roomId: string]: number;
}
export class Sync3 {
private hsApi: HomeServerApi;
@ -110,6 +113,7 @@ export class Sync3 {
// sync v3 specific: contains the sliding window ranges to request
private ranges: number[][];
private roomIndexToRoomId: IndexToRoomId;
private roomIdToRoomIndex: RoomIdToIndex;
public error?: any;
public status: ObservableValue<SyncStatus>;
@ -126,6 +130,7 @@ export class Sync3 {
// Hydrogen only has 1 list currently (no DM section) so we only need 1 range
this.ranges = [[0, 99]];
this.roomIndexToRoomId = {};
this.roomIdToRoomIndex = {};
console.log("session", session);
console.log("storage", storage);
}
@ -152,6 +157,21 @@ export class Sync3 {
}
}
compare(roomIdA: string, roomIdB: string) {
if (roomIdA === roomIdB) {
return 0;
}
const indexA = this.roomIdToRoomIndex[roomIdA];
const indexB = this.roomIdToRoomIndex[roomIdB];
if (indexA === undefined || indexB === undefined) {
console.error("sync3 cannot compare: missing indices for rooms", roomIdA, roomIdB, indexA, indexB);
}
if (indexA < indexB) {
return -1;
}
return 1;
}
// The purpose of this function is to do repeated /sync calls and call processResponse. It doesn't
// know or care how to handle the response, it only cares about the position and retries.
private async syncLoop(pos?: number) {
@ -298,6 +318,14 @@ export class Sync3 {
}
await syncTxn.complete(log);
// atomically move all the rooms to their new positions
this.roomIndexToRoomId = indexToRoom;
this.roomIdToRoomIndex = {};
Object.keys(indexToRoom).forEach((indexStr) => {
const index = Number(indexStr);
this.roomIdToRoomIndex[indexToRoom[index]] = index;
});
// update in-memory structs
// this.session.afterSync(); // ???
@ -317,10 +345,6 @@ export class Sync3 {
}
}), []);
});
// instantly move all the rooms to their new positions
this.roomIndexToRoomId = indexToRoom;
}
// The purpose of this function is to process the response `ops` array by modifying the current

View file

@ -104,6 +104,7 @@
navigation: navigation,
urlCreator: urlRouter,
platform: platform,
compareFn: syncer.compare.bind(syncer),
});
leftPanel.loadRoomRange = async (range) => {
// pretend to load something