@@ -279,8 +279,19 @@ def _get_users_in_room_with_profiles(
279
279
280
280
@cached (max_entries = 100000 ) # type: ignore[synapse-@cached-mutable]
281
281
async def get_room_summary (self , room_id : str ) -> Mapping [str , MemberSummary ]:
282
- """Get the details of a room roughly suitable for use by the room
282
+ """
283
+ Get the details of a room roughly suitable for use by the room
283
284
summary extension to /sync. Useful when lazy loading room members.
285
+
286
+ Returns the total count of members in the room by membership type, and a
287
+ truncated list of members (the heroes). This will be the first 6 members of the
288
+ room:
289
+ - We want 5 heroes plus 1, in case one of them is the
290
+ calling user.
291
+ - They are ordered by `stream_ordering`, which are joined or
292
+ invited. When no joined or invited members are available, this also includes
293
+ banned and left users.
294
+
284
295
Args:
285
296
room_id: The room ID to query
286
297
Returns:
@@ -308,23 +319,28 @@ def _get_room_summary_txn(
308
319
for count , membership in txn :
309
320
res .setdefault (membership , MemberSummary ([], count ))
310
321
311
- # we order by membership and then fairly arbitrarily by event_id so
312
- # heroes are consistent
313
- # Note, rejected events will have a null membership field, so
314
- # we we manually filter them out.
322
+ # Order by membership (joins -> invites -> leave (former insiders) -> everything else
323
+ # including knocks since they are outsiders), then by `stream_ordering` so
324
+ # the first members in the room show up first and to make the sort stable
325
+ # (consistent heroes).
326
+ #
327
+ # Note: rejected events will have a null membership field, so we we manually
328
+ # filter them out.
315
329
sql = """
316
330
SELECT state_key, membership, event_id
317
331
FROM current_state_events
318
332
WHERE type = 'm.room.member' AND room_id = ?
319
333
AND membership IS NOT NULL
320
334
ORDER BY
321
- CASE membership WHEN ? THEN 1 WHEN ? THEN 2 ELSE 3 END ASC,
322
- event_id ASC
335
+ CASE membership WHEN ? THEN 1 WHEN ? THEN 2 WHEN ? THEN 3 ELSE 4 END ASC,
336
+ event_stream_ordering ASC
323
337
LIMIT ?
324
338
"""
325
339
326
340
# 6 is 5 (number of heroes) plus 1, in case one of them is the calling user.
327
- txn .execute (sql , (room_id , Membership .JOIN , Membership .INVITE , 6 ))
341
+ txn .execute (
342
+ sql , (room_id , Membership .JOIN , Membership .INVITE , Membership .LEAVE , 6 )
343
+ )
328
344
for user_id , membership , event_id in txn :
329
345
summary = res [membership ]
330
346
# we will always have a summary for this membership type at this
0 commit comments