mirror of
https://github.com/matrix-org/sliding-sync.git
synced 2025-03-10 13:37:11 +00:00
Invalidate ranges when the filter changes on a list
Some bugs still exist on the client where it gets confused about the new offsets, but the server code seems to be doing the right thing.
This commit is contained in:
parent
4c10175125
commit
44bfebfab9
@ -20,6 +20,9 @@
|
||||
<input id="syncButton" type="button" value="Start Sync" />
|
||||
<input id="debugButton" type="button" value="DEBUG" style="display: none;" />
|
||||
<span id="errorMsg"></span>
|
||||
<div>
|
||||
<input id="roomfilter" type="text" placeholder="Filter rooms..." />
|
||||
</div>
|
||||
</div>
|
||||
<div class="roomheading">
|
||||
<img class="roomavatar" decoding="async" id="selectedroomavatar" src="/client/placeholder.svg"/>
|
||||
|
@ -2,14 +2,17 @@ let lastError = null;
|
||||
let activeAbortController = new AbortController();
|
||||
let activeSessionId;
|
||||
let activeRoomId = ""; // the room currently being viewed
|
||||
const DEFAULT_RANGES = [[0, 20]];
|
||||
|
||||
let activeLists = [
|
||||
{
|
||||
name: "Direct Messages",
|
||||
listFiltersModified: false,
|
||||
listFilters: {
|
||||
is_dm: true,
|
||||
room_name_like: undefined,
|
||||
},
|
||||
activeRanges: [[0, 20]],
|
||||
activeRanges: 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: {},
|
||||
@ -18,10 +21,12 @@ let activeLists = [
|
||||
},
|
||||
{
|
||||
name: "Group Chats",
|
||||
listFiltersModified: false,
|
||||
listFilters: {
|
||||
is_dm: false,
|
||||
room_name_like: undefined,
|
||||
},
|
||||
activeRanges: [[0, 20]],
|
||||
activeRanges: 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: {},
|
||||
@ -412,6 +417,14 @@ const doSyncLoop = async (accessToken, sessionId) => {
|
||||
ranges: al.activeRanges,
|
||||
filters: al.listFilters,
|
||||
};
|
||||
// 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) {
|
||||
l.ranges = DEFAULT_RANGES;
|
||||
al.listFiltersModified = false;
|
||||
al.roomIndexToRoomId = {};
|
||||
}
|
||||
// if this is the first request on this session, send sticky request data which never changes
|
||||
if (!currentPos) {
|
||||
l.required_state = requiredStateEventsInList;
|
||||
@ -420,7 +433,6 @@ const doSyncLoop = async (accessToken, sessionId) => {
|
||||
}
|
||||
return l;
|
||||
}),
|
||||
session_id: sessionId ? sessionId : undefined,
|
||||
};
|
||||
// check if we are (un)subscribing to a room and modify request this one time for it
|
||||
let subscribingToRoom;
|
||||
@ -752,6 +764,17 @@ window.addEventListener("load", (event) => {
|
||||
activeSessionId = new Date().getTime() + "";
|
||||
doSyncLoop(accessToken, activeSessionId);
|
||||
};
|
||||
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;
|
||||
}
|
||||
if (activeAbortController) {
|
||||
// interrupt the sync request to send up new filters
|
||||
activeAbortController.abort();
|
||||
}
|
||||
});
|
||||
document.getElementById("debugButton").onclick = () => {
|
||||
const debugBox = document.getElementById("debugCmd");
|
||||
debugBox.style = "";
|
||||
|
@ -42,7 +42,9 @@ type ConnState struct {
|
||||
muxedReq *sync3.Request
|
||||
lists *sync3.SortableRoomLists
|
||||
roomSubscriptions map[string]sync3.RoomSubscription
|
||||
loadPosition int64
|
||||
|
||||
allRooms []sync3.RoomConnMetadata
|
||||
loadPosition int64
|
||||
|
||||
// A channel which the dispatcher uses to send updates to the conn goroutine
|
||||
// Consumed when the conn is read. There is a limit to how many updates we will store before
|
||||
@ -104,6 +106,7 @@ func (s *ConnState) load(req *sync3.Request) error {
|
||||
),
|
||||
}
|
||||
}
|
||||
s.allRooms = rooms
|
||||
s.loadPosition = initialLoadPosition
|
||||
|
||||
for i, l := range req.Lists {
|
||||
@ -236,9 +239,11 @@ func (s *ConnState) onIncomingListRequest(listIndex int, prevReqList, nextReqLis
|
||||
|
||||
var prevRange sync3.SliceRanges
|
||||
var prevSort []string
|
||||
var prevFilters *sync3.RequestFilters
|
||||
if prevReqList != nil {
|
||||
prevRange = prevReqList.Ranges
|
||||
prevSort = prevReqList.Sort
|
||||
prevFilters = prevReqList.Filters
|
||||
}
|
||||
if nextReqList.Sort == nil {
|
||||
nextReqList.Sort = []string{sync3.SortByRecency}
|
||||
@ -252,10 +257,11 @@ func (s *ConnState) onIncomingListRequest(listIndex int, prevReqList, nextReqLis
|
||||
} else {
|
||||
addedRanges = nextReqList.Ranges
|
||||
}
|
||||
if !reflect.DeepEqual(prevSort, nextReqList.Sort) {
|
||||
// the sort operations have changed, invalidate everything (if there were previous syncs), re-sort and re-SYNC
|
||||
if prevSort != nil {
|
||||
for _, r := range prevReqList.Ranges {
|
||||
changedFilters := sync3.ChangedFilters(prevFilters, nextReqList.Filters)
|
||||
if !reflect.DeepEqual(prevSort, nextReqList.Sort) || changedFilters {
|
||||
// the sort/filter operations have changed, invalidate everything (if there were previous syncs), re-sort and re-SYNC
|
||||
if prevSort != nil || changedFilters {
|
||||
for _, r := range prevRange {
|
||||
responseOperations = append(responseOperations, &sync3.ResponseOpRange{
|
||||
List: listIndex,
|
||||
Operation: sync3.OpInvalidate,
|
||||
@ -263,6 +269,11 @@ func (s *ConnState) onIncomingListRequest(listIndex int, prevReqList, nextReqLis
|
||||
})
|
||||
}
|
||||
}
|
||||
if changedFilters {
|
||||
// we need to re-create the list as the rooms may have completely changed
|
||||
roomList = sync3.NewFilteredSortableRooms(s.allRooms, nextReqList.Filters)
|
||||
s.lists.Set(listIndex, roomList)
|
||||
}
|
||||
if err := roomList.Sort(nextReqList.Sort); err != nil {
|
||||
logger.Err(err).Int("index", listIndex).Msg("cannot sort list")
|
||||
}
|
||||
|
@ -115,7 +115,6 @@ func (h *SyncLiveHandler) serve(w http.ResponseWriter, req *http.Request) error
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println("incoming sync pos=", req.URL.Query().Get("pos"))
|
||||
conn, err := h.setupConnection(req, &requestBody, req.URL.Query().Get("pos") != "")
|
||||
if err != nil {
|
||||
hlog.FromRequest(req).Err(err).Msg("failed to get or create Conn")
|
||||
|
@ -194,6 +194,19 @@ func (rf *RequestFilters) Include(r *RoomConnMetadata) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func ChangedFilters(prev, next *RequestFilters) bool {
|
||||
// easier to marshal as JSON rather than do a bazillion nil checks
|
||||
pb, err := json.Marshal(prev)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nb, err := json.Marshal(next)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return !bytes.Equal(pb, nb)
|
||||
}
|
||||
|
||||
type RoomSubscription struct {
|
||||
RequiredState [][2]string `json:"required_state"`
|
||||
TimelineLimit int64 `json:"timeline_limit"`
|
||||
|
Loading…
x
Reference in New Issue
Block a user