From 628f303c0f34ea96850062e045f1f58ed9282094 Mon Sep 17 00:00:00 2001 From: Giom Foret Date: Tue, 2 Jan 2018 16:23:12 +0100 Subject: [PATCH] Groups: Improve the groups notifications handling at application level --- Riot/ViewController/GroupHomeViewController.m | 65 +++++++++++++------ .../GroupParticipantsViewController.m | 55 +++++++++++----- .../ViewController/GroupRoomsViewController.m | 55 +++++++++++----- 3 files changed, 121 insertions(+), 54 deletions(-) diff --git a/Riot/ViewController/GroupHomeViewController.m b/Riot/ViewController/GroupHomeViewController.m index bac5e13b3..5a6def131 100644 --- a/Riot/ViewController/GroupHomeViewController.m +++ b/Riot/ViewController/GroupHomeViewController.m @@ -150,23 +150,38 @@ if (_group) { - // Force a screen refresh - [self didUpdateGroupDetails:nil]; + // Restore the listeners on the group update. + [self registerOnGroupChangeNotifications]; + + // Check whether the selected group is stored in the user's session, or if it is a group preview. + // Replace the displayed group instance with the one stored in the session (if any). + MXGroup *storedGroup = [_mxSession groupWithGroupId:_group.groupId]; + BOOL isPreview = (!storedGroup); + + // Force refresh + [self refreshDisplayWithGroup:(isPreview ? _group : storedGroup)]; + + // Prepare a block called on successful update in case of a group preview. + // Indeed the group update notifications are triggered by the matrix session only for the user's groups. + void (^success)(void) = ^void(void) + { + [self refreshDisplayWithGroup:_group]; + }; // Trigger a refresh on the group summary. - [self.mxSession updateGroupSummary:_group success:nil failure:^(NSError *error) { + [self.mxSession updateGroupSummary:_group success:(isPreview ? success : nil) failure:^(NSError *error) { NSLog(@"[GroupHomeViewController] viewWillAppear: group summary update failed %@", _group.groupId); }]; // Trigger a refresh on the group members (ignore here the invited users). - [self.mxSession updateGroupUsers:_group success:nil failure:^(NSError *error) { + [self.mxSession updateGroupUsers:_group success:(isPreview ? success : nil) failure:^(NSError *error) { NSLog(@"[GroupHomeViewController] viewWillAppear: group members update failed %@", _group.groupId); }]; // Trigger a refresh on the group rooms. - [self.mxSession updateGroupRooms:_group success:nil failure:^(NSError *error) { + [self.mxSession updateGroupRooms:_group success:(isPreview ? success : nil) failure:^(NSError *error) { NSLog(@"[GroupHomeViewController] viewWillAppear: group rooms update failed %@", _group.groupId); @@ -183,6 +198,7 @@ - (void)destroy { + // Note: all observers are removed during super call. [super destroy]; _group = nil; @@ -191,8 +207,6 @@ [currentRequest cancel]; currentRequest = nil; - [self cancelRegistrationOnGroupChangeNotifications]; - if (kRiotDesignValuesDidChangeThemeNotificationObserver) { [[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver]; @@ -202,7 +216,13 @@ - (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession { - _mxSession = mxSession; + if (_mxSession != mxSession) + { + [self cancelRegistrationOnGroupChangeNotifications]; + _mxSession = mxSession; + + [self registerOnGroupChangeNotifications]; + } [self addMatrixSession:mxSession]; @@ -213,25 +233,30 @@ - (void)registerOnGroupChangeNotifications { - [self cancelRegistrationOnGroupChangeNotifications]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupSummaryNotification object:self.mxSession]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupUsersNotification object:self.mxSession]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupRoomsNotification object:self.mxSession]; + if (_mxSession) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupSummaryNotification object:_mxSession]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupUsersNotification object:_mxSession]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession]; + } } - (void)cancelRegistrationOnGroupChangeNotifications { // Remove any pending observers - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupSummaryNotification object:_mxSession]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupUsersNotification object:_mxSession]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession]; } - (void)didUpdateGroupDetails:(NSNotification *)notif { - // Update here the displayed group instance with the one stored in the session (if any). - MXGroup *group = [self.mxSession groupWithGroupId:_group.groupId]; - - [self refreshDisplayWithGroup:(group ? group : _group)]; + MXGroup *group = notif.userInfo[kMXSessionNotificationGroupKey]; + if (group && [group.groupId isEqualToString:_group.groupId]) + { + // Update the current displayed group instance with the one stored in the session + [self refreshDisplayWithGroup:group]; + } } - (void)refreshDisplayWithGroup:(MXGroup*)group @@ -240,8 +265,6 @@ if (_group) { - [self registerOnGroupChangeNotifications]; - [_group setGroupAvatarImageIn:_groupAvatar matrixSession:self.mxSession]; _groupName.text = _group.summary.profile.name; @@ -388,7 +411,7 @@ self->currentRequest = nil; [self stopActivityIndicator]; - [self refreshDisplayWithGroup:[self.mxSession groupWithGroupId:_group.groupId]]; + [self refreshDisplayWithGroup:[_mxSession groupWithGroupId:_group.groupId]]; } } failure:^(NSError *error) { diff --git a/Riot/ViewController/GroupParticipantsViewController.m b/Riot/ViewController/GroupParticipantsViewController.m index 51bd2786e..9078eb6d0 100644 --- a/Riot/ViewController/GroupParticipantsViewController.m +++ b/Riot/ViewController/GroupParticipantsViewController.m @@ -204,6 +204,7 @@ [self removePendingActionMask]; + // Note: all observers are removed during super call. [super destroy]; } @@ -222,16 +223,31 @@ if (_group) { + // Restore the listeners on the group update. + [self registerOnGroupChangeNotifications]; + + // Check whether the selected group is stored in the user's session, or if it is a group preview. + // Replace the displayed group instance with the one stored in the session (if any). + MXGroup *storedGroup = [_mxSession groupWithGroupId:_group.groupId]; + BOOL isPreview = (!storedGroup); + // Force refresh - [self didUpdateGroupUsers:nil]; + [self refreshDisplayWithGroup:(isPreview ? _group : storedGroup)]; + + // Prepare a block called on successful update in case of a group preview. + // Indeed the group update notifications are triggered by the matrix session only for the user's groups. + void (^success)(void) = ^void(void) + { + [self refreshDisplayWithGroup:_group]; + }; // Trigger a refresh on the group members and the invited users. - [self.mxSession updateGroupUsers:_group success:nil failure:^(NSError *error) { + [self.mxSession updateGroupUsers:_group success:(isPreview ? success : nil) failure:^(NSError *error) { NSLog(@"[GroupParticipantsViewController] viewWillAppear: group members update failed %@", _group.groupId); }]; - [self.mxSession updateGroupInvitedUsers:_group success:nil failure:^(NSError *error) { + [self.mxSession updateGroupInvitedUsers:_group success:(isPreview ? success : nil) failure:^(NSError *error) { NSLog(@"[GroupParticipantsViewController] viewWillAppear: invited users update failed %@", _group.groupId); @@ -243,6 +259,8 @@ { [super viewWillDisappear:animated]; + [self cancelRegistrationOnGroupChangeNotifications]; + if (currentAlert) { [currentAlert dismissViewControllerAnimated:NO completion:nil]; @@ -305,7 +323,13 @@ // Cancel any pending search [self searchBarCancelButtonClicked:_searchBarView]; - _mxSession = mxSession; + if (_mxSession != mxSession) + { + [self cancelRegistrationOnGroupChangeNotifications]; + _mxSession = mxSession; + + [self registerOnGroupChangeNotifications]; + } [self addMatrixSession:mxSession]; @@ -316,23 +340,26 @@ - (void)registerOnGroupChangeNotifications { - [self cancelRegistrationOnGroupChangeNotifications]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupUsers:) name:kMXSessionDidUpdateGroupUsersNotification object:self.mxSession]; + if (_mxSession) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupUsers:) name:kMXSessionDidUpdateGroupUsersNotification object:_mxSession]; + } } - (void)cancelRegistrationOnGroupChangeNotifications { // Remove any pending observers - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupUsersNotification object:_mxSession]; } - (void)didUpdateGroupUsers:(NSNotification *)notif { - // Update here the displayed group instance with the one stored in the session (if any). - MXGroup *group = [self.mxSession groupWithGroupId:_group.groupId]; - - [self refreshDisplayWithGroup:(group ? group : _group)]; + MXGroup *group = notif.userInfo[kMXSessionNotificationGroupKey]; + if (group && [group.groupId isEqualToString:_group.groupId]) + { + // Update the current displayed group instance with the one stored in the session + [self refreshDisplayWithGroup:group]; + } } - (void)refreshDisplayWithGroup:(MXGroup *)group @@ -342,15 +369,11 @@ if (_group) { _searchBarHeader.hidden = NO; - - [self registerOnGroupChangeNotifications]; } else { // Search bar header is hidden when no group is provided _searchBarHeader.hidden = YES; - - [self cancelRegistrationOnGroupChangeNotifications]; } // Refresh the members list. diff --git a/Riot/ViewController/GroupRoomsViewController.m b/Riot/ViewController/GroupRoomsViewController.m index 1b004a070..a59542e4c 100644 --- a/Riot/ViewController/GroupRoomsViewController.m +++ b/Riot/ViewController/GroupRoomsViewController.m @@ -166,6 +166,7 @@ groupRooms = nil; + // Note: all observers are removed during super call. [super destroy]; } @@ -178,11 +179,26 @@ if (_group) { + // Restore the listeners on the group update. + [self registerOnGroupChangeNotifications]; + + // Check whether the selected group is stored in the user's session, or if it is a group preview. + // Replace the displayed group instance with the one stored in the session (if any). + MXGroup *storedGroup = [_mxSession groupWithGroupId:_group.groupId]; + BOOL isPreview = (!storedGroup); + // Force refresh - [self didUpdateGroupRooms:nil]; + [self refreshDisplayWithGroup:(isPreview ? _group : storedGroup)]; + + // Prepare a block called on successful update in case of a group preview. + // Indeed the group update notifications are triggered by the matrix session only for the user's groups. + void (^success)(void) = ^void(void) + { + [self refreshDisplayWithGroup:_group]; + }; // Trigger a refresh on the group rooms. - [self.mxSession updateGroupRooms:_group success:nil failure:^(NSError *error) { + [self.mxSession updateGroupRooms:_group success:(isPreview ? success : nil) failure:^(NSError *error) { NSLog(@"[GroupRoomsViewController] viewWillAppear: group rooms update failed %@", _group.groupId); @@ -194,6 +210,8 @@ { [super viewWillDisappear:animated]; + [self cancelRegistrationOnGroupChangeNotifications]; + // cancel any pending search [self searchBarCancelButtonClicked:_searchBarView]; } @@ -216,7 +234,13 @@ // Cancel any pending search [self searchBarCancelButtonClicked:_searchBarView]; - _mxSession = mxSession; + if (_mxSession != mxSession) + { + [self cancelRegistrationOnGroupChangeNotifications]; + _mxSession = mxSession; + + [self registerOnGroupChangeNotifications]; + } [self addMatrixSession:mxSession]; @@ -227,23 +251,26 @@ - (void)registerOnGroupChangeNotifications { - [self cancelRegistrationOnGroupChangeNotifications]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupRooms:) name:kMXSessionDidUpdateGroupRoomsNotification object:self.mxSession]; + if (_mxSession) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupRooms:) name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession]; + } } - (void)cancelRegistrationOnGroupChangeNotifications { // Remove any pending observers - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession]; } - (void)didUpdateGroupRooms:(NSNotification *)notif { - // Update here the displayed group instance with the one stored in the session (if any). - MXGroup *group = [self.mxSession groupWithGroupId:_group.groupId]; - - [self refreshDisplayWithGroup:(group ? group : _group)]; + MXGroup *group = notif.userInfo[kMXSessionNotificationGroupKey]; + if (group && [group.groupId isEqualToString:_group.groupId]) + { + // Update the current displayed group instance with the one stored in the session. + [self refreshDisplayWithGroup:group]; + } } - (void)refreshDisplayWithGroup:(MXGroup *)group @@ -253,18 +280,12 @@ if (_group) { _searchBarHeader.hidden = NO; - - [self registerOnGroupChangeNotifications]; - groupRooms = _group.rooms.chunk; } else { // Search bar header is hidden when no group is provided _searchBarHeader.hidden = YES; - - [self cancelRegistrationOnGroupChangeNotifications]; - groupRooms = nil; }