client: Move some sliding sync code to sync.js

This commit is contained in:
Kegan Dougal 2022-02-23 17:39:31 +00:00
parent 0b7405d062
commit 05a731dfbc
2 changed files with 74 additions and 41 deletions

View File

@ -1,3 +1,5 @@
// This file contains the entry point for the client, as well as DOM interactions.
import { SlidingList } from './sync.js';
import * as render from './render.js';
let lastError = null;
@ -6,37 +8,14 @@ let activeSessionId;
let activeRoomId = ""; // the room currently being viewed
let txBytes = 0;
let rxBytes = 0;
const DEFAULT_RANGES = [[0, 20]];
let activeLists = [
{
name: "Direct Messages",
listFiltersModified: false,
listFilters: {
is_dm: true,
room_name_like: undefined,
},
activeRanges: JSON.parse(JSON.stringify(DEFAULT_RANGES)),
// the constantly changing sliding window ranges. Not an array for performance reasons
// E.g tracking ranges 0-99, 500-599, we don't want to have a 600 element array
roomIndexToRoomId: {},
// the total number of joined rooms according to the server, always >= len(roomIndexToRoomId)
joinedCount: 0,
},
{
name: "Group Chats",
listFiltersModified: false,
listFilters: {
is_dm: false,
room_name_like: undefined,
},
activeRanges: JSON.parse(JSON.stringify(DEFAULT_RANGES)),
// the constantly changing sliding window ranges. Not an array for performance reasons
// E.g tracking ranges 0-99, 500-599, we don't want to have a 600 element array
roomIndexToRoomId: {},
// the total number of joined rooms according to the server, always >= len(roomIndexToRoomId)
joinedCount: 0,
},
new SlidingList("Direct Messages", {
is_dm: true,
}),
new SlidingList("Group Chats", {
is_dm: false,
}),
];
const requiredStateEventsInList = [
@ -395,17 +374,9 @@ const doSyncLoop = async (accessToken, sessionId) => {
// these fields are always required
let reqBody = {
lists: activeLists.map((al) => {
// if we are viewing a window at 100-120 and then we filter down to 5 total rooms,
// we'll end up showing nothing. Therefore, if the filters change (e.g room name filter)
// reset the range back to 0-20.
if (al.listFiltersModified) {
al.listFiltersModified = false;
al.activeRanges = JSON.parse(JSON.stringify(DEFAULT_RANGES));
al.roomIndexToRoomId = {};
}
let l = {
ranges: al.activeRanges,
filters: al.listFilters,
filters: al.getFilters(),
};
// if this is the first request on this session, send sticky request data which never changes
if (!currentPos) {
@ -607,7 +578,6 @@ const doSyncLoop = async (accessToken, sessionId) => {
};
// accessToken = string, pos = int, ranges = [2]int e.g [0,99]
let doSyncRequest = async (accessToken, pos, reqBody) => {
console.log(reqBody);
activeAbortController = new AbortController();
const jsonBody = JSON.stringify(reqBody);
let resp = await fetch("/_matrix/client/v3/sync" + (pos ? "?pos=" + pos : ""), {
@ -821,8 +791,9 @@ window.addEventListener("load", (event) => {
document.getElementById("roomfilter").addEventListener("input", (ev) => {
const roomNameFilter = ev.target.value;
for (let i = 0; i < activeLists.length; i++) {
activeLists[i].listFilters.room_name_like = roomNameFilter;
activeLists[i].listFiltersModified = true;
const filters = activeLists[i].getFilters();
filters.room_name_like = roomNameFilter;
activeLists[i].setFilters(filters);
}
// bump to the start of the room list again
const lists = document.getElementsByClassName("roomlist");

62
client/sync.js Normal file
View File

@ -0,0 +1,62 @@
// This file contains the main sliding sync code.
// The default range to /always/ track on a list.
// When you scroll the list, new windows are added to the first element. E.g [[0,20], [37,45]]
// TODO: explain why
const DEFAULT_RANGES = [[0, 20]];
/**
* SlidingList represents a single list in sliding sync. The list can have filters, multiple sliding
* windows, and maintains the index->room_id mapping.
*/
export class SlidingList {
/**
* Construct a new sliding list.
* @param {string} name Human-readable name to display on the UI for this list.
* @param {object} filters Optional. The sliding sync filters to apply e.g { is_dm: true }.
*/
constructor(name, filters) {
this.name = name;
this.filters = filters || {};
this.activeRanges = JSON.parse(JSON.stringify(DEFAULT_RANGES));
// the constantly changing sliding window ranges. Not an array for performance reasons
// E.g tracking ranges 0-99, 500-599, we don't want to have a 600 element array
this.roomIndexToRoomId = {};
// the total number of joined rooms according to the server, always >= len(roomIndexToRoomId)
this.joinedCount = 0;
}
/**
* Get the filters for this list.
* @returns {object} A copy of the filters
*/
getFilters() {
// return a copy of the filters to ensure the caller cannot modify it without calling setFilters
return Object.assign({}, this.filters);
}
/**
* Modify the filters on this list. The filters provided are copied.
* @param {object} filters The sliding sync filters to apply e.g { is_dm: true }.
*/
setFilters(filters) {
this.filters = Object.assign({}, filters);
// if we are viewing a window at 100-120 and then we filter down to 5 total rooms,
// we'll end up showing nothing. Therefore, if the filters change (e.g room name filter)
// reset the range back to 0-20.
this.activeRanges = JSON.parse(JSON.stringify(DEFAULT_RANGES));
// Wipe the index to room ID map as the filters have changed which will invalidate these.
this.roomIndexToRoomId = {};
}
}
class SlidingSync {
/**
*
* @param {[]SlidingList} activeLists
*/
constructor(activeLists) {
}
}