mirror of
https://mau.dev/maunium/synapse.git
synced 2024-12-15 04:43:51 +01:00
Send down device list change notif when member leaves/rejoins room
This commit is contained in:
parent
e2fcba038c
commit
53cc8ad35a
3 changed files with 55 additions and 14 deletions
|
@ -320,7 +320,7 @@ class DeviceHandler(BaseHandler):
|
|||
|
||||
# check if this member has changed since any of the extremities
|
||||
# at the stream_ordering, and add them to the list if so.
|
||||
for state_dict in prev_state_ids.values():
|
||||
for state_dict in prev_state_ids.itervalues():
|
||||
prev_event_id = state_dict.get(key, None)
|
||||
if not prev_event_id or prev_event_id != event_id:
|
||||
possibly_changed.add(state_key)
|
||||
|
|
|
@ -108,6 +108,16 @@ class InvitedSyncResult(collections.namedtuple("InvitedSyncResult", [
|
|||
return True
|
||||
|
||||
|
||||
class DeviceLists(collections.namedtuple("DeviceLists", [
|
||||
"changed", # list of user_ids whose devices may have changed
|
||||
"left", # list of user_ids whose devices we no longer track
|
||||
])):
|
||||
__slots__ = []
|
||||
|
||||
def __nonzero__(self):
|
||||
return bool(self.changed or self.left)
|
||||
|
||||
|
||||
class SyncResult(collections.namedtuple("SyncResult", [
|
||||
"next_batch", # Token for the next sync
|
||||
"presence", # List of presence events for the user.
|
||||
|
@ -535,7 +545,7 @@ class SyncHandler(object):
|
|||
res = yield self._generate_sync_entry_for_rooms(
|
||||
sync_result_builder, account_data_by_room
|
||||
)
|
||||
newly_joined_rooms, newly_joined_users = res
|
||||
newly_joined_rooms, newly_joined_users, _, newly_left_users = res
|
||||
|
||||
block_all_presence_data = (
|
||||
since_token is None and
|
||||
|
@ -549,7 +559,11 @@ class SyncHandler(object):
|
|||
yield self._generate_sync_entry_for_to_device(sync_result_builder)
|
||||
|
||||
device_lists = yield self._generate_sync_entry_for_device_list(
|
||||
sync_result_builder
|
||||
sync_result_builder,
|
||||
newly_joined_rooms=newly_joined_rooms,
|
||||
newly_joined_users=newly_joined_users,
|
||||
newly_left_rooms=[],
|
||||
newly_left_users=newly_left_users,
|
||||
)
|
||||
|
||||
device_id = sync_config.device_id
|
||||
|
@ -574,7 +588,9 @@ class SyncHandler(object):
|
|||
|
||||
@measure_func("_generate_sync_entry_for_device_list")
|
||||
@defer.inlineCallbacks
|
||||
def _generate_sync_entry_for_device_list(self, sync_result_builder):
|
||||
def _generate_sync_entry_for_device_list(self, sync_result_builder,
|
||||
newly_joined_rooms, newly_joined_users,
|
||||
newly_left_rooms, newly_left_users):
|
||||
user_id = sync_result_builder.sync_config.user.to_string()
|
||||
since_token = sync_result_builder.since_token
|
||||
|
||||
|
@ -582,16 +598,32 @@ class SyncHandler(object):
|
|||
changed = yield self.store.get_user_whose_devices_changed(
|
||||
since_token.device_list_key
|
||||
)
|
||||
if not changed:
|
||||
defer.returnValue([])
|
||||
|
||||
# TODO: Check that these users are actually new, i.e. either they
|
||||
# weren't in the previous sync *or* they left and rejoined.
|
||||
changed.update(newly_joined_users)
|
||||
|
||||
# TODO: Add the members from newly_*_rooms
|
||||
|
||||
if not changed and not newly_left_users:
|
||||
defer.returnValue(DeviceLists(
|
||||
changed=[],
|
||||
left=newly_left_users,
|
||||
))
|
||||
|
||||
users_who_share_room = yield self.store.get_users_who_share_room_with_user(
|
||||
user_id
|
||||
)
|
||||
|
||||
defer.returnValue(users_who_share_room & changed)
|
||||
defer.returnValue(DeviceLists(
|
||||
changed=users_who_share_room & changed,
|
||||
left=set(newly_left_users) - users_who_share_room,
|
||||
))
|
||||
else:
|
||||
defer.returnValue([])
|
||||
defer.returnValue(DeviceLists(
|
||||
changed=[],
|
||||
left=[],
|
||||
))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _generate_sync_entry_for_to_device(self, sync_result_builder):
|
||||
|
@ -755,8 +787,8 @@ class SyncHandler(object):
|
|||
account_data_by_room(dict): Dictionary of per room account data
|
||||
|
||||
Returns:
|
||||
Deferred(tuple): Returns a 2-tuple of
|
||||
`(newly_joined_rooms, newly_joined_users)`
|
||||
Deferred(tuple): Returns a 4-tuple of
|
||||
`(newly_joined_rooms, newly_joined_users, newly_left_rooms, newly_left_users)`
|
||||
"""
|
||||
user_id = sync_result_builder.sync_config.user.to_string()
|
||||
block_all_room_ephemeral = (
|
||||
|
@ -787,7 +819,7 @@ class SyncHandler(object):
|
|||
)
|
||||
if not tags_by_room:
|
||||
logger.debug("no-oping sync")
|
||||
defer.returnValue(([], []))
|
||||
defer.returnValue(([], [], [], []))
|
||||
|
||||
ignored_account_data = yield self.store.get_global_account_data_by_type_for_user(
|
||||
"m.ignored_user_list", user_id=user_id,
|
||||
|
@ -828,17 +860,24 @@ class SyncHandler(object):
|
|||
|
||||
# Now we want to get any newly joined users
|
||||
newly_joined_users = set()
|
||||
newly_left_users = set()
|
||||
if since_token:
|
||||
for joined_sync in sync_result_builder.joined:
|
||||
it = itertools.chain(
|
||||
joined_sync.timeline.events, joined_sync.state.values()
|
||||
joined_sync.timeline.events, joined_sync.state.itervalues()
|
||||
)
|
||||
for event in it:
|
||||
if event.type == EventTypes.Member:
|
||||
if event.membership == Membership.JOIN:
|
||||
newly_joined_users.add(event.state_key)
|
||||
else:
|
||||
prev_content = event.unsigned.get("prev_content", {})
|
||||
prev_membership = prev_content.get("membership", None)
|
||||
if prev_membership == Membership.JOIN:
|
||||
newly_left_users.add(event.state_key)
|
||||
|
||||
defer.returnValue((newly_joined_rooms, newly_joined_users))
|
||||
newly_left_users -= newly_joined_users
|
||||
defer.returnValue((newly_joined_rooms, newly_joined_users, [], newly_left_users))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _have_rooms_changed(self, sync_result_builder):
|
||||
|
@ -1259,6 +1298,7 @@ class SyncResultBuilder(object):
|
|||
self.invited = []
|
||||
self.archived = []
|
||||
self.device = []
|
||||
self.to_device = []
|
||||
|
||||
|
||||
class RoomSyncResultBuilder(object):
|
||||
|
|
|
@ -189,7 +189,8 @@ class SyncRestServlet(RestServlet):
|
|||
"account_data": {"events": sync_result.account_data},
|
||||
"to_device": {"events": sync_result.to_device},
|
||||
"device_lists": {
|
||||
"changed": list(sync_result.device_lists),
|
||||
"changed": list(sync_result.device_lists.changed),
|
||||
"left": list(sync_result.device_lists.left),
|
||||
},
|
||||
"presence": SyncRestServlet.encode_presence(
|
||||
sync_result.presence, time_now
|
||||
|
|
Loading…
Reference in a new issue