mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Reduce the number of unnecessary home page reloads
This commit is contained in:
parent
53a6c29743
commit
08b48b6285
7 changed files with 99 additions and 97 deletions
|
@ -1501,35 +1501,41 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
|
|||
forSection:(RecentsListServiceSection)section
|
||||
totalCountsChanged:(BOOL)totalCountsChanged
|
||||
{
|
||||
NSInteger sectionIndex = -1;
|
||||
switch (section)
|
||||
RecentsDataSourceSections *updatedSections = [self makeDataSourceSections];
|
||||
BOOL hasChangedSections = ![self.sections isEqual:updatedSections];
|
||||
if (hasChangedSections) {
|
||||
// If the number or order of sections has changed, we reload all of the data
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
RecentsDataSourceSectionType sectionType = [self sectionTypeForServiceSection:section];
|
||||
NSInteger sectionIndex = [self.sections sectionIndexForSectionType:sectionType];
|
||||
if (sectionIndex >= 0) {
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:(NSUInteger)sectionIndex];
|
||||
[self.delegate dataSource:self didCellChange:indexPath];
|
||||
}
|
||||
}
|
||||
|
||||
- (RecentsDataSourceSectionType)sectionTypeForServiceSection:(RecentsListServiceSection)serviceSection
|
||||
{
|
||||
switch (serviceSection)
|
||||
{
|
||||
case RecentsListServiceSectionInvited:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypeInvites];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypeInvites;
|
||||
case RecentsListServiceSectionFavorited:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypeFavorites];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypeFavorites;
|
||||
case RecentsListServiceSectionPeople:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypePeople];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypePeople;
|
||||
case RecentsListServiceSectionConversation:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypeConversation];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypeConversation;
|
||||
case RecentsListServiceSectionLowPriority:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypeLowPriority];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypeLowPriority;
|
||||
case RecentsListServiceSectionServerNotice:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypeServerNotice];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypeServerNotice;
|
||||
case RecentsListServiceSectionSuggested:
|
||||
sectionIndex = [self.sections sectionIndexForSectionType:RecentsDataSourceSectionTypeSuggestedRooms];
|
||||
break;
|
||||
return RecentsDataSourceSectionTypeSuggestedRooms;
|
||||
}
|
||||
|
||||
RecentsSectionUpdate *update = [[RecentsSectionUpdate alloc] initWithSectionIndex:sectionIndex
|
||||
totalCountsChanged:totalCountsChanged];
|
||||
[self.delegate dataSource:self didCellChange:update];
|
||||
}
|
||||
|
||||
#pragma mark - Shrinkable
|
||||
|
|
|
@ -75,4 +75,11 @@ import Foundation
|
|||
}
|
||||
return item.key
|
||||
}
|
||||
|
||||
override func isEqual(_ object: Any?) -> Bool {
|
||||
guard let other = object as? RecentsDataSourceSections else {
|
||||
return false
|
||||
}
|
||||
return sections == other.sections
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Object to represent a recents section update. Will be used as the `changes` parameter of `-[MXKDataSourceDelegate dataSource:didCellChange:]`method.
|
||||
@objcMembers
|
||||
class RecentsSectionUpdate: NSObject {
|
||||
|
||||
/// Updated section index.
|
||||
let sectionIndex: Int
|
||||
|
||||
/// Flag indicating the total counts on the section have changed or not.
|
||||
let totalCountsChanged: Bool
|
||||
|
||||
init(withSectionIndex sectionIndex: Int,
|
||||
totalCountsChanged: Bool) {
|
||||
self.sectionIndex = sectionIndex
|
||||
self.totalCountsChanged = totalCountsChanged
|
||||
super.init()
|
||||
}
|
||||
|
||||
/// Flag indicating the section update info is valid. If `true`, only the related section at `sectionIndex` can be reloaded.
|
||||
var isValid: Bool {
|
||||
return sectionIndex >= 0
|
||||
}
|
||||
}
|
|
@ -363,6 +363,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
- (void)refreshRecentsTable
|
||||
{
|
||||
MXLogDebug(@"[RecentsViewController]: Refreshing recents table view")
|
||||
// Refresh the tabBar icon badges
|
||||
[[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges];
|
||||
|
||||
|
@ -1031,49 +1032,44 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
- (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes
|
||||
{
|
||||
BOOL cellReloaded = NO;
|
||||
if ([changes isKindOfClass:RecentsSectionUpdate.class])
|
||||
if ([changes isKindOfClass:NSIndexPath.class])
|
||||
{
|
||||
RecentsSectionUpdate *update = (RecentsSectionUpdate*)changes;
|
||||
if (update.isValid && !update.totalCountsChanged)
|
||||
NSIndexPath *indexPath = (NSIndexPath *)changes;
|
||||
UITableViewCell *cell = [self.recentsTableView cellForRowAtIndexPath:indexPath];
|
||||
if ([cell isKindOfClass:TableViewCellWithCollectionView.class])
|
||||
{
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:update.sectionIndex];
|
||||
UITableViewCell *cell = [self.recentsTableView cellForRowAtIndexPath:indexPath];
|
||||
if ([cell isKindOfClass:TableViewCellWithCollectionView.class])
|
||||
{
|
||||
TableViewCellWithCollectionView *collectionViewCell = (TableViewCellWithCollectionView *)cell;
|
||||
[collectionViewCell.collectionView reloadData];
|
||||
cellReloaded = YES;
|
||||
MXLogDebug(@"[RecentsViewController]: Reloading nested collection view cell in section %ld", indexPath.section);
|
||||
|
||||
TableViewCellWithCollectionView *collectionViewCell = (TableViewCellWithCollectionView *)cell;
|
||||
[collectionViewCell.collectionView reloadData];
|
||||
|
||||
CGRect headerFrame = [self.recentsTableView rectForHeaderInSection:update.sectionIndex];
|
||||
UIView *headerView = [self.recentsTableView headerViewForSection:update.sectionIndex];
|
||||
UIView *updatedHeaderView = [self.dataSource viewForHeaderInSection:update.sectionIndex withFrame:headerFrame inTableView:self.recentsTableView];
|
||||
if ([headerView isKindOfClass:SectionHeaderView.class]
|
||||
&& [updatedHeaderView isKindOfClass:SectionHeaderView.class])
|
||||
{
|
||||
SectionHeaderView *sectionHeaderView = (SectionHeaderView *)headerView;
|
||||
SectionHeaderView *updatedSectionHeaderView = (SectionHeaderView *)updatedHeaderView;
|
||||
sectionHeaderView.headerLabel = updatedSectionHeaderView.headerLabel;
|
||||
sectionHeaderView.accessoryView = updatedSectionHeaderView.accessoryView;
|
||||
sectionHeaderView.rightAccessoryView = updatedSectionHeaderView.rightAccessoryView;
|
||||
}
|
||||
CGRect headerFrame = [self.recentsTableView rectForHeaderInSection:indexPath.section];
|
||||
UIView *headerView = [self.recentsTableView headerViewForSection:indexPath.section];
|
||||
UIView *updatedHeaderView = [self.dataSource viewForHeaderInSection:indexPath.section withFrame:headerFrame inTableView:self.recentsTableView];
|
||||
if ([headerView isKindOfClass:SectionHeaderView.class]
|
||||
&& [updatedHeaderView isKindOfClass:SectionHeaderView.class])
|
||||
{
|
||||
SectionHeaderView *sectionHeaderView = (SectionHeaderView *)headerView;
|
||||
SectionHeaderView *updatedSectionHeaderView = (SectionHeaderView *)updatedHeaderView;
|
||||
sectionHeaderView.headerLabel = updatedSectionHeaderView.headerLabel;
|
||||
sectionHeaderView.accessoryView = updatedSectionHeaderView.accessoryView;
|
||||
sectionHeaderView.rightAccessoryView = updatedSectionHeaderView.rightAccessoryView;
|
||||
}
|
||||
} else {
|
||||
MXLogDebug(@"[RecentsViewController]: Reloading table view section %ld", indexPath.section);
|
||||
[self.recentsTableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
} else if (!changes) {
|
||||
MXLogDebug(@"[RecentsViewController]: Reloading the entire table view");
|
||||
[self refreshRecentsTable];
|
||||
}
|
||||
|
||||
if (!cellReloaded)
|
||||
{
|
||||
[super dataSource:dataSource didCellChange:changes];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since we've enabled room list pagination, `refreshRecentsTable` not called in this case.
|
||||
// Refresh tab bar badges separately.
|
||||
[[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges];
|
||||
}
|
||||
// Since we've enabled room list pagination, `refreshRecentsTable` not called in this case.
|
||||
// Refresh tab bar badges separately.
|
||||
[[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges];
|
||||
|
||||
[self showEmptyViewIfNeeded];
|
||||
|
||||
|
||||
if (dataSource.state == MXKDataSourceStateReady)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RecentsViewControllerDataReadyNotification
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -610,9 +610,10 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
|
|||
multicastDelegate.invoke { $0.recentsListServiceDidChangeData?(self,
|
||||
forSection: section,
|
||||
totalCountsChanged: totalCountsChanged) }
|
||||
} else {
|
||||
multicastDelegate.invoke { $0.recentsListServiceDidChangeData?(self,
|
||||
totalCountsChanged: totalCountsChanged) }
|
||||
}
|
||||
multicastDelegate.invoke { $0.recentsListServiceDidChangeData?(self,
|
||||
totalCountsChanged: totalCountsChanged) }
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
|
|
@ -112,4 +112,35 @@ class RecentsDataSourceSectionsTests: XCTestCase {
|
|||
]
|
||||
)
|
||||
}
|
||||
|
||||
func test_equalsIfSameSectionsInSameOrder() {
|
||||
let original = RecentsDataSourceSections(sectionTypes: [
|
||||
.favorites,
|
||||
.invites,
|
||||
.lowPriority,
|
||||
.searchedRoom,
|
||||
])
|
||||
let sameOrder = RecentsDataSourceSections(sectionTypes: [
|
||||
.favorites,
|
||||
.invites,
|
||||
.lowPriority,
|
||||
.searchedRoom,
|
||||
])
|
||||
let differentOrder = RecentsDataSourceSections(sectionTypes: [
|
||||
.lowPriority,
|
||||
.favorites,
|
||||
.invites,
|
||||
.searchedRoom,
|
||||
])
|
||||
let differentSections = RecentsDataSourceSections(sectionTypes: [
|
||||
.favorites,
|
||||
.serverNotice,
|
||||
.lowPriority,
|
||||
.searchedRoom,
|
||||
])
|
||||
|
||||
XCTAssertEqual(original, sameOrder)
|
||||
XCTAssertNotEqual(original, differentOrder)
|
||||
XCTAssertNotEqual(original, differentSections)
|
||||
}
|
||||
}
|
||||
|
|
1
changelog.d/5619.bugfix
Normal file
1
changelog.d/5619.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Home: Reduce the number of unnecessary home page reloads
|
Loading…
Reference in a new issue