Skip to content

Commit 6ded99e

Browse files
committed
refactor(sliding-sync): gate listTimelineLimit behind message preview settings
LIST_TIMELINE_LIMIT is now configurable via SlidingSyncConfig.listTimelineLimit (default: 1). When dmMessagePreview or roomMessagePreview is enabled, the limit is bumped to 5 so reactions/edits don't leave the preview empty. Users with both preview settings disabled keep the lightweight limit of 1.
1 parent c08e14d commit 6ded99e

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

src/app/pages/client/ClientRoot.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { useSyncNicknames } from '$hooks/useNickname';
4848
import { useAppVisibility } from '$hooks/useAppVisibility';
4949
import { getHomePath } from '$pages/pathUtils';
5050
import { useClientConfig } from '$hooks/useClientConfig';
51+
import { getSettings } from '$state/settings';
5152
import { pushSessionToSW } from '../../../sw-session';
5253
import { SyncStatus } from './SyncStatus';
5354
import { SpecVersions } from './SpecVersions';
@@ -212,12 +213,18 @@ export function ClientRoot({ children }: ClientRootProps) {
212213

213214
const [startState, startMatrix] = useAsyncCallback<void, Error, [MatrixClient]>(
214215
useCallback(
215-
(m) =>
216-
startClient(m, {
216+
(m) => {
217+
const s = getSettings();
218+
const needsPreviewTimeline = s.dmMessagePreview || s.roomMessagePreview;
219+
return startClient(m, {
217220
baseUrl: activeSession?.baseUrl,
218-
slidingSync: clientConfig.slidingSync,
221+
slidingSync: {
222+
...clientConfig.slidingSync,
223+
listTimelineLimit: needsPreviewTimeline ? 5 : undefined,
224+
},
219225
sessionSlidingSyncOptIn: activeSession?.slidingSyncOptIn,
220-
}),
226+
});
227+
},
221228
[activeSession?.baseUrl, activeSession?.slidingSyncOptIn, clientConfig.slidingSync]
222229
)
223230
);

src/client/slidingSync.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ export const LIST_ROOM_SEARCH = 'room_search';
3636
export const LIST_SPACE = 'space';
3737
// A small number of timeline events per list room. Unread counts come from
3838
// the server-side notification_count field, so a full history isn't needed.
39-
// We fetch a few events (rather than 1) so that reactions and edits — which
40-
// the SDK excludes from the main timeline when their parent event is absent —
41-
// don't leave the timeline empty and break message previews.
42-
const LIST_TIMELINE_LIMIT = 5;
39+
// When message previews are enabled, a higher limit (e.g. 5) avoids empty
40+
// timelines caused by reactions/edits whose parent event is absent.
41+
const DEFAULT_LIST_TIMELINE_LIMIT = 1;
4342
const DEFAULT_LIST_PAGE_SIZE = 250;
4443
const DEFAULT_POLL_TIMEOUT_MS = 20000;
4544
const DEFAULT_MAX_ROOMS = 5000;
@@ -53,7 +52,7 @@ const LIST_SORT_ORDER = ['by_recency', 'by_name'];
5352
// Encrypted rooms get [*,*] required_state; unencrypted rooms also request lazy members.
5453
const UNENCRYPTED_SUBSCRIPTION_KEY = 'unencrypted';
5554
// Timeline limit for the active-room subscription (full history load).
56-
// List entries always use LIST_TIMELINE_LIMIT=1 for lightweight previews.
55+
// List entries use a small timeline limit (default 1) for lightweight previews.
5756
const ACTIVE_ROOM_TIMELINE_LIMIT = 50;
5857

5958
export type PartialSlidingSyncRequest = {
@@ -67,6 +66,7 @@ export type SlidingSyncConfig = {
6766
proxyBaseUrl?: string;
6867
bootstrapClassicOnColdCache?: boolean;
6968
listPageSize?: number;
69+
listTimelineLimit?: number;
7070
timelineLimit?: number;
7171
pollTimeoutMs?: number;
7272
maxRooms?: number;
@@ -147,7 +147,7 @@ const buildUnencryptedSubscription = (timelineLimit: number): MSC3575RoomSubscri
147147
],
148148
});
149149

150-
const buildLists = (pageSize: number, includeInviteList: boolean): Map<string, MSC3575List> => {
150+
const buildLists = (pageSize: number, includeInviteList: boolean, listTimelineLimit: number): Map<string, MSC3575List> => {
151151
const lists = new Map<string, MSC3575List>();
152152
const listRequiredState = buildListRequiredState();
153153

@@ -159,7 +159,7 @@ const buildLists = (pageSize: number, includeInviteList: boolean): Map<string, M
159159
lists.set(LIST_JOINED, {
160160
ranges: [[0, Math.max(0, initialRange - 1)]],
161161
sort: LIST_SORT_ORDER,
162-
timeline_limit: LIST_TIMELINE_LIMIT,
162+
timeline_limit: listTimelineLimit,
163163
required_state: listRequiredState,
164164
slow_get_all_rooms: true,
165165
filters: { is_invite: false },
@@ -169,7 +169,7 @@ const buildLists = (pageSize: number, includeInviteList: boolean): Map<string, M
169169
lists.set(LIST_INVITES, {
170170
ranges: [[0, Math.max(0, initialRange - 1)]],
171171
sort: LIST_SORT_ORDER,
172-
timeline_limit: LIST_TIMELINE_LIMIT,
172+
timeline_limit: listTimelineLimit,
173173
required_state: listRequiredState,
174174
slow_get_all_rooms: true,
175175
filters: { is_invite: true },
@@ -179,7 +179,7 @@ const buildLists = (pageSize: number, includeInviteList: boolean): Map<string, M
179179
lists.set(LIST_DMS, {
180180
ranges: [[0, Math.max(0, initialRange - 1)]],
181181
sort: LIST_SORT_ORDER,
182-
timeline_limit: LIST_TIMELINE_LIMIT,
182+
timeline_limit: listTimelineLimit,
183183
required_state: listRequiredState,
184184
slow_get_all_rooms: true,
185185
filters: { is_dm: true },
@@ -251,6 +251,8 @@ export class SlidingSyncManager {
251251

252252
private readonly listPageSize: number;
253253

254+
private readonly listTimelineLimit: number;
255+
254256
private readonly roomTimelineLimit: number;
255257

256258
private readonly onConnectionChange: () => void;
@@ -303,12 +305,13 @@ export class SlidingSyncManager {
303305
this.maxRooms = clampPositive(config.maxRooms, DEFAULT_MAX_ROOMS);
304306
this.listPageSize = listPageSize;
305307
const includeInviteList = config.includeInviteList !== false;
308+
this.listTimelineLimit = clampPositive(config.listTimelineLimit, DEFAULT_LIST_TIMELINE_LIMIT);
306309

307310
const roomTimelineLimit = clampPositive(config.timelineLimit, ACTIVE_ROOM_TIMELINE_LIMIT);
308311
this.roomTimelineLimit = roomTimelineLimit;
309312

310313
const defaultSubscription = buildEncryptedSubscription(roomTimelineLimit);
311-
const lists = buildLists(listPageSize, includeInviteList);
314+
const lists = buildLists(listPageSize, includeInviteList, this.listTimelineLimit);
312315
this.listKeys = Array.from(lists.keys());
313316
this.slidingSync = new SlidingSync(proxyBaseUrl, lists, defaultSubscription, mx, pollTimeoutMs);
314317

@@ -720,7 +723,7 @@ export class SlidingSyncManager {
720723
list = {
721724
ranges: [[0, 20]],
722725
sort: LIST_SORT_ORDER,
723-
timeline_limit: LIST_TIMELINE_LIMIT,
726+
timeline_limit: this.listTimelineLimit,
724727
required_state: buildListRequiredState(),
725728
...updateArgs,
726729
};

0 commit comments

Comments
 (0)