forked from mystiq/hydrogen-web
Implement sync v3 sorting
This commit is contained in:
parent
29c60eb699
commit
956b4a9b96
5 changed files with 43 additions and 9 deletions
|
@ -39,7 +39,8 @@ export class SessionViewModel extends ViewModel {
|
||||||
})));
|
})));
|
||||||
this._leftPanelViewModel = this.track(new LeftPanelViewModel(this.childOptions({
|
this._leftPanelViewModel = this.track(new LeftPanelViewModel(this.childOptions({
|
||||||
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),
|
||||||
})));
|
})));
|
||||||
this._settingsViewModel = null;
|
this._settingsViewModel = null;
|
||||||
this._roomViewModelObservable = null;
|
this._roomViewModelObservable = null;
|
||||||
|
|
|
@ -26,7 +26,7 @@ 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} = options;
|
const {rooms, invites, compareFn} = options;
|
||||||
this._tileViewModelsMap = this._mapTileViewModels(rooms, invites);
|
this._tileViewModelsMap = this._mapTileViewModels(rooms, invites);
|
||||||
this._tileViewModelsFilterMap = new ApplyMap(this._tileViewModelsMap);
|
this._tileViewModelsFilterMap = new ApplyMap(this._tileViewModelsMap);
|
||||||
this._tileViewModels = this._tileViewModelsFilterMap.sortValues((a, b) => a.compare(b));
|
this._tileViewModels = this._tileViewModelsFilterMap.sortValues((a, b) => a.compare(b));
|
||||||
|
@ -34,6 +34,7 @@ export class LeftPanelViewModel extends ViewModel {
|
||||||
this._setupNavigation();
|
this._setupNavigation();
|
||||||
this._closeUrl = this.urlCreator.urlForSegment("session");
|
this._closeUrl = this.urlCreator.urlForSegment("session");
|
||||||
this._settingsUrl = this.urlCreator.urlForSegment("settings");
|
this._settingsUrl = this.urlCreator.urlForSegment("settings");
|
||||||
|
this._compareFn = compareFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mapTileViewModels(rooms, invites) {
|
_mapTileViewModels(rooms, invites) {
|
||||||
|
@ -45,7 +46,11 @@ export class LeftPanelViewModel extends ViewModel {
|
||||||
} else if (roomOrInvite.isPlaceholder) {
|
} else if (roomOrInvite.isPlaceholder) {
|
||||||
vm = new PlaceholderRoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange}));
|
vm = new PlaceholderRoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange}));
|
||||||
} else {
|
} 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;
|
const isOpen = this.navigation.path.get("room")?.value === roomOrInvite.id;
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
|
|
|
@ -20,9 +20,10 @@ import {BaseTileViewModel} from "./BaseTileViewModel.js";
|
||||||
export class RoomTileViewModel extends BaseTileViewModel {
|
export class RoomTileViewModel extends BaseTileViewModel {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
const {room} = options;
|
const {room, compareFn} = options;
|
||||||
this._room = room;
|
this._room = room;
|
||||||
this._url = this.urlCreator.openRoomActionUrl(this._room.id);
|
this._url = this.urlCreator.openRoomActionUrl(this._room.id);
|
||||||
|
this._compareFn = compareFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
get kind() {
|
get kind() {
|
||||||
|
@ -34,6 +35,8 @@ export class RoomTileViewModel extends BaseTileViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
compare(other) {
|
compare(other) {
|
||||||
|
return this._compareFn(this._room.id, other._room.id);
|
||||||
|
|
||||||
const parentComparison = super.compare(other);
|
const parentComparison = super.compare(other);
|
||||||
if (parentComparison !== 0) {
|
if (parentComparison !== 0) {
|
||||||
return parentComparison;
|
return parentComparison;
|
||||||
|
|
|
@ -97,8 +97,11 @@ interface RoomResponse {
|
||||||
};
|
};
|
||||||
|
|
||||||
type IndexToRoomId = {
|
type IndexToRoomId = {
|
||||||
[index: string]: string;
|
[index: number]: string;
|
||||||
};
|
};
|
||||||
|
type RoomIdToIndex = {
|
||||||
|
[roomId: string]: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class Sync3 {
|
export class Sync3 {
|
||||||
private hsApi: HomeServerApi;
|
private hsApi: HomeServerApi;
|
||||||
|
@ -110,6 +113,7 @@ export class Sync3 {
|
||||||
// sync v3 specific: contains the sliding window ranges to request
|
// sync v3 specific: contains the sliding window ranges to request
|
||||||
private ranges: number[][];
|
private ranges: number[][];
|
||||||
private roomIndexToRoomId: IndexToRoomId;
|
private roomIndexToRoomId: IndexToRoomId;
|
||||||
|
private roomIdToRoomIndex: RoomIdToIndex;
|
||||||
|
|
||||||
public error?: any;
|
public error?: any;
|
||||||
public status: ObservableValue<SyncStatus>;
|
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
|
// Hydrogen only has 1 list currently (no DM section) so we only need 1 range
|
||||||
this.ranges = [[0, 99]];
|
this.ranges = [[0, 99]];
|
||||||
this.roomIndexToRoomId = {};
|
this.roomIndexToRoomId = {};
|
||||||
|
this.roomIdToRoomIndex = {};
|
||||||
console.log("session", session);
|
console.log("session", session);
|
||||||
console.log("storage", storage);
|
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
|
// 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.
|
// know or care how to handle the response, it only cares about the position and retries.
|
||||||
private async syncLoop(pos?: number) {
|
private async syncLoop(pos?: number) {
|
||||||
|
@ -298,6 +318,14 @@ export class Sync3 {
|
||||||
}
|
}
|
||||||
await syncTxn.complete(log);
|
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
|
// update in-memory structs
|
||||||
// this.session.afterSync(); // ???
|
// 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
|
// The purpose of this function is to process the response `ops` array by modifying the current
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
navigation: navigation,
|
navigation: navigation,
|
||||||
urlCreator: urlRouter,
|
urlCreator: urlRouter,
|
||||||
platform: platform,
|
platform: platform,
|
||||||
|
compareFn: syncer.compare.bind(syncer),
|
||||||
});
|
});
|
||||||
leftPanel.loadRoomRange = async (range) => {
|
leftPanel.loadRoomRange = async (range) => {
|
||||||
// pretend to load something
|
// pretend to load something
|
||||||
|
|
Loading…
Reference in a new issue