@@ -291,6 +291,7 @@ class _RoomMembershipForUser:
291291 sender: The person who sent the membership event
292292 newly_joined: Whether the user newly joined the room during the given token
293293 range
294+ is_dm: Whether this user considers this room as a direct-message (DM) room
294295 """
295296
296297 room_id : str
@@ -299,6 +300,7 @@ class _RoomMembershipForUser:
299300 membership : str
300301 sender : Optional [str ]
301302 newly_joined : bool
303+ is_dm : bool
302304
303305 def copy_and_replace (self , ** kwds : Any ) -> "_RoomMembershipForUser" :
304306 return attr .evolve (self , ** kwds )
@@ -613,6 +615,7 @@ async def get_sync_room_ids_for_user(
613615 membership = room_for_user .membership ,
614616 sender = room_for_user .sender ,
615617 newly_joined = False ,
618+ is_dm = False ,
616619 )
617620 for room_for_user in room_for_user_list
618621 }
@@ -652,6 +655,7 @@ async def get_sync_room_ids_for_user(
652655 # - 1c) Update room membership events to the point in time of the `to_token`
653656 # - 2) Add back newly_left rooms (> `from_token` and <= `to_token`)
654657 # - 3) Figure out which rooms are `newly_joined`
658+ # - 4) Figure out which rooms are DM's
655659
656660 # 1) -----------------------------------------------------
657661
@@ -714,6 +718,7 @@ async def get_sync_room_ids_for_user(
714718 membership = first_membership_change_after_to_token .prev_membership ,
715719 sender = first_membership_change_after_to_token .prev_sender ,
716720 newly_joined = False ,
721+ is_dm = False ,
717722 )
718723 else :
719724 # If we can't find the previous membership event, we shouldn't
@@ -809,6 +814,7 @@ async def get_sync_room_ids_for_user(
809814 membership = last_membership_change_in_from_to_range .membership ,
810815 sender = last_membership_change_in_from_to_range .sender ,
811816 newly_joined = False ,
817+ is_dm = False ,
812818 )
813819
814820 # 3) Figure out `newly_joined`
@@ -846,6 +852,35 @@ async def get_sync_room_ids_for_user(
846852 room_id
847853 ].copy_and_replace (newly_joined = True )
848854
855+ # 4) Figure out which rooms the user considers to be direct-message (DM) rooms
856+ #
857+ # We're using global account data (`m.direct`) instead of checking for
858+ # `is_direct` on membership events because that property only appears for
859+ # the invitee membership event (doesn't show up for the inviter).
860+ #
861+ # We're unable to take `to_token` into account for global account data since
862+ # we only keep track of the latest account data for the user.
863+ dm_map = await self .store .get_global_account_data_by_type_for_user (
864+ user_id , AccountDataTypes .DIRECT
865+ )
866+
867+ # Flatten out the map. Account data is set by the client so it needs to be
868+ # scrutinized.
869+ dm_room_id_set = set ()
870+ if isinstance (dm_map , dict ):
871+ for room_ids in dm_map .values ():
872+ # Account data should be a list of room IDs. Ignore anything else
873+ if isinstance (room_ids , list ):
874+ for room_id in room_ids :
875+ if isinstance (room_id , str ):
876+ dm_room_id_set .add (room_id )
877+
878+ # 4) Fixup
879+ for room_id in filtered_sync_room_id_set :
880+ filtered_sync_room_id_set [room_id ] = filtered_sync_room_id_set [
881+ room_id
882+ ].copy_and_replace (is_dm = room_id in dm_room_id_set )
883+
849884 return filtered_sync_room_id_set
850885
851886 async def filter_rooms (
@@ -869,41 +904,24 @@ async def filter_rooms(
869904 A filtered dictionary of room IDs along with membership information in the
870905 room at the time of `to_token`.
871906 """
872- user_id = user .to_string ()
873-
874- # TODO: Apply filters
875-
876907 filtered_room_id_set = set (sync_room_map .keys ())
877908
878909 # Filter for Direct-Message (DM) rooms
879910 if filters .is_dm is not None :
880- # We're using global account data (`m.direct`) instead of checking for
881- # `is_direct` on membership events because that property only appears for
882- # the invitee membership event (doesn't show up for the inviter). Account
883- # data is set by the client so it needs to be scrutinized.
884- #
885- # We're unable to take `to_token` into account for global account data since
886- # we only keep track of the latest account data for the user.
887- dm_map = await self .store .get_global_account_data_by_type_for_user (
888- user_id , AccountDataTypes .DIRECT
889- )
890-
891- # Flatten out the map
892- dm_room_id_set = set ()
893- if isinstance (dm_map , dict ):
894- for room_ids in dm_map .values ():
895- # Account data should be a list of room IDs. Ignore anything else
896- if isinstance (room_ids , list ):
897- for room_id in room_ids :
898- if isinstance (room_id , str ):
899- dm_room_id_set .add (room_id )
900-
901911 if filters .is_dm :
902912 # Only DM rooms please
903- filtered_room_id_set = filtered_room_id_set .intersection (dm_room_id_set )
913+ filtered_room_id_set = {
914+ room_id
915+ for room_id in filtered_room_id_set
916+ if sync_room_map [room_id ].is_dm
917+ }
904918 else :
905919 # Only non-DM rooms please
906- filtered_room_id_set = filtered_room_id_set .difference (dm_room_id_set )
920+ filtered_room_id_set = {
921+ room_id
922+ for room_id in filtered_room_id_set
923+ if not sync_room_map [room_id ].is_dm
924+ }
907925
908926 if filters .spaces :
909927 raise NotImplementedError ()
@@ -1538,8 +1556,7 @@ async def get_room_sync_data(
15381556 name = room_name ,
15391557 avatar = room_avatar ,
15401558 heroes = heroes ,
1541- # TODO: Dummy value
1542- is_dm = False ,
1559+ is_dm = room_membership_for_user_at_to_token .is_dm ,
15431560 initial = initial ,
15441561 required_state = list (required_room_state .values ()),
15451562 timeline_events = timeline_events ,
0 commit comments