diff --git a/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.h b/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.h index b919ec23e..b3f36bf6a 100644 --- a/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.h +++ b/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.h @@ -32,17 +32,21 @@ */ @interface PublicRoomsDirectoryDataSource : MXKDataSource +/** + All public rooms of the directory. + */ +@property (nonatomic, readonly) NSArray *rooms; + /** The filter being applied. Nil if there is no filter. Setting a new value may trigger a request to the home server. So, the data source state may change to MXKDataSourceStatePreparing. */ -@property (nonatomic) NSString *searchPattern; +@property (nonatomic) NSString *filter; /** - The public room of the directory. - The returned array is filtered according to `searchPattern`. + Public rooms of the directory that match `filter`. */ -@property (nonatomic, readonly) NSArray *rooms; +@property (nonatomic, readonly) NSArray *filteredRooms; @end diff --git a/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.m b/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.m index 83a828916..bfe86c810 100644 --- a/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.m +++ b/Vector/Model/RoomList/PublicRoomsDirectoryDataSource.m @@ -16,77 +16,104 @@ #import "PublicRoomsDirectoryDataSource.h" +#pragma mark - Constants definitions + +// Time in seconds from which public rooms data is considered as obsolete +double const kPublicRoomsDirectoryDataExpiration = 10; + +#pragma mark - PublicRoomsDirectoryDataSource + @interface PublicRoomsDirectoryDataSource () { // The pending request to refresh public rooms data. MXHTTPOperation *publicRoomsRequest; - // TODO - //NSDate *lastRefreshDate; + // The date of the last fetched data. + NSDate *lastRefreshDate; } @end @implementation PublicRoomsDirectoryDataSource -- (void)setSearchPattern:(NSString *)searchTerm +- (void)setFilter:(NSString *)searchTerm { - if ([searchTerm isEqualToString:_searchPattern]) + if (![searchTerm isEqualToString:_filter]) { - return; + _filter = searchTerm; + [self refreshPublicRooms]; } - - _searchPattern = searchTerm; - [self refreshPublicRooms]; } #pragma mark - Private methods - (void)refreshPublicRooms { - // Cancel the previous request - if (publicRoomsRequest) + // Do not refresh data if it is not too old + if (lastRefreshDate && -lastRefreshDate.timeIntervalSinceNow < kPublicRoomsDirectoryDataExpiration) { - [publicRoomsRequest cancel]; - } - - [self setState:MXKDataSourceStatePreparing]; - - publicRoomsRequest = [self.mxSession.matrixRestClient publicRooms:^(NSArray *rooms) { - - publicRoomsRequest = nil; - - // Apply filter if any - if (_searchPattern) - { - NSMutableArray *matchingRooms = [NSMutableArray array]; - for (MXPublicRoom *publicRoom in rooms) - { - if ([matchingRooms indexOfObject:publicRoom] == NSNotFound) - { - if ([publicRoom.displayname rangeOfString:_searchPattern options:NSCaseInsensitiveSearch].location != NSNotFound) - { - [matchingRooms addObject:publicRoom]; - } - } - } - - _rooms = matchingRooms; - } - else - { - _rooms = rooms; - } + // Apply the new filter on the current data + [self refreshFilteredPublicRooms]; [self setState:MXKDataSourceStateReady]; + } + else + { + // Cancel the previous request + if (publicRoomsRequest) + { + [publicRoomsRequest cancel]; + } - } failure:^(NSError *error) { - NSLog(@"[PublicRoomsDirectoryDataSource] Failed to fecth public rooms. Error: %@", error); + [self setState:MXKDataSourceStatePreparing]; - [self setState:MXKDataSourceStateFailed]; - }]; + lastRefreshDate = [NSDate date]; + + // Get the public rooms from the server + publicRoomsRequest = [self.mxSession.matrixRestClient publicRooms:^(NSArray *rooms) { + + _rooms = rooms; + lastRefreshDate = [NSDate date]; + publicRoomsRequest = nil; + + [self refreshFilteredPublicRooms]; + + [self setState:MXKDataSourceStateReady]; + + } failure:^(NSError *error) { + NSLog(@"[PublicRoomsDirectoryDataSource] Failed to fecth public rooms. Error: %@", error); + + [self setState:MXKDataSourceStateFailed]; + }]; + } } +- (void)refreshFilteredPublicRooms +{ + // Apply filter if any + if (_filter) + { + NSMutableArray *filteredRooms = [NSMutableArray array]; + for (MXPublicRoom *publicRoom in _rooms) + { + if ([filteredRooms indexOfObject:publicRoom] == NSNotFound) + { + if ([publicRoom.displayname rangeOfString:_filter options:NSCaseInsensitiveSearch].location != NSNotFound) + { + [filteredRooms addObject:publicRoom]; + } + } + } + + _filteredRooms = filteredRooms; + } + else + { + _filteredRooms = _rooms; + } +} + + // Update the MXKDataSource state and the delegate - (void)setState:(MXKDataSourceState)newState { diff --git a/Vector/Model/RoomList/RecentsDataSource.m b/Vector/Model/RoomList/RecentsDataSource.m index 51acb057d..6eeea2402 100644 --- a/Vector/Model/RoomList/RecentsDataSource.m +++ b/Vector/Model/RoomList/RecentsDataSource.m @@ -577,8 +577,8 @@ // Show the cell showing the public rooms directory search result // only in case of search - if (publicRoomsDirectoryDataSource.searchPattern - && (publicRoomsDirectoryDataSource.rooms.count > 0 || publicRoomsDirectoryDataSource.state == MXKDataSourceStatePreparing)) + if (publicRoomsDirectoryDataSource.filter + && (publicRoomsDirectoryDataSource.filteredRooms.count > 0 || publicRoomsDirectoryDataSource.state == MXKDataSourceStatePreparing)) { directorySection = sectionIndex; sectionIndex++; @@ -658,7 +658,7 @@ { // Search only on the first pattern // XXX: Why is it an array? - publicRoomsDirectoryDataSource.searchPattern = patternsList[0]; + publicRoomsDirectoryDataSource.filter = patternsList[0]; } } diff --git a/Vector/Views/RoomList/DirectoryRecentTableViewCell.m b/Vector/Views/RoomList/DirectoryRecentTableViewCell.m index 098ba3e2f..edba7e8be 100644 --- a/Vector/Views/RoomList/DirectoryRecentTableViewCell.m +++ b/Vector/Views/RoomList/DirectoryRecentTableViewCell.m @@ -47,8 +47,8 @@ case MXKDataSourceStateReady: self.titleLabel.text = NSLocalizedStringFromTable(@"directory_search_results_title", @"Vector", nil); self.descriptionLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"directory_search_results", @"Vector", nil), - publicRoomsDirectoryDataSource.rooms.count, - publicRoomsDirectoryDataSource.searchPattern]; + publicRoomsDirectoryDataSource.filteredRooms.count, + publicRoomsDirectoryDataSource.filter]; break;